Rewrite of the old Contiki shell. The new shell supports dynamic

insertion of new commands and command pipelining. There are also a
bunch of new commands for network access (using Rime): ping, data
collection, packet sniffing, sending shell commands across the
network, and testing the single-hop throughput to neighboring
nodes. Commands are also available for reading from and writing to
files, reading the sensors (on the Tmote Sky platform), and accessing
the power and energy consumption of the system. Dynamic loading of
programs across the network is also possible, although a little
untested at the moment.
This commit is contained in:
adamdunkels 2008-02-04 23:42:17 +00:00
parent 465f75736d
commit a26d87e09e
37 changed files with 4815 additions and 340 deletions

View file

@ -1,2 +1,7 @@
shell_src = shell-gui.c shell.c ctk-textentry-cmdline.c
shell_src = shell.c serial-shell.c shell-reboot.c \
shell-vars.c shell-ps.c shell-rime.c shell-sendtest.c \
shell-blink.c shell-text.c shell-time.c \
shell-file.c shell-netfile.c shell-exec.c \
shell-rime-ping.c shell-rime-sniff.c \
shell-sky.c #shell-rsh.c
shell_dsc = shell-dsc.c

87
apps/shell/serial-shell.c Normal file
View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: serial-shell.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A shell driver for the serial port
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell.h"
#include "dev/serial.h"
#include "net/rime.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(serial_shell_process, "Contiki serial shell");
/*---------------------------------------------------------------------------*/
void
shell_default_output(const char *text1, int len1, const char *text2, int len2)
{
printf("%.*s%.*s\r\n", len1, text1, len2, text2);
}
/*---------------------------------------------------------------------------*/
void
shell_prompt(char *str)
{
printf("%d.%d: %s", rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1],
str);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(serial_shell_process, ev, data)
{
PROCESS_BEGIN();
shell_init();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == serial_event_message && data != NULL);
/* printf("input: '%s'\n", (char *)data);*/
shell_input(data, strlen(data));
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
serial_shell_init(void)
{
process_start(&serial_shell_process, NULL);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/serial-shell.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: serial-shell.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SERIAL_SHELL_H__
#define __SERIAL_SHELL_H__
#include "contiki.h"
void serial_shell_init(void);
#endif /* __SERIAL_SHELL_H__ */

122
apps/shell/shell-blink.c Normal file
View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-blink.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell.h"
#include "dev/leds.h"
#include <stdio.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_blink_process, "blink");
SHELL_COMMAND(blink_command,
"blink",
"blink [num]: blink LEDs ([num] times)",
&shell_blink_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_blink_process, ev, data)
{
static struct etimer etimer;
static int i, num, on = 0;
const char *nextptr;
PROCESS_EXITHANDLER(if(on) { leds_toggle(LEDS_ALL); } );
PROCESS_BEGIN();
if(data != NULL) {
num = shell_strtolong(data, &nextptr);
if(nextptr != data) {
etimer_set(&etimer, CLOCK_SECOND / 2);
for(i = 0; i < num; ++i) {
leds_toggle(LEDS_ALL);
on = 1;
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
etimer_reset(&etimer);
leds_toggle(LEDS_ALL);
on = 0;
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
etimer_reset(&etimer);
}
PROCESS_EXIT();
}
}
while(1) {
struct shell_input *input;
PROCESS_WAIT_EVENT();
if(ev == PROCESS_EVENT_TIMER && data == &etimer) {
if(on) {
leds_toggle(LEDS_ALL);
on = 0;
}
} else if(ev == shell_event_input) {
input = data;
if(input->len1 + input->len2 == 0) {
if(on) {
leds_toggle(LEDS_ALL);
on = 0;
}
PROCESS_EXIT();
}
shell_output(&blink_command,
input->data1, input->len1,
input->data2, input->len2);
if(on == 0) {
leds_toggle(LEDS_ALL);
on = 1;
}
etimer_set(&etimer, CLOCK_SECOND / 16);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_blink_init(void)
{
shell_register_command(&blink_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-blink.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-blink.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_BLINK_H__
#define __SHELL_BLINK_H__
#include "shell.h"
void shell_blink_init(void);
#endif /* __SHELL_BLINK_H__ */

140
apps/shell/shell-exec.c Normal file
View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-exec.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell-exec.h"
#include "loader/elfloader.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_exec_process, "exec");
SHELL_COMMAND(exec_command,
"exec",
"exec: load and execute an ELF file",
&shell_exec_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_exec_process, ev, data)
{
char *name;
int fd;
PROCESS_BEGIN();
name = data;
if(name == NULL || strlen(name) == 0) {
shell_output_str(&exec_command,
"exec <file>: filename must be given", "");
PROCESS_EXIT();
}
/* Kill any old processes. */
if(elfloader_autostart_processes != NULL) {
autostart_exit(elfloader_autostart_processes);
}
fd = cfs_open(name, CFS_READ);
if(fd <= 0) {
shell_output_str(&exec_command,
"exec: could not open ", name);
} else {
int ret;
char *print, *symbol;
ret = elfloader_load(fd);
cfs_close(fd);
symbol = "";
switch(ret) {
case ELFLOADER_OK:
print = "OK";
break;
case ELFLOADER_BAD_ELF_HEADER:
print = "Bad ELF header";
break;
case ELFLOADER_NO_SYMTAB:
print = "No symbol table";
break;
case ELFLOADER_NO_STRTAB:
print = "No string table";
break;
case ELFLOADER_NO_TEXT:
print = "No text segment";
break;
case ELFLOADER_SYMBOL_NOT_FOUND:
print = "Symbol not found: ";
symbol = elfloader_unknown;
break;
case ELFLOADER_SEGMENT_NOT_FOUND:
print = "Segment not found: ";
symbol = elfloader_unknown;
break;
case ELFLOADER_NO_STARTPOINT:
print = "No starting point";
break;
default:
print = "Unknown return code from the ELF loader (internal bug)";
break;
}
shell_output_str(&exec_command, print, symbol);
if(ret == ELFLOADER_OK) {
int i;
for(i = 0; elfloader_autostart_processes[i] != NULL; ++i) {
shell_output_str(&exec_command, "exec: starting process ",
elfloader_autostart_processes[i]->name);
}
autostart_start(elfloader_autostart_processes);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_exec_init(void)
{
elfloader_init();
shell_register_command(&exec_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-exec.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-exec.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_EXEC_H__
#define __SHELL_EXEC_H__
#include "shell.h"
void shell_exec_init(void);
#endif /* __SHELL_EXEC_H__ */

218
apps/shell/shell-file.c Normal file
View file

@ -0,0 +1,218 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-file.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell-file.h"
#include "cfs/cfs.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_ls_process, "ls");
SHELL_COMMAND(ls_command,
"ls",
"ls: list files",
&shell_ls_process);
PROCESS(shell_append_process, "append");
SHELL_COMMAND(append_command,
"append",
"append <filename>: append to file",
&shell_append_process);
PROCESS(shell_write_process, "write");
SHELL_COMMAND(write_command,
"write",
"write <filename>: write to file",
&shell_write_process);
PROCESS(shell_read_process, "read");
SHELL_COMMAND(read_command,
"read",
"read <filename>: read from file",
&shell_read_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_ls_process, ev, data)
{
static struct cfs_dir dir;
static int totsize;
struct cfs_dirent dirent;
char buf[32];
PROCESS_BEGIN();
if(cfs_opendir(&dir, ".") != 0) {
shell_output_str(&ls_command, "Cannot open directory", "");
} else {
totsize = 0;
while(cfs_readdir(&dir, &dirent) == 0) {
totsize += dirent.size;
sprintf(buf, "%d ", dirent.size);
shell_output_str(&ls_command, buf, dirent.name);
}
cfs_closedir(&dir);
sprintf(buf, "%d", totsize);
shell_output_str(&ls_command, "Total size: ", buf);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_append_process, ev, data)
{
static int fd = 0;
PROCESS_EXITHANDLER(cfs_close(fd));
PROCESS_BEGIN();
fd = cfs_open(data, CFS_WRITE | CFS_APPEND);
if(fd <= 0) {
shell_output_str(&append_command,
"Could not open file for writing: ", data);
}
while(1) {
struct shell_input *input;
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
/* printf("cat input %d %d\n", input->len1, input->len2);*/
if(input->len1 + input->len2 == 0) {
cfs_close(fd);
PROCESS_EXIT();
}
cfs_write(fd, input->data1, input->len1);
cfs_write(fd, input->data2, input->len2);
shell_output(&append_command,
input->data1, input->len1,
input->data2, input->len2);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_write_process, ev, data)
{
static int fd = 0;
PROCESS_EXITHANDLER(cfs_close(fd));
PROCESS_BEGIN();
fd = cfs_open(data, CFS_WRITE);
if(fd <= 0) {
shell_output_str(&write_command,
"Could not open file for writing: ", data);
}
while(1) {
struct shell_input *input;
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
/* printf("cat input %d %d\n", input->len1, input->len2);*/
if(input->len1 + input->len2 == 0) {
cfs_close(fd);
PROCESS_EXIT();
}
cfs_write(fd, input->data1, input->len1);
cfs_write(fd, input->data2, input->len2);
shell_output(&write_command,
input->data1, input->len1,
input->data2, input->len2);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_read_process, ev, data)
{
static int fd = 0;
PROCESS_EXITHANDLER(cfs_close(fd));
PROCESS_BEGIN();
fd = cfs_open(data, CFS_READ);
if(fd <= 0) {
shell_output_str(&write_command,
"Could not open file for writing: ", data);
}
while(1) {
char buf[40];
int len;
struct shell_input *input;
len = cfs_read(fd, buf, sizeof(buf));
if(len <= 0) {
cfs_close(fd);
PROCESS_EXIT();
}
shell_output(&read_command,
buf, len, "", 0);
process_post(&shell_read_process, PROCESS_EVENT_CONTINUE, NULL);
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE ||
ev == shell_event_input);
if(ev == shell_event_input) {
input = data;
/* printf("cat input %d %d\n", input->len1, input->len2);*/
if(input->len1 + input->len2 == 0) {
cfs_close(fd);
PROCESS_EXIT();
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_file_init(void)
{
shell_register_command(&ls_command);
shell_register_command(&write_command);
shell_register_command(&append_command);
shell_register_command(&read_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-file.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-file.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_FILE_H__
#define __SHELL_FILE_H__
#include "shell.h"
void shell_file_init(void);
#endif /* __SHELL_FILE_H__ */

171
apps/shell/shell-netfile.c Normal file
View file

@ -0,0 +1,171 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-netfile.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell-netfile.h"
#include "net/rime.h"
#include "net/rime/rudolph0.h"
#include "dev/leds.h"
#include "cfs/cfs.h"
#include <stdio.h>
#include <string.h>
#define FILENAME_LEN 20
static struct rudolph0_conn rudolph0_conn;
static char filename[FILENAME_LEN];
static int receiving_file;
static struct pt recvnetfilept;
/*---------------------------------------------------------------------------*/
PROCESS(shell_netfile_process, "netfile");
SHELL_COMMAND(netfile_command,
"netfile",
"netfile: send file to entire network",
&shell_netfile_process);
PROCESS(shell_recvnetfile_process, "recvnetfile");
SHELL_COMMAND(recvnetfile_command,
"recvnetfile",
"recvnetfile: receive file from network and print to output",
&shell_recvnetfile_process);
/*---------------------------------------------------------------------------*/
static int
write_chunk(struct rudolph0_conn *c, int offset, int flag,
uint8_t *data, int datalen)
{
PT_BEGIN(&recvnetfilept);
PT_WAIT_UNTIL(&recvnetfilept, receiving_file);
leds_on(LEDS_YELLOW);
leds_on(LEDS_RED);
PT_WAIT_UNTIL(&recvnetfilept, flag == RUDOLPH0_FLAG_NEWFILE);
leds_off(LEDS_RED);
do {
if(datalen > 0) {
shell_output(&recvnetfile_command, data, datalen, "", 0);
printf("write_chunk wrote %d bytes at %d\n", datalen, offset);
}
PT_YIELD(&recvnetfilept);
} while(flag != RUDOLPH0_FLAG_LASTCHUNK);
shell_output(&recvnetfile_command, data, datalen, "", 0);
printf("write_chunk wrote %d bytes at %d\n", datalen, offset);
shell_output(&recvnetfile_command, "", 0, "", 0);
leds_off(LEDS_YELLOW);
receiving_file = 0;
process_post(&shell_recvnetfile_process, PROCESS_EVENT_CONTINUE, NULL);
PT_END(&recvnetfilept);
}
static int
read_chunk(struct rudolph0_conn *c, int offset, uint8_t *to, int maxsize)
{
int ret;
int fd;
fd = cfs_open(filename, CFS_READ);
cfs_seek(fd, offset);
ret = cfs_read(fd, to, maxsize);
printf("read_chunk %d bytes at %d, %d\n", ret, offset, (unsigned char)to[0]);
cfs_close(fd);
return ret;
}
const static struct rudolph0_callbacks rudolph0_callbacks =
{(void (*)(struct rudolph0_conn *, int, int, uint8_t *, int))write_chunk,
read_chunk};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_netfile_process, ev, data)
{
int fd;
PROCESS_BEGIN();
rudolph0_send(&rudolph0_conn, CLOCK_SECOND);
if(data != NULL) {
strcpy(filename, data);
}
fd = cfs_open(filename, CFS_READ);
if(fd <= 0) {
shell_output_str(&netfile_command, "Could not open file ", filename);
} else {
cfs_close(fd);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_recvnetfile_process, ev, data)
{
PROCESS_BEGIN();
PT_INIT(&recvnetfilept);
receiving_file = 1;
while(1) {
struct shell_input *input;
PROCESS_WAIT_EVENT();
if(ev == shell_event_input) {
input = data;
if(input->len1 + input->len2 == 0) {
receiving_file = 0;
PROCESS_EXIT();
}
} else if(receiving_file == 0) {
PROCESS_EXIT();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_netfile_init(void)
{
receiving_file = 0;
shell_register_command(&netfile_command);
shell_register_command(&recvnetfile_command);
rudolph0_open(&rudolph0_conn, 26, &rudolph0_callbacks);
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-netfile.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_NETFILE_H__
#define __SHELL_NETFILE_H__
#include "shell.h"
void shell_netfile_init(void);
#endif /* __SHELL_NETFILE_H__ */

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-profile.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "contiki-conf.h"
#include "shell-profile.h"
#include "loader/symbols.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_profile_process, "Shell 'profile' command");
SHELL_COMMAND(profile_command,
"profile",
"profile: show aggregate profiling information",
&shell_profile_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_profile_process, ev, data)
{
int i;
char buf[100];
PROCESS_BEGIN();
#if DETAILED_AGGREGATES
for(i = 0; i < aggregates_list_ptr; ++i) {
sprintf(buf, "-- %s: %lu / %u = %lu", aggregates[i].ptr,
aggregates[i].cycles,
aggregates[i].episodes,
aggregates[i].cycles / aggregates[i].episodes);
shell_output(buf, "");
}
#else
for(i = 0; i < aggregates_list_ptr; ++i) {
sprintf(buf, "-- %c%c: %lu / %u = %lu",
aggregates[i].ptr[0], aggregates[i].ptr[1],
aggregates[i].cycles,
aggregates[i].episodes,
aggregates[i].cycles / aggregates[i].episodes);
shell_output(buf, "");
}
#endif
sprintf(buf, "Memory for aggregates: %d * %d = %d\n",
(int)sizeof(struct aggregate), aggregates_list_ptr,
(int)sizeof(struct aggregate) * aggregates_list_ptr);
shell_output(buf, "");
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_profile_init(void)
{
shell_register_command(&profile_command);
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-profile.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_PROFILE_H__
#define __SHELL_PROFILE_H__
#include "shell.h"
void shell_profile_init(void);
#endif /* __SHELL_PROFILE_H__ */

72
apps/shell/shell-ps.c Normal file
View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-ps.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Process-related Contiki shell commands
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell-ps.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_ps_process, "ps");
SHELL_COMMAND(ps_command,
"ps",
"ps: list all running processes",
&shell_ps_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_ps_process, ev, data)
{
struct process *p;
PROCESS_BEGIN();
shell_output_str(&ps_command, "Processes:", "");
for(p = PROCESS_LIST(); p != NULL; p = p->next) {
shell_output_str(&ps_command, (char *)p->name, "");
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_ps_init(void)
{
shell_register_command(&ps_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-ps.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-ps.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Header file for process-related Contiki shell commands
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_PS_H__
#define __SHELL_PS_H__
#include "shell.h"
void shell_ps_init(void);
#endif /* __SHELL_PS_H__ */

86
apps/shell/shell-reboot.c Normal file
View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-reboot.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Reboot Contiki shell command
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell.h"
#include "dev/leds.h"
#include "dev/watchdog.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_reboot_process, "reboot");
SHELL_COMMAND(reboot_command,
"reboot",
"reboot: reboot the system",
&shell_reboot_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_reboot_process, ev, data)
{
static struct etimer etimer;
PROCESS_BEGIN();
shell_output_str(&reboot_command,
"Rebooting the node in four seconds...", "");
etimer_set(&etimer, CLOCK_SECOND);
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
leds_on(LEDS_RED);
etimer_reset(&etimer);
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
leds_on(LEDS_GREEN);
etimer_reset(&etimer);
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
leds_on(LEDS_BLUE);
etimer_reset(&etimer);
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
watchdog_reboot();
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_reboot_init(void)
{
shell_register_command(&reboot_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-reboot.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-reboot.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Header file for reboot Contik shell command
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_REBOOT_H__
#define __SHELL_REBOOT_H__
#include "shell.h"
void shell_reboot_init(void);
#endif /* __SHELL_REBOOT_H__ */

View file

@ -0,0 +1,165 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rime-ping.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* The Contiki shell Rime ping application
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "shell.h"
#include "net/rime.h"
#include <stdio.h>
#ifndef HAVE_SNPRINTF
int snprintf(char *str, size_t size, const char *format, ...);
#endif /* HAVE_SNPRINTF */
struct ping_msg {
rtimer_clock_t pingtime;
rtimer_clock_t pongtime;
};
static struct mesh_conn mesh;
static int waiting_for_pong = 0;
/*---------------------------------------------------------------------------*/
PROCESS(shell_ping_process, "ping");
SHELL_COMMAND(ping_command,
"ping",
"ping <node addr>: send a message to a specific node and get a reply",
&shell_ping_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_ping_process, ev, data)
{
static int i;
static struct etimer timeout, periodic;
static rimeaddr_t receiver;
struct ping_msg *ping;
const char *nextptr;
char buf[32];
PROCESS_BEGIN();
receiver.u8[0] = shell_strtolong(data, &nextptr);
if(nextptr == data || *nextptr != '.') {
shell_output_str(&ping_command,
"ping <receiver>: recevier must be specified", "");
PROCESS_EXIT();
}
++nextptr;
receiver.u8[1] = shell_strtolong(nextptr, &nextptr);
snprintf(buf, sizeof(buf), "%d.%d", receiver.u8[0], receiver.u8[1]);
shell_output_str(&ping_command, "Sending 4 pings to ", buf);
for(i = 0; i < 4; ++i) {
rimebuf_clear();
ping = rimebuf_dataptr();
rimebuf_set_datalen(sizeof(struct ping_msg));
#if TIMESYNCH_CONF_ENABLED
ping->pingtime = timesynch_time();
#else
ping->pingtime = 0;
#endif
mesh_send(&mesh, &receiver);
etimer_set(&timeout, CLOCK_SECOND * 8);
etimer_set(&periodic, CLOCK_SECOND * 1);
waiting_for_pong = 1;
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timeout) ||
waiting_for_pong == 0);
if(waiting_for_pong == 0) {
PROCESS_WAIT_UNTIL(etimer_expired(&periodic));
} else {
shell_output_str(&ping_command,
"Timed out", "");
}
waiting_for_pong = 0;
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
timedout_mesh(struct mesh_conn *c)
{
/* printf("packet timedout\n");*/
}
static void
recv_mesh(struct mesh_conn *c, rimeaddr_t *from, u8_t hops)
{
struct ping_msg *ping;
char buf[32];
rtimer_clock_t pingrecvtime;
ping = rimebuf_dataptr();
if(waiting_for_pong == 0) {
#if TIMESYNCH_CONF_ENABLED
ping->pongtime = timesynch_time();
#else
ping->pongtime = 0;
#endif
mesh_send(&mesh, from);
} else {
#if TIMESYNCH_CONF_ENABLED
pingrecvtime = timesynch_time();
#else
pingrecvtime = 0;
#endif
snprintf(buf, sizeof(buf), "%lu, %lu, %lu, %d.",
(1000L * (pingrecvtime - ping->pingtime)) / RTIMER_ARCH_SECOND,
(1000L * (ping->pongtime - ping->pingtime)) / RTIMER_ARCH_SECOND,
(1000L * (pingrecvtime - ping->pongtime)) / RTIMER_ARCH_SECOND,
hops);
shell_output_str(&ping_command,
"Pong recived; rtt (ms), latency 1 (ms), latency 2 (ms), hops: ", buf);
waiting_for_pong = 0;
process_post(&shell_ping_process, PROCESS_EVENT_CONTINUE, NULL);
}
}
const static struct mesh_callbacks mesh_callbacks = { recv_mesh,
NULL,
timedout_mesh };
/*---------------------------------------------------------------------------*/
void
shell_rime_ping_init(void)
{
mesh_open(&mesh, 19, &mesh_callbacks);
shell_register_command(&ping_command);
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rime-ping.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Header file for the Contiki shell Rime ping application
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_RIME_PING_H__
#define __SHELL_RIME_PING_H__
void shell_rime_ping_init(void);
#endif /* __SHELL-RIME_-PING_H__ */

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rime-sniff.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Contiki shell Rime sniffer application
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "shell.h"
#include "net/rime.h"
/*---------------------------------------------------------------------------*/
PROCESS(shell_sniff_process, "sniff");
SHELL_COMMAND(sniff_command,
"sniff",
"sniff: dump incoming packets",
&shell_sniff_process);
/*---------------------------------------------------------------------------*/
enum {
SNIFFER_INPUT,
SNIFFER_OUTPUT,
};
/*---------------------------------------------------------------------------*/
static void
input_sniffer(void)
{
struct {
uint16_t len;
uint16_t flags;
} msg;
msg.len = rimebuf_totlen() / 2 + 1;
msg.flags = SNIFFER_INPUT;
shell_output(&sniff_command, &msg, sizeof(msg),
rimebuf_dataptr(), (rimebuf_datalen() & 0xfffe) +
2 * (rimebuf_totlen() & 1));
}
/*---------------------------------------------------------------------------*/
static void
output_sniffer(void)
{
struct {
uint16_t len;
uint16_t flags;
} msg;
msg.len = rimebuf_totlen() / 2 + 1;
msg.flags = SNIFFER_OUTPUT;
shell_output(&sniff_command, &msg, sizeof(msg),
rimebuf_hdrptr(), (rimebuf_totlen() & 0xfffe) +
2 * (rimebuf_totlen() & 1));
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_sniff_process, ev, data)
{
RIME_SNIFFER(s, input_sniffer, output_sniffer);
PROCESS_EXITHANDLER(goto exit;);
PROCESS_BEGIN();
rime_sniffer_add(&s);
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
exit:
rime_sniffer_remove(&s);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_rime_sniff_init(void)
{
shell_register_command(&sniff_command);
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rime-sniff.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Header file for the Contiki shell Rime sniffer application
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_RIME_SNIFF_H__
#define __SHELL_RIME_SNIFF_H__
void shell_rime_sniff_init(void);
#endif /* __SHELL_RIME_SNIFF_H__ */

642
apps/shell/shell-rime.c Normal file
View file

@ -0,0 +1,642 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rime.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "contiki-conf.h"
#include "shell-rime.h"
#include "dev/leds.h"
#include "lib/random.h"
#include "net/rime.h"
#include "net/rime/neighbor.h"
#include "net/rime/route.h"
#include "net/rime/trickle.h"
#include "net/rime/timesynch.h"
#define WITH_DEBUG_COMMANDS 1
#if NETSIM
#include "ether.h"
#endif /* NETSIM */
#include <stdio.h>
#ifndef HAVE_SNPRINTF
int snprintf(char *str, size_t size, const char *format, ...);
#endif /* HAVE_SNPRINTF */
#include <string.h>
#define COLLECT_REXMITS 4
enum {
TRICKLE_TYPE_NODES,
TRICKLE_TYPE_NETCMD,
};
struct trickle_msg {
uint8_t type;
char netcmd[1];
};
#define COLLECT_MSG_HDRSIZE 2
struct collect_msg {
uint16_t timestamp;
uint8_t data[1];
};
#if WITH_DEBUG_COMMANDS
static struct abc_conn abc;
static struct uc_conn uc;
#endif /* WITH_DEBUG_COMMANDS */
static struct collect_conn collect;
static struct trickle_conn trickle;
static struct ctimer ctimer;
static int waiting_for_nodes = 0;
static int waiting_for_collect = 0;
static int messages_received = 0;
static int is_sink = 0;
/* XXX ideas not implemented yet:
* download: download file from specific node.
* traceroute
*/
/*---------------------------------------------------------------------------*/
PROCESS(shell_nodes_process, "nodes");
SHELL_COMMAND(nodes_command,
"nodes",
"nodes: get a list of nodes in the network",
&shell_nodes_process);
PROCESS(shell_netcmd_process, "netcmd");
PROCESS(shell_netcmd_server_process, "netcmd server");
SHELL_COMMAND(netcmd_command,
"netcmd",
"netcmd <command>: run a command on all nodes in the network",
&shell_netcmd_process);
PROCESS(shell_send_process, "send");
SHELL_COMMAND(send_command,
"send",
"send: send data to the collector node",
&shell_send_process);
PROCESS(shell_collect_process, "collect");
SHELL_COMMAND(collect_command,
"collect",
"collect: collect data from the network",
&shell_collect_process);
#if WITH_TREEDEPTH
PROCESS(shell_treedepth_process, "treedepth");
SHELL_COMMAND(treedepth_command,
"treedepth",
"treedepth: print the collection tree depth",
&shell_treedepth_process);
#endif /* WITH_TREEDEPTH */
PROCESS(shell_neighbors_process, "neighbors");
SHELL_COMMAND(neighbors_command,
"neighbors",
"neighbors: dump neighbor list in binary format",
&shell_neighbors_process);
PROCESS(shell_routes_process, "routes");
SHELL_COMMAND(routes_command,
"routes",
"routes: dump route list in binary format",
&shell_routes_process);
PROCESS(shell_packetize_process, "packetize");
SHELL_COMMAND(packetize_command,
"packetize",
"packetize: put data into one packet",
&shell_packetize_process);
/*---------------------------------------------------------------------------*/
#if WITH_DEBUG_COMMANDS
PROCESS(shell_broadcast_process, "broadcast");
SHELL_COMMAND(broadcast_command,
"broadcast",
"broadcast: broadcast data to all neighbors",
&shell_broadcast_process);
PROCESS(shell_unicast_process, "unicast");
SHELL_COMMAND(unicast_command,
"unicast",
"unicast <node addr>: unicast data to specific neighbor",
&shell_unicast_process);
#endif /* WITH_DEBUG_COMMANDS */
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_packetize_process, ev, data)
{
static struct queuebuf *q = NULL;
static char *ptr;
static int size;
int len;
PROCESS_BEGIN();
while(1) {
struct shell_input *input;
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
if(q == NULL) {
rimebuf_clear();
q = queuebuf_new_from_rimebuf();
if(q == NULL) {
shell_output_str(&packetize_command, "packetize: could not allocate packet buffer", "");
PROCESS_EXIT();
}
ptr = queuebuf_dataptr(q);
size = 0;
}
input = data;
len = input->len1 + input->len2;
if(len + size >= RIMEBUF_SIZE ||
len == 0) {
shell_output(&packetize_command,
ptr, size,
"", 0);
queuebuf_free(q);
q = NULL;
PROCESS_EXIT();
}
memcpy(ptr + size, input->data1, input->len1);
size += input->len1;
memcpy(ptr + size, input->data2, input->len2);
size += input->len2;
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_routes_process, ev, data)
{
struct {
uint16_t len;
uint16_t dest;
uint16_t nexthop;
uint16_t hop_count;
uint16_t seqno;
} msg;
int i;
struct route_entry *r;
PROCESS_BEGIN();
memset(&msg, 0, sizeof(msg));
msg.len = 4;
for(i = 0; i < route_num(); ++i) {
r = route_get(i);
rimeaddr_copy((rimeaddr_t *)&msg.dest, &r->dest);
rimeaddr_copy((rimeaddr_t *)&msg.nexthop, &r->nexthop);
msg.hop_count = r->hop_count;
msg.seqno = r->seqno;
shell_output(&routes_command, &msg, sizeof(msg), "", 0);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_neighbors_process, ev, data)
{
struct {
uint16_t len;
uint16_t addr;
uint16_t rtmetric;
uint16_t etx;
} msg;
int i;
struct neighbor *n;
PROCESS_BEGIN();
for(i = 0; i < neighbor_num(); ++i) {
n = neighbor_get(i);
if(!rimeaddr_cmp(&n->addr, &rimeaddr_null)) {
memset(&msg, 0, sizeof(msg));
msg.len = 3;
rimeaddr_copy((rimeaddr_t *)&msg.addr, &n->addr);
msg.rtmetric = n->rtmetric;
msg.etx = neighbor_etx(n);
shell_output(&neighbors_command, &msg, sizeof(msg), "", 0);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_netcmd_server_process, ev, data)
{
static struct process *child_command;
int err;
PROCESS_BEGIN();
/* XXX: direct output to null. */
printf("netcmd server got command string '%s'\n", (char *)data);
err = shell_start_command(data, strlen((char * )data), NULL, &child_command);
if(err == SHELL_FOREGROUND && process_is_running(child_command)) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT ||
(ev == PROCESS_EVENT_EXITED &&
data == child_command));
if(ev == PROCESS_EVENT_EXIT) {
process_exit(child_command);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_netcmd_process, ev, data)
{
struct trickle_msg *msg;
int len;
PROCESS_BEGIN();
len = strlen((char *)data);
if(len > RIMEBUF_SIZE) {
char buf[32];
snprintf(buf, sizeof(buf), "%d", len);
shell_output_str(&netcmd_command, "command line too large: ", buf);
} else {
rimebuf_clear();
msg = rimebuf_dataptr();
rimebuf_set_datalen(1 + len + 1);
msg->type = TRICKLE_TYPE_NETCMD;
strcpy(msg->netcmd, data);
printf("netcmd sending '%s'\n", msg->netcmd);
trickle_send(&trickle);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_nodes_process, ev, data)
{
static struct etimer etimer;
struct trickle_msg *msg;
char buf[10];
PROCESS_BEGIN();
if(!is_sink) {
shell_output_str(&nodes_command,
"Setting up a collection network...", "");
#if TIMESYNCH_CONF_ENABLED
timesynch_set_authority_level(0);
#endif
collect_set_sink(&collect, 1);
etimer_set(&etimer, CLOCK_SECOND * 2);
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
is_sink = 1;
}
rimebuf_clear();
msg = rimebuf_dataptr();
rimebuf_set_datalen(sizeof(struct trickle_msg));
msg->type = TRICKLE_TYPE_NODES;
trickle_send(&trickle);
etimer_set(&etimer, CLOCK_SECOND * 10);
waiting_for_nodes = 1;
shell_output_str(&nodes_command,
"Request sent, waiting for replies...", "");
messages_received = 0;
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
snprintf(buf, sizeof(buf), "%d", messages_received);
shell_output_str(&nodes_command, buf, " nodes heard");
waiting_for_nodes = 0;
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
#if WITH_TREEDEPTH
PROCESS_THREAD(shell_treedepth_process, ev, data)
{
char buf[20];
PROCESS_BEGIN();
snprintf(buf, sizeof(buf), "%d", collect_depth(&collect));
shell_output_str(&treedepth_command, buf, "");
PROCESS_END();
}
#endif /* WITH_TREEDEPTH */
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_collect_process, ev, data)
{
PROCESS_BEGIN();
#if TIMESYNCH_CONF_ENABLED
timesynch_set_authority_level(0);
#endif
collect_set_sink(&collect, 1);
is_sink = 1;
waiting_for_collect = 1;
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
waiting_for_collect = 0;
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_send_process, ev, data)
{
struct shell_input *input;
int len;
struct collect_msg *msg;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
len = input->len1 + input->len2;
if(len == 0) {
PROCESS_EXIT();
}
if(len < RIMEBUF_SIZE) {
rimebuf_clear();
rimebuf_set_datalen(len + COLLECT_MSG_HDRSIZE);
msg = rimebuf_dataptr();
memcpy(msg->data, input->data1, input->len1);
memcpy(msg->data + input->len1, input->data2, input->len2);
#if TIMESYNCH_CONF_ENABLED
msg->timestamp = timesynch_time();
#else
msg->timestamp = 0;
#endif
/* printf("Sending %d bytes\n", len);*/
collect_send(&collect, COLLECT_REXMITS);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
#if WITH_DEBUG_COMMANDS
PROCESS_THREAD(shell_broadcast_process, ev, data)
{
struct shell_input *input;
int len;
struct collect_msg *msg;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
len = input->len1 + input->len2;
if(len == 0) {
PROCESS_EXIT();
}
if(len < RIMEBUF_SIZE) {
rimebuf_clear();
rimebuf_set_datalen(len + COLLECT_MSG_HDRSIZE);
msg = rimebuf_dataptr();
memcpy(msg->data, input->data1, input->len1);
memcpy(msg->data + input->len1, input->data2, input->len2);
#if TIMESYNCH_CONF_ENABLED
msg->timestamp = timesynch_time();
#else
msg->timestamp = 0;
#endif
/* printf("Sending %d bytes\n", len);*/
abc_send(&abc);
}
}
PROCESS_END();
}
static void
recv_abc(struct abc_conn *c)
{
printf("abc message received\n");
}
static const struct abc_callbacks abc_callbacks = {recv_abc};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_unicast_process, ev, data)
{
struct shell_input *input;
static rimeaddr_t receiver;
int len;
const char *nextptr;
struct collect_msg *msg;
char buf[30];
PROCESS_BEGIN();
receiver.u8[0] = shell_strtolong(data, &nextptr);
if(nextptr == data || *nextptr != '.') {
shell_output_str(&unicast_command,
"unicast <receiver>: recevier must be specified", "");
PROCESS_EXIT();
}
++nextptr;
receiver.u8[1] = shell_strtolong(nextptr, &nextptr);
snprintf(buf, sizeof(buf), "%d.%d", receiver.u8[0], receiver.u8[1]);
shell_output_str(&unicast_command, "Sending unicast packets to ", buf);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
len = input->len1 + input->len2;
if(len == 0) {
PROCESS_EXIT();
}
if(len < RIMEBUF_SIZE) {
rimebuf_clear();
rimebuf_set_datalen(len + COLLECT_MSG_HDRSIZE);
msg = rimebuf_dataptr();
memcpy(msg->data, input->data1, input->len1);
memcpy(msg->data + input->len1, input->data2, input->len2);
#if TIMESYNCH_CONF_ENABLED
msg->timestamp = timesynch_time();
#else
msg->timestamp = 0;
#endif
/* printf("Sending %d bytes\n", len);*/
uc_send(&uc, &receiver);
}
}
PROCESS_END();
}
static void
recv_uc(struct uc_conn *c, rimeaddr_t *from)
{
printf("uc message received from %d.%d\n", from->u8[0], from->u8[1]);
}
static const struct uc_callbacks uc_callbacks = {recv_uc};
#endif /* WITH_DEBUG_COMMANDS */
/*---------------------------------------------------------------------------*/
static void
recv_collect(rimeaddr_t *originator, u8_t seqno, u8_t hops)
{
struct collect_msg *collect_msg;
rtimer_clock_t latency;
collect_msg = rimebuf_dataptr();
#if TIMESYNCH_CONF_ENABLED
latency = timesynch_time() - collect_msg->timestamp;
#else
latency = 0;
#endif
if(waiting_for_collect) {
struct {
uint16_t len;
uint16_t originator;
uint16_t seqno;
uint16_t hops;
uint16_t latency;
} msg;
msg.len = 5 + (rimebuf_datalen() - COLLECT_MSG_HDRSIZE) / 2;
rimeaddr_copy((rimeaddr_t *)&msg.originator, originator);
msg.seqno = seqno;
msg.hops = hops;
msg.latency = latency;
/* printf("recv_collect datalen %d\n", rimebuf_datalen());*/
shell_output(&collect_command,
&msg, sizeof(msg),
collect_msg->data, rimebuf_datalen() - COLLECT_MSG_HDRSIZE);
} else if(waiting_for_nodes) {
char buf[40];
snprintf(buf, sizeof(buf), "%d.%d, %d hops, latency %lu ms",
originator->u8[0], originator->u8[1],
hops, (1000L * latency) / RTIMER_ARCH_SECOND);
shell_output_str(&nodes_command, "Message from node ", buf);
messages_received++;
}
}
static const struct collect_callbacks collect_callbacks = { recv_collect };
/*---------------------------------------------------------------------------*/
static void
send_collect(void *dummy)
{
struct collect_msg msg;
#if TIMESYNCH_CONF_ENABLED
msg.timestamp = timesynch_time();
#else
msg.timestamp = 0;
#endif
rimebuf_copyfrom(&msg, COLLECT_MSG_HDRSIZE);
collect_send(&collect, COLLECT_REXMITS);
}
/*---------------------------------------------------------------------------*/
static void
recv_trickle(struct trickle_conn *c)
{
struct trickle_msg *msg;
msg = rimebuf_dataptr();
if(msg->type == TRICKLE_TYPE_NODES) {
ctimer_set(&ctimer, random_rand() % (CLOCK_SECOND * 2),
send_collect, NULL);
} else if(msg->type == TRICKLE_TYPE_NETCMD) {
/* First ensure that the old process is killed. */
process_exit(&shell_netcmd_server_process);
/* Make sure that the incoming command is null-terminated (which
is should be already). */
msg->netcmd[rimebuf_datalen() - 2] = 0;
/* Start the server process with the incoming command. */
process_start(&shell_netcmd_server_process, msg->netcmd);
}
}
const static struct trickle_callbacks trickle_callbacks = { recv_trickle };
/*---------------------------------------------------------------------------*/
void
shell_rime_init(void)
{
trickle_open(&trickle, CLOCK_SECOND * 4, 16, &trickle_callbacks);
collect_open(&collect, 17, &collect_callbacks);
shell_register_command(&collect_command);
shell_register_command(&neighbors_command);
shell_register_command(&netcmd_command);
shell_register_command(&nodes_command);
shell_register_command(&packetize_command);
shell_register_command(&routes_command);
shell_register_command(&send_command);
#if WITH_TREEDEPTH
shell_register_command(&treedepth_command);
#endif /* WITH_TREEDEPTH */
#if WITH_DEBUG_COMMANDS
uc_open(&uc, 14, &uc_callbacks);
abc_open(&abc, 15, &abc_callbacks);
shell_register_command(&broadcast_command);
shell_register_command(&unicast_command);
#endif /* WITH_DEBUG_COMMANDS */
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-rime.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rime.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_RIME_H__
#define __SHELL_RIME_H__
#include "shell.h"
void shell_rime_init(void);
#endif /* __SHELL_RIME_H__ */

215
apps/shell/shell-rsh.c Normal file
View file

@ -0,0 +1,215 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rsh.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell.h"
#include "net/rime.h"
#include "net/rime/meshconn.h"
#include <stdio.h>
#include <string.h>
static struct meshconn_conn meshconn;
static struct process *front_process;
static int initiator = 0;
/*---------------------------------------------------------------------------*/
PROCESS(shell_rsh_process, "rsh");
SHELL_COMMAND(rsh_command,
"rsh",
"rsh <node>: remote login to another node",
&shell_rsh_process);
PROCESS(shell_rsh_server_process, "rsh server");
/*SHELL_COMMAND(rsh_server_command,
"rsh server",
"rsh server: never invoked directly",
&shell_rsh_server_process);*/
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_rsh_process, ev, data)
{
static rimeaddr_t receiver;
const char *nextptr;
char buf[40];
PROCESS_BEGIN();
receiver.u8[0] = shell_strtolong(data, &nextptr);
if(nextptr == data || *nextptr != '.') {
shell_output_str(&rsh_command,
"rsh <node>: node address must be specified", "");
PROCESS_EXIT();
}
++nextptr;
receiver.u8[1] = shell_strtolong(nextptr, &nextptr);
sprintf(buf, "%d.%d", receiver.u8[0], receiver.u8[1]);
shell_output_str(&rsh_command, "Connecting to ", buf);
initiator = 1;
meshconn_connect(&meshconn, &receiver);
while(1) {
struct shell_input *input;
PROCESS_WAIT_EVENT();
if(ev == shell_event_input) {
input = data;
if(input->len1 + input->len2 == 0) {
meshconn_close_connection(&meshconn);
PROCESS_EXIT();
}
if(input->len1 + input->len2 >= RIMEBUF_SIZE) {
shell_output_str(&rsh_command, "rsh: input too long", "");
} else {
rimebuf_clear();
memcpy(rimebuf_dataptr(), input->data1, input->len1);
memcpy((char *)rimebuf_dataptr() + input->len1,
input->data2, input->len2);
rimebuf_set_datalen(input->len1 + input->len2);
meshconn_send(&meshconn);
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_rsh_server_process, ev, data)
{
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input ||
(ev == PROCESS_EVENT_EXITED &&
data == front_process));
if(ev == PROCESS_EVENT_EXITED) {
front_process = NULL;
} else if(ev == shell_event_input) {
struct shell_input *input;
input = data;
rimebuf_clear();
memcpy(rimebuf_dataptr(), input->data1, input->len1);
memcpy((char *)rimebuf_dataptr() + input->len1,
input->data2, input->len2);
rimebuf_set_datalen(input->len1 + input->len2);
printf("Sending meshconn with %d + %d bytes\n",
input->len1, input->len2);
meshconn_send(&meshconn);
}
/* PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);*/
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
connected_meshconn(struct meshconn_conn *c)
{
printf("connected\n");
}
static void
recv_meshconn(struct meshconn_conn *c)
{
/* int ret;
struct process *started_process;*/
/* printf("got '%.*s'\n", rimebuf_datalen(), (char *)rimebuf_dataptr());*/
/* Echo reply */
if(!initiator) {
rimebuf_copyfrom("abcdefghijklmnopq", 18);
meshconn_send(c);
}
return;
#if 0
if(front_process != NULL &&
process_is_running(front_process)) {
struct shell_input input;
input.data1 = rimebuf_dataptr();
input.len1 = rimebuf_datalen();
input.data2 = "";
input.len2 = 0;
process_post_synch(front_process, shell_event_input, &input);
} else {
ret = shell_start_command(rimebuf_dataptr(), rimebuf_datalen(),
&rsh_server_command, &started_process);
if(started_process != NULL &&
ret == SHELL_FOREGROUND &&
process_is_running(started_process)) {
front_process = started_process;
}
}
/* shell_input(rimebuf_dataptr(), rimebuf_datalen());*/
/* shell_output(&rsh_command, rimebuf_dataptr(), rimebuf_datalen(), "", 0);*/
#endif
}
static void
closed_meshconn(struct meshconn_conn *c)
{
printf("closed\n");
}
static void
timedout_meshconn(struct meshconn_conn *c)
{
printf("timedout\n");
}
static void
reset_meshconn(struct meshconn_conn *c)
{
printf("reset\n");
}
/*---------------------------------------------------------------------------*/
static struct meshconn_callbacks meshconn_callbacks = { connected_meshconn,
recv_meshconn,
closed_meshconn,
timedout_meshconn,
reset_meshconn };
/*---------------------------------------------------------------------------*/
void
shell_rsh_init(void)
{
meshconn_open(&meshconn, 23, &meshconn_callbacks);
shell_register_command(&rsh_command);
process_start(&shell_rsh_server_process, NULL);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-rsh.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-rsh.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_RSH_H__
#define __SHELL_RSH_H__
#include "shell.h"
void shell_rsh_init(void);
#endif /* __SHELL_RSH_H__ */

169
apps/shell/shell-sendtest.c Normal file
View file

@ -0,0 +1,169 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-sendtest.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell-ps.h"
#include "net/rime.h"
#include <stdio.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_sendtest_process, "sendtest");
SHELL_COMMAND(sendtest_command,
"sendtest",
"sendtest: measure single-hop throughput",
&shell_sendtest_process);
/*---------------------------------------------------------------------------*/
static clock_time_t start_time_rucb, end_time_rucb;
static unsigned long filesize, bytecount, packetsize;
static int download_complete;
static void
write_chunk(struct rucb_conn *c, int offset, int flag,
char *data, int datalen)
{
#if NETSIM
{
char buf[100];
printf("received %d; %d\n", offset, datalen);
sprintf(buf, "%d%%", (100 * (offset + datalen)) / filesize);
ether_set_text(buf);
}
#endif /* NETSIM */
printf("+");
}
static int
read_chunk(struct rucb_conn *c, int offset, char *to, int maxsize)
{
int size;
printf("-");
size = maxsize;
if(bytecount + maxsize >= filesize) {
size = filesize - bytecount;
}
if(size > packetsize) {
size = packetsize;
}
bytecount += size;
if(bytecount == filesize) {
end_time_rucb = clock_time();
download_complete = 1;
process_post(&shell_sendtest_process, PROCESS_EVENT_CONTINUE, NULL);
/* profile_aggregates_print(); */
/* profile_print_stats(); */
// print_stats();
}
/* printf("bytecount %lu\n", bytecount);*/
return size;
}
const static struct rucb_callbacks rucb_callbacks = {write_chunk,
read_chunk,
NULL};
static struct rucb_conn rucb;
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_sendtest_process, ev, data)
{
static rimeaddr_t receiver;
const char *nextptr;
const char *args;
char buf[40];
PROCESS_BEGIN();
args = data;
receiver.u8[0] = shell_strtolong(args, &nextptr);
if(nextptr == data || *nextptr != '.') {
shell_output_str(&sendtest_command,
"sendtest <receiver> <size> [packetsize]: recevier must be specified", "");
PROCESS_EXIT();
}
args = nextptr + 1;
receiver.u8[1] = shell_strtolong(args, &nextptr);
args = nextptr;
while(*args == ' ') {
++args;
}
filesize = shell_strtolong(args, &nextptr);
if(nextptr == data || filesize == 0) {
shell_output_str(&sendtest_command,
"sendtest <receiver> <size> [packetsize]: size must be specified and > 0", "");
PROCESS_EXIT();
}
args = nextptr;
while(*args == ' ') {
++args;
}
packetsize = 64;
packetsize = shell_strtolong(args, &nextptr);
if(packetsize == 0) {
shell_output_str(&sendtest_command,
"sendtest <receiver> <size> [packetsize]: packetsize must be > 0", "");
PROCESS_EXIT();
}
snprintf(buf, sizeof(buf), "%d.%d, %lu bytes, packetsize %lu",
receiver.u8[0], receiver.u8[1], filesize, packetsize);
shell_output_str(&sendtest_command, "Sending data to ", buf);
bytecount = 0;
download_complete = 0;
start_time_rucb = clock_time();
rucb_send(&rucb, &receiver);
PROCESS_WAIT_UNTIL(download_complete);
sprintf(buf, "%d seconds, %lu bytes/second",
(int)((end_time_rucb - start_time_rucb) / CLOCK_SECOND),
CLOCK_SECOND * filesize / (end_time_rucb - start_time_rucb));
shell_output_str(&sendtest_command, "Completed in ", buf);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_sendtest_init(void)
{
rucb_open(&rucb, 22, &rucb_callbacks);
shell_register_command(&sendtest_command);
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-sendtest.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_SENDTEST_H__
#define __SHELL_SENDTEST_H__
#include "shell.h"
void shell_sendtest_init(void);
#endif /* __SHELL_SENDTEST_H__ */

362
apps/shell/shell-sky.c Normal file
View file

@ -0,0 +1,362 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-sky.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Tmote Sky-specific Contiki shell commands
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell-sky.h"
#include "dev/watchdog.h"
#include "net/rime.h"
#include "dev/simple-cc2420.h"
#include "dev/leds.h"
#include "dev/light.h"
#include "dev/sht11.h"
#include "net/rime/timesynch.h"
#include <stdio.h>
#include <string.h>
struct power_msg {
uint16_t len;
uint32_t cpu;
uint32_t lpm;
uint32_t transmit;
uint32_t listen;
};
/*---------------------------------------------------------------------------*/
PROCESS(shell_sense_process, "sense");
SHELL_COMMAND(sense_command,
"sense",
"sense: print out sensor data",
&shell_sense_process);
PROCESS(shell_senseconv_process, "senseconv");
SHELL_COMMAND(senseconv_command,
"senseconv",
"senseconv: convert 'sense' data to human readable format",
&shell_senseconv_process);
PROCESS(shell_txpower_process, "txpower");
SHELL_COMMAND(txpower_command,
"txpower",
"txpower <power>: change CC2420 transmission power (0 - 31)",
&shell_txpower_process);
PROCESS(shell_rfchannel_process, "rfchannel");
SHELL_COMMAND(rfchannel_command,
"rfchannel",
"rfchannel <power>: change CC2420 transmission power (0 - 31)",
&shell_rfchannel_process);
PROCESS(shell_power_process, "power");
SHELL_COMMAND(power_command,
"power",
"power: print power profile",
&shell_power_process);
PROCESS(shell_energy_process, "energy");
SHELL_COMMAND(energy_command,
"energy",
"energy: print energy profile",
&shell_energy_process);
PROCESS(shell_powerconv_process, "powerconv");
SHELL_COMMAND(powerconv_command,
"powerconv",
"powerconv: convert power profile to human readable output",
&shell_powerconv_process);
/*---------------------------------------------------------------------------*/
#define MAX(a, b) ((a) > (b)? (a): (b))
#define MIN(a, b) ((a) < (b)? (a): (b))
struct spectrum {
int channel[16];
};
#define NUM_SAMPLES 4
static struct spectrum rssi_samples[NUM_SAMPLES];
static int
do_rssi(void)
{
static int sample;
int channel;
rime_mac->off();
simple_cc2420_on();
for(channel = 11; channel <= 26; ++channel) {
simple_cc2420_set_channel(channel);
rssi_samples[sample].channel[channel - 11] = simple_cc2420_rssi() + 53;
}
rime_mac->on();
sample = (sample + 1) % NUM_SAMPLES;
{
int channel, tot;
tot = 0;
for(channel = 0; channel < 16; ++channel) {
int max = -256;
int i;
for(i = 0; i < NUM_SAMPLES; ++i) {
max = MAX(max, rssi_samples[i].channel[channel]);
}
tot += max / 20;
}
return tot;
}
}
/*---------------------------------------------------------------------------*/
struct sense_msg {
uint16_t len;
uint16_t clock;
uint16_t timesynch_time;
uint16_t light1;
uint16_t light2;
uint16_t temp;
uint16_t humidity;
uint16_t rssi;
};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_sense_process, ev, data)
{
struct sense_msg msg;
PROCESS_BEGIN();
msg.len = 7;
msg.clock = clock_time();
msg.timesynch_time = timesynch_time();
msg.light1 = sensors_light1();
msg.light2 = sensors_light2();
msg.temp = sht11_temp();
msg.humidity = sht11_humidity();
msg.rssi = do_rssi();
shell_output(&sense_command, &msg, sizeof(msg), "", 0);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_senseconv_process, ev, data)
{
struct shell_input *input;
struct sense_msg *msg;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
if(input->len1 + input->len2 == 0) {
PROCESS_EXIT();
}
msg = (struct sense_msg *)input->data1;
if(msg != NULL) {
char buf[40];
snprintf(buf, sizeof(buf),
"l1 %d l2 %d t %d.%d h %d r %d\n",
10 * msg->light1 / 7,
46 * msg->light2 / 10,
(msg->temp / 10 - 396) / 10,
(msg->temp / 10 - 396) % 10,
(int)(-4L + 405L * msg->humidity / 10000L),
msg->rssi);
shell_output(&senseconv_command, buf, strlen(buf), "", 0);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_txpower_process, ev, data)
{
struct {
uint16_t len;
uint16_t txpower;
} msg;
const char *newptr;
PROCESS_BEGIN();
msg.txpower = shell_strtolong(data, &newptr);
/* If no transmission power was given on the command line, we print
out the current txpower. */
if(newptr == data) {
msg.txpower = simple_cc2420_get_txpower();
} else {
simple_cc2420_set_txpower(msg.txpower);
}
msg.len = 1;
shell_output(&txpower_command, &msg, sizeof(msg), "", 0);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_rfchannel_process, ev, data)
{
struct {
uint16_t len;
uint16_t channel;
} msg;
const char *newptr;
PROCESS_BEGIN();
msg.channel = shell_strtolong(data, &newptr);
/* If no channel was given on the command line, we print out the
current channel. */
if(newptr == data) {
msg.channel = simple_cc2420_get_channel();
} else {
simple_cc2420_set_channel(msg.channel);
}
msg.len = 1;
shell_output(&txpower_command, &msg, sizeof(msg), "", 0);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_power_process, ev, data)
{
static unsigned long last_cpu, last_lpm, last_transmit, last_listen;
struct power_msg msg;
PROCESS_BEGIN();
msg.len = 8;
msg.cpu = energest_type_time(ENERGEST_TYPE_CPU) - last_cpu;
msg.lpm = energest_type_time(ENERGEST_TYPE_LPM) - last_lpm;
msg.transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT) - last_transmit;
msg.listen = energest_type_time(ENERGEST_TYPE_LISTEN) - last_listen;
last_cpu = energest_type_time(ENERGEST_TYPE_CPU);
last_lpm = energest_type_time(ENERGEST_TYPE_LPM);
last_transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT);
last_listen = energest_type_time(ENERGEST_TYPE_LISTEN);
shell_output(&power_command, &msg, sizeof(msg), "", 0);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_energy_process, ev, data)
{
struct power_msg msg;
PROCESS_BEGIN();
msg.len = 8;
msg.cpu = energest_type_time(ENERGEST_TYPE_CPU);
msg.lpm = energest_type_time(ENERGEST_TYPE_LPM);
msg.transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT);
msg.listen = energest_type_time(ENERGEST_TYPE_LISTEN);
shell_output(&energy_command, &msg, sizeof(msg), "", 0);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
#define DEC2FIX(h,d) ((h * 64L) + (unsigned long)((d * 64L) / 1000L))
static void
printpower(struct power_msg *msg)
{
char buf[50];
unsigned long avg_power;
unsigned long time;
time = msg->cpu + msg->lpm;
avg_power = (3L *
(msg->cpu * DEC2FIX(1L,800L) +
msg->lpm * DEC2FIX(0L,545L) +
msg->transmit * DEC2FIX(17L,700L) +
msg->listen * DEC2FIX(20L,0))) / ((64L * time) / 1000);
snprintf(buf, sizeof(buf), "CPU %d%% LPM %d%% tx %d%% rx %d%% tot %lu uW",
(int)((100L * (unsigned long)msg->cpu) / time),
(int)((100L * (unsigned long)msg->lpm) / time),
(int)((100L * (unsigned long)msg->transmit) / time),
(int)((100L * (unsigned long)msg->listen) / time),
avg_power);
shell_output_str(&powerconv_command, buf, "");
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_powerconv_process, ev, data)
{
struct power_msg *msg;
struct shell_input *input;
int len;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
if(input->len1 + input->len2 == 0) {
PROCESS_EXIT();
}
len = input->len1;
for(msg = (struct power_msg *)input->data1;
len > 0;
msg++, len -= sizeof(struct power_msg)) {
printpower(msg);
}
len = input->len2;
for(msg = (struct power_msg *)input->data2;
len > 0;
msg++, len -= sizeof(struct power_msg)) {
printpower(msg);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_sky_init(void)
{
shell_register_command(&power_command);
shell_register_command(&powerconv_command);
shell_register_command(&energy_command);
shell_register_command(&txpower_command);
shell_register_command(&rfchannel_command);
shell_register_command(&sense_command);
shell_register_command(&senseconv_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-sky.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-sky.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* Header file for Tmote Sky-specific Contiki shell commands
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_SKY_H__
#define __SHELL_SKY_H__
#include "shell.h"
void shell_sky_init(void);
#endif /* __SHELL_SKY_H__ */

298
apps/shell/shell-text.c Normal file
View file

@ -0,0 +1,298 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-text.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell.h"
#include <ctype.h>
#include <stdio.h>
#ifndef HAVE_SNPRINTF
int snprintf(char *str, size_t size, const char *format, ...);
#endif /* HAVE_SNPRINTF */
#include <string.h>
/*---------------------------------------------------------------------------*/
PROCESS(shell_echo_process, "echo");
SHELL_COMMAND(echo_command,
"echo",
"echo <text>: print <text>",
&shell_echo_process);
PROCESS(shell_dec64_process, "dec64");
SHELL_COMMAND(dec64_command,
"dec64",
"dec64: decode base64 input",
&shell_dec64_process);
PROCESS(shell_binprint_process, "binprint");
SHELL_COMMAND(binprint_command,
"binprint",
"binprint: print binary data in decimal format",
&shell_binprint_process);
PROCESS(shell_hd_process, "hd");
SHELL_COMMAND(hd_command,
"hd",
"hd: print binary data in hexadecimal format",
&shell_hd_process);
PROCESS(shell_size_process, "size");
SHELL_COMMAND(size_command,
"size",
"size: print the size of the input",
&shell_size_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_echo_process, ev, data)
{
PROCESS_BEGIN();
shell_output(&echo_command, data, strlen(data), "\n", 1);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
#define BASE64_MAX_LINELEN 76
struct base64_decoder_state {
uint8_t data[3 * BASE64_MAX_LINELEN / 4];
int dataptr;
unsigned long tmpdata;
int sextets;
int padding;
};
/*---------------------------------------------------------------------------*/
static int
base64_decode_char(char c)
{
if(c >= 'A' && c <= 'Z') {
return c - 'A';
} else if(c >= 'a' && c <= 'z') {
return c - 'a' + 26;
} else if(c >= '0' && c <= '9') {
return c - '0' + 52;
} else if(c == '+') {
return 62;
} else if(c == '/') {
return 63;
} else {
return 0;
}
}
/*---------------------------------------------------------------------------*/
static int
base64_add_char(struct base64_decoder_state *s, char c)
{
if(isspace(c)) {
return 0;
}
if(s->dataptr >= sizeof(s->data)) {
return 0;
}
if(c == '=') {
++s->padding;
}
s->tmpdata = (s->tmpdata << 6) | base64_decode_char(c);
++s->sextets;
if(s->sextets == 4) {
s->sextets = 0;
s->data[s->dataptr] = (s->tmpdata >> 16) & 0xff;
s->data[s->dataptr + 1] = (s->tmpdata >> 8) & 0xff;
s->data[s->dataptr + 2] = (s->tmpdata) & 0xff;
s->dataptr += 3;
if(s->dataptr == sizeof(s->data)) {
return 0;
} else {
return 1;
}
}
return 1;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_dec64_process, ev, data)
{
PROCESS_BEGIN();
while(1) {
struct shell_input *input;
struct base64_decoder_state s;
int i;
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
if(input->len1 + input->len2 == 0) {
PROCESS_EXIT();
}
s.sextets = s.dataptr = s.padding = 0;
for(i = 0; i < input->len1; ++i) {
base64_add_char(&s, input->data1[i]);
}
for(i = 0; i < input->len2; ++i) {
base64_add_char(&s, input->data2[i]);
}
shell_output(&dec64_command, s.data, s.dataptr - s.padding, "", 0);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_hd_process, ev, data)
{
struct shell_input *input;
PROCESS_BEGIN();
uint16_t *ptr;
int i;
char buf[57], *bufptr;
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
if(input->len1 + input->len2 == 0) {
PROCESS_EXIT();
}
bufptr = buf;
ptr = (uint16_t *)input->data1;
for(i = 0; i < input->len1 && i < input->len1 - 1; i += 2) {
bufptr += sprintf(bufptr, "0x%04x ", *ptr);
if(bufptr - buf >= sizeof(buf) - 7) {
shell_output_str(&hd_command, buf, "");
bufptr = buf;
}
ptr++;
}
ptr = (uint16_t *)input->data2;
for(i = 0; i < input->len2 && i < input->len2 - 1; i += 2) {
bufptr += sprintf(bufptr, "0x%04x ", *ptr);
if(bufptr - buf >= sizeof(buf) - 7) {
shell_output_str(&hd_command, buf, "");
bufptr = buf;
}
ptr++;
}
if(bufptr != buf) {
shell_output_str(&hd_command, buf, "");
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_binprint_process, ev, data)
{
struct shell_input *input;
PROCESS_BEGIN();
uint16_t *ptr;
int i;
char buf[2*64], *bufptr;
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
if(input->len1 + input->len2 == 0) {
PROCESS_EXIT();
}
bufptr = buf;
ptr = (uint16_t *)input->data1;
for(i = 0; i < input->len1 && i < input->len1 - 1; i += 2) {
bufptr += sprintf(bufptr, "%u ", *ptr);
if(bufptr - buf >= sizeof(buf) - 6) {
shell_output_str(&binprint_command, buf, "");
bufptr = buf;
}
ptr++;
}
ptr = (uint16_t *)input->data2;
for(i = 0; i < input->len2 && i < input->len2 - 1; i += 2) {
bufptr += sprintf(bufptr, "%u ", *ptr);
if(bufptr - buf >= sizeof(buf) - 6) {
shell_output_str(&binprint_command, buf, "");
bufptr = buf;
}
ptr++;
}
if(bufptr != buf) {
shell_output_str(&binprint_command, buf, "");
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_size_process, ev, data)
{
struct shell_input *input;
static unsigned long size;
PROCESS_BEGIN();
size = 0;
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
size += input->len1 + input->len2;
if(input->len1 + input->len2 == 0) {
char buf[10];
snprintf(buf, sizeof(buf), "%lu", size);
shell_output_str(&size_command, buf, "");
PROCESS_EXIT();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_text_init(void)
{
shell_register_command(&binprint_command);
shell_register_command(&hd_command);
shell_register_command(&echo_command);
shell_register_command(&dec64_command);
shell_register_command(&size_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-text.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-text.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_TEXT_H__
#define __SHELL_TEXT_H__
#include "shell.h"
void shell_text_init(void);
#endif /* __SHELL_TEXT_H__ */

347
apps/shell/shell-time.c Normal file
View file

@ -0,0 +1,347 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-time.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "shell-time.h"
#include "sys/clock.h"
#include "net/rime/timesynch.h"
#include "lib/random.h"
#include <stdio.h>
#include <string.h>
#define MAX_COMMANDLENGTH 64
/*---------------------------------------------------------------------------*/
PROCESS(shell_time_process, "time");
SHELL_COMMAND(time_command,
"time",
"time [seconds]: print time or set time in seconds since 1970",
&shell_time_process);
PROCESS(shell_timestamp_process, "timestamp");
SHELL_COMMAND(timestamp_command,
"timestamp",
"timestamp: prepent a timestamp to data",
&shell_timestamp_process);
PROCESS(shell_repeat_process, "repeat");
PROCESS(shell_repeat_server_process, "repeat server");
SHELL_COMMAND(repeat_command,
"repeat",
"repeat <num> <time> <command>: run a command every <time> seconds",
&shell_repeat_process);
PROCESS(shell_randwait_process, "randwait");
SHELL_COMMAND(randwait_command,
"randwait",
"randwait <maxtime> <command>: wait for a random time before running a command",
&shell_randwait_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_time_process, ev, data)
{
struct {
uint16_t len;
uint16_t clock;
uint16_t rtimer;
uint16_t timesynch;
uint16_t timesynch_authority;
uint16_t time[2];
} msg;
unsigned long newtime;
PROCESS_BEGIN();
if(data != NULL) {
const char *nextptr;
newtime = shell_strtolong(data, &nextptr);
if(data != nextptr) {
shell_set_time(newtime);
}
}
msg.clock = clock_time();
msg.rtimer = rtimer_arch_now();
#if TIMESYNCH_CONF_ENABLED
msg.timesynch = timesynch_time();
msg.timesynch_authority = timesynch_authority_level();
#else
msg.timesynch = 0;
msg.timesynch_authority = -1;
#endif
msg.time[0] = shell_time() >> 16;
msg.time[1] = shell_time();
msg.len = 6;
shell_output(&time_command, &msg, sizeof(msg), "", 0);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_timestamp_process, ev, data)
{
struct msg {
uint16_t len;
uint16_t time[2];
uint16_t timesynch;
uint8_t data[MAX_COMMANDLENGTH];
} msg;
PROCESS_BEGIN();
while(1) {
struct shell_input *input;
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
if(input->len1 + input->len2 == 0) {
PROCESS_EXIT();
}
msg.len = 3 + *(uint16_t *)input->data1;
msg.time[0] = shell_time() >> 16;
msg.time[1] = shell_time();
#if TIMESYNCH_CONF_ENABLED
msg.timesynch = timesynch_time();
#else /* TIMESYNCH_CONF_ENABLED */
msg.timesynch = 0;
#endif /* TIMESYNCH_CONF_ENABLED */
memcpy(msg.data, input->data1 + 2,
input->len1 - 2 > MAX_COMMANDLENGTH?
MAX_COMMANDLENGTH: input->len1 - 2);
shell_output(&timestamp_command, &msg, 6 + input->len1,
input->data2, input->len2);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_repeat_server_process, ev, data)
{
static char *command;
char command_copy[MAX_COMMANDLENGTH];
if(ev == shell_event_input) {
goto exit;
}
PROCESS_BEGIN();
command = data;
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE &&
data == &shell_repeat_process);
{
int ret;
static struct process *started_process;
strncpy(command_copy, command, MAX_COMMANDLENGTH);
ret = shell_start_command(command_copy, strlen(command_copy),
&repeat_command, &started_process);
if(started_process != NULL &&
process_is_running(started_process)) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXITED &&
data == started_process);
}
}
/* PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
printf("haha \n");
if(repeat_command.child != NULL &&
process_is_running(repeat_command.child->process)) {
process_post_synch(repeat_command.child->process, ev, data);
}*/
exit:
;
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_repeat_process, ev, data)
{
static int reps, period;
static char command[MAX_COMMANDLENGTH];
static struct etimer etimer;
static int i;
const char *args, *next;
if(ev == shell_event_input) {
struct shell_input *input;
input = data;
/* printf("shell repeat input %d %d\n", input->len1, input->len2);*/
if(input->len1 + input->len2 != 0) {
shell_output(&repeat_command, input->data1, input->len1,
input->data2, input->len2);
}
}
PROCESS_BEGIN();
/* printf("data '%s'\n", data);*/
args = data;
if(args == NULL) {
shell_output_str(&repeat_command, "usage 0", "");
PROCESS_EXIT();
}
reps = shell_strtolong(args, &next);
if(next == args) {
shell_output_str(&repeat_command, "usage 1", "");
PROCESS_EXIT();
}
args = next;
period = shell_strtolong(args, &next);
if(next == args) {
shell_output_str(&repeat_command, "usage 2", "");
PROCESS_EXIT();
}
args = next;
while(*args == ' ') {
args++;
}
strncpy(command, args, MAX_COMMANDLENGTH);
if(strlen(command) == 0) {
shell_output_str(&repeat_command, "usage 3", "");
PROCESS_EXIT();
}
/* printf("repeats %d period %d command '%s'\n",
reps, period, command);*/
etimer_set(&etimer, CLOCK_SECOND * period);
for(i = 0; i < reps; ++i) {
process_start(&shell_repeat_server_process, command);
process_post(&shell_repeat_server_process,
PROCESS_EVENT_CONTINUE,
&shell_repeat_process);
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXITED &&
data == &shell_repeat_server_process);
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
etimer_reset(&etimer);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_randwait_process, ev, data)
{
static int maxwait;
static char command[MAX_COMMANDLENGTH];
static struct etimer etimer;
static struct process *started_process;
const char *args, *next;
int ret;
/* if(ev == shell_event_input) {
struct shell_input *input;
input = data;
printf("shell randwait input %d %d\n", input->len1, input->len2);
if(input->len1 + input->len2 != 0) {
shell_output(&randwait_command, input->data1, input->len1,
input->data2, input->len2);
}
}*/
PROCESS_BEGIN();
args = data;
if(args == NULL) {
shell_output_str(&randwait_command, "usage 0", "");
PROCESS_EXIT();
}
maxwait = shell_strtolong(args, &next);
if(next == args) {
shell_output_str(&randwait_command, "usage 1", "");
PROCESS_EXIT();
}
args = next;
while(*args == ' ') {
args++;
}
strncpy(command, args, MAX_COMMANDLENGTH);
if(strlen(command) == 0) {
shell_output_str(&repeat_command, "usage 3", "");
PROCESS_EXIT();
}
/* printf("randwait %d command '%s'\n",
maxwait, command);*/
etimer_set(&etimer, random_rand() % (CLOCK_SECOND * maxwait));
PROCESS_WAIT_UNTIL(etimer_expired(&etimer));
/* printf("Starting '%s' child %p (%s)\n", command, randwait_command.child, */
/* randwait_command.child == NULL? "null": randwait_command.child->command); */
ret = shell_start_command(command, strlen(command),
randwait_command.child, &started_process);
if(started_process != NULL &&
process_is_running(started_process)) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXITED &&
data == started_process);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_time_init(void)
{
shell_register_command(&time_command);
shell_register_command(&timestamp_command);
shell_register_command(&repeat_command);
shell_register_command(&randwait_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-time.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-time.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_TIME_H__
#define __SHELL_TIME_H__
#include "shell.h"
void shell_time_init(void);
#endif /* __SHELL_TIME_H__ */

135
apps/shell/shell-vars.c Normal file
View file

@ -0,0 +1,135 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-vars.c,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "contiki-conf.h"
#include "shell-vars.h"
#include "loader/symbols.h"
#include <stdio.h>
#include <string.h>
#ifdef SHELL_VARS_CONF_RAM_BEGIN
#define SHELL_VARS_RAM_BEGIN SHELL_VARS_CONF_RAM_BEGIN
#define SHELL_VARS_RAM_END SHELL_VARS_CONF_RAM_END
#else /* SHELL_VARS_CONF_RAM_BEGIN */
#define SHELL_VARS_RAM_BEGIN 0
#define SHELL_VARS_RAM_END (unsigned int)-1
#endif /* SHELL_VARS_CONF_RAM_BEGIN */
/*---------------------------------------------------------------------------*/
PROCESS(shell_vars_process, "vars");
SHELL_COMMAND(vars_command,
"vars",
"vars: list all variables in RAM",
&shell_vars_process);
/*---------------------------------------------------------------------------*/
PROCESS(shell_var_process, "var");
SHELL_COMMAND(var_command,
"var",
"var <variable>: show content of a variable",
&shell_var_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_vars_process, ev, data)
{
int i;
PROCESS_BEGIN();
shell_output_str(&vars_command, "Variables in RAM:", "");
for(i = 0; i < symbols_nelts; ++i) {
if(symbols[i].name != NULL &&
(unsigned int)symbols[i].value >= SHELL_VARS_RAM_BEGIN &&
(unsigned int)symbols[i].value <= SHELL_VARS_RAM_END) {
shell_output_str(&vars_command, (char *)symbols[i].name, "");
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_var_process, ev, data)
{
int i;
PROCESS_BEGIN();
if(data == NULL) {
shell_output_str(&var_command, "syntax: var <variable name>", "");
} else {
for(i = 0; i < symbols_nelts; ++i) {
if(symbols[i].name != NULL &&
strncmp(symbols[i].name, data, strlen(symbols[i].name)) == 0) {
char numbuf[32];
int j;
sprintf(numbuf, " %d", *((int *)symbols[i].value));
shell_output_str(&var_command, (char *)symbols[i].name, numbuf);
for(j = 0; j < 8 * 8; j += 8) {
sprintf(numbuf, "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
((unsigned char *)symbols[i].value)[j],
((unsigned char *)symbols[i].value)[j + 1],
((unsigned char *)symbols[i].value)[j + 2],
((unsigned char *)symbols[i].value)[j + 3],
((unsigned char *)symbols[i].value)[j + 4],
((unsigned char *)symbols[i].value)[j + 5],
((unsigned char *)symbols[i].value)[j + 6],
((unsigned char *)symbols[i].value)[j + 7]);
shell_output_str(&var_command, numbuf, "");
}
PROCESS_EXIT();
}
}
shell_output_str(&var_command, data, ": variable name not found");
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_vars_init(void)
{
shell_register_command(&var_command);
shell_register_command(&vars_command);
}
/*---------------------------------------------------------------------------*/

48
apps/shell/shell-vars.h Normal file
View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell-vars.h,v 1.1 2008/02/04 23:42:17 adamdunkels Exp $
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef __SHELL_VARS_H__
#define __SHELL_VARS_H__
#include "shell.h"
void shell_vars_init(void);
#endif /* __SHELL_VARS_H__ */

View file

@ -1,281 +1,513 @@
/*
* Copyright (c) 2003, Adam Dunkels.
* All rights reserved.
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki desktop OS.
*
* $Id: shell.c,v 1.5 2007/08/30 14:39:16 matsutsuka Exp $
* This file is part of the Contiki operating system.
*
* $Id: shell.c,v 1.6 2008/02/04 23:42:17 adamdunkels Exp $
*/
#include "program-handler.h"
#include "contiki-net.h"
#include "cfs/cfs.h"
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "contiki.h"
#include "contiki-lib.h"
#include "net/rime.h"
#include "shell.h"
#include <ctype.h>
#include <string.h>
#include <stdio.h>
static char showingdir = 0;
static struct cfs_dir dir;
static unsigned int totsize;
LIST(commands);
struct ptentry {
char c1;
char c2;
void (* pfunc)(char *str);
};
int shell_event_input;
/*-----------------------------------------------------------------------------------*/
static void
parse(CC_REGISTER_ARG char *str, struct ptentry *t)
static struct process *front_process;
static unsigned long time_offset;
PROCESS(shell_process, "Shell");
PROCESS(shell_server_process, "Shell server");
/*---------------------------------------------------------------------------*/
PROCESS(help_command_process, "help");
SHELL_COMMAND(help_command, "help", "help: shows this help",
&help_command_process);
SHELL_COMMAND(question_command, "?", "?: shows this help",
&help_command_process);
PROCESS(shell_killall_process, "killall");
SHELL_COMMAND(killall_command, "killall", "killall: stop all running commands",
&shell_killall_process);
PROCESS(shell_kill_process, "kill");
SHELL_COMMAND(kill_command, "kill", "kill <command>: stop a specific command",
&shell_kill_process);
PROCESS(shell_null_process, "null");
SHELL_COMMAND(null_command,
"null",
"null: discard input",
&shell_null_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_null_process, ev, data)
{
register struct ptentry *p;
char *sstr;
struct shell_input *input;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
input = data;
sstr = str;
if(input->len1 + input->len2 == 0) {
PROCESS_EXIT();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
command_kill(struct shell_command *c)
{
if(c != NULL) {
shell_output_str(&killall_command, "Stopping command ", c->command);
process_exit(c->process);
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_killall_process, ev, data)
{
struct shell_command *c;
PROCESS_BEGIN();
for(c = list_head(commands);
c != NULL;
c = c->next) {
if(c != &killall_command && process_is_running(c->process)) {
command_kill(c);
}
}
/* Loop over the parse table entries in t in order to find one that
matches the first character in str. */
for(p = t; p->c1 != 0; ++p) {
if(*str == p->c1 || *str == p->c2) {
/* Skip rest of the characters up to the first space. */
while(*str != ' ') {
++str;
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_kill_process, ev, data)
{
struct shell_command *c;
char *name;
PROCESS_BEGIN();
/* Skip all spaces.*/
while(*str == ' ') {
++str;
}
name = data;
if(name == NULL || strlen(name) == 0) {
shell_output_str(&kill_command,
"kill <command>: command name must be given", "");
}
/* Call parse table entry function and return. */
p->pfunc(str);
return;
for(c = list_head(commands);
c != NULL;
c = c->next) {
if(strcmp(name, c->command) == 0 &&
c != &kill_command &&
process_is_running(c->process)) {
command_kill(c);
PROCESS_EXIT();
}
}
/* Did not find matching entry in parse table. We just call the
default handler supplied by the caller and return. */
p->pfunc(str);
shell_output_str(&kill_command, "Command not found: ", name);
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/
static void
inttostr(CC_REGISTER_ARG char *str, unsigned int i)
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(help_command_process, ev, data)
{
str[0] = '0' + i / 100;
if(str[0] == '0') {
str[0] = ' ';
}
str[1] = '0' + (i / 10) % 10;
if(str[0] == ' ' && str[1] == '0') {
str[1] = ' ';
}
str[2] = '0' + i % 10;
str[3] = ' ';
str[4] = 0;
}
/*-----------------------------------------------------------------------------------*/
static void
processes(char *str)
{
struct process *p;
struct shell_command *c;
PROCESS_BEGIN();
shell_output("Processes:", "");
for(p = PROCESS_LIST(); p != NULL; p = p->next) {
shell_output((char *)p->name, "");
shell_output_str(&help_command, "Available commands:", "");
for(c = list_head(commands);
c != NULL;
c = c->next) {
shell_output_str(&help_command, c->description, "");
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
replace_braces(char *commandline)
{
char *ptr;
int level = 0;
for(ptr = commandline; *ptr != 0; ++ptr) {
if(*ptr == '{') {
if(level == 0) {
*ptr = ' ';
}
++level;
} else if(*ptr == '}') {
--level;
if(level == 0) {
*ptr = ' ';
}
}
}
}
/*-----------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static char *
nullterminate(char *str)
find_pipe(char *commandline)
{
char *nt;
/* Nullterminate string. Start with finding newline character. */
for(nt = str; *nt != '\r' &&
*nt != '\n'; ++nt);
/* Replace newline with a null char. */
*nt = 0;
/* Remove trailing spaces. */
while(nt > str && *(nt - 1) == ' ') {
*(nt - 1) = 0;
--nt;
}
char *ptr;
int level = 0;
/* Return pointer to null char. */
return nt;
}
/*-----------------------------------------------------------------------------------*/
#if SHELL_CONF_WITH_PROGRAM_HANDLER
static void
runfile(char *str)
{
nullterminate(str);
if(strlen(str) > 0) {
/* Call loader function. */
program_handler_load(str, NULL);
shell_output("Starting program ", str);
} else {
shell_output("Must supply a program name", "");
}
}
/*-----------------------------------------------------------------------------------*/
static void
execfile(char *str)
{
runfile(str);
shell_quit(NULL);
}
#endif /* SHELL_CONF_WITH_PROGRAM_HANDLER */
/*-----------------------------------------------------------------------------------*/
static void
killproc(char *str)
{
struct process *p;
nullterminate(str);
for(p = PROCESS_LIST(); p != NULL; p = p->next) {
if(strcasecmp(p->name, str) == 0) {
break;
for(ptr = commandline; *ptr != 0; ++ptr) {
if(*ptr == '{') {
++level;
} else if(*ptr == '}') {
--level;
} else if(*ptr == '|') {
if(level == 0) {
return ptr;
}
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
static struct shell_command *
start_command(char *commandline, struct shell_command *child)
{
char *next, *args;
int command_len;
struct shell_command *c;
if(p != NULL) {
shell_output("Killing process ", (char *)p->name);
process_post(p, PROCESS_EVENT_EXIT, NULL);
} else {
shell_output("Invalid process name", "");
}
}
/*-----------------------------------------------------------------------------------*/
static void
help(char *str)
{
shell_output("Available commands:", "");
#if SHELL_CONF_WITH_PROGRAM_HANDLER
shell_output("run - start program", "");
shell_output("exec - start program & exit shell", "");
#endif
shell_output("ps - show processes", "");
shell_output("kill - kill process", "");
shell_output("ls - display directory", "");
shell_output("quit - quit shell", "");
shell_output("? - show this help", "");
}
/*-----------------------------------------------------------------------------------*/
static void
directory(char *str)
{
if(cfs_opendir(&dir, ".") != 0) {
shell_output("Cannot open directory", "");
showingdir = 0;
} else {
shell_output("Disk directory:", "");
showingdir = 1;
totsize = 0;
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL);
while(*commandline == ' ') {
commandline++;
}
}
/*-----------------------------------------------------------------------------------*/
static void
none(char *str)
{
}
/*-----------------------------------------------------------------------------------*/
static struct ptentry configparsetab[] =
{
#if SHELL_CONF_WITH_PROGRAM_HANDLER
{'e', 'E', execfile},
{'r', 'R', runfile},
#endif
{'k', 'K', killproc},
{'p', 'P', processes},
{'l', 'L', directory},
{'q', 'Q', shell_quit},
{'h', '?', help},
next = find_pipe(commandline);
if(next != NULL) {
*next = 0;
child = start_command(next + 1, child);
}
/* Default action */
{0, 0, none}};
/*-----------------------------------------------------------------------------------*/
replace_braces(commandline);
args = strchr(commandline, ' ');
if(args != NULL) {
args++;
}
if(args == NULL) {
command_len = strlen(commandline);
args = &commandline[command_len];
} else {
command_len = args - commandline - 1;
}
/* Go through list of commands to find a match for the first word in
the command line. */
for(c = list_head(commands);
c != NULL &&
!(strncmp(c->command, commandline, command_len) == 0 &&
c->command[command_len] == 0);
c = c->next);
if(c == NULL) {
shell_output_str(NULL, commandline, ": command not found (try 'help')");
command_kill(child);
c = NULL;
} else if(process_is_running(c->process) || child == c) {
shell_output_str(NULL, commandline, ": command already running");
c->child = NULL;
c = NULL;
} else {
c->child = child;
/* printf("shell: start_command starting '%s'\n", c->process->name);*/
/* Start a new process for the command. */
process_start(c->process, args);
}
return c;
}
/*---------------------------------------------------------------------------*/
int
shell_start_command(char *commandline, int commandline_len,
struct shell_command *child,
struct process **started_process)
{
struct shell_command *c;
int background = 0;
if(commandline_len == 0) {
if(started_process != NULL) {
*started_process = NULL;
}
return SHELL_NOTHING;
}
if(commandline[commandline_len - 1] == '&') {
commandline[commandline_len - 1] = 0;
background = 1;
commandline_len--;
}
c = start_command(commandline, child);
/* Return a pointer to the started process, so that the caller can
wait for the process to complete. */
if(c != NULL && started_process != NULL) {
*started_process = c->process;
if(background) {
return SHELL_BACKGROUND;
} else {
return SHELL_FOREGROUND;
}
}
return SHELL_NOTHING;
}
/*---------------------------------------------------------------------------*/
static void
input_to_child_command(struct shell_command *c,
char *data1, int len1,
const char *data2, int len2)
{
struct shell_input input;
if(process_is_running(c->process)) {
input.data1 = data1;
input.len1 = len1;
input.data2 = data2;
input.len2 = len2;
process_post_synch(c->process, shell_event_input, &input);
}
}
/*---------------------------------------------------------------------------*/
void
shell_input(char *commandline, int commandline_len)
{
struct shell_input input;
/* printf("shell_input front_process '%s'\n", front_process->name);*/
if(commandline[0] == '~' &&
commandline[1] == 'K') {
/* process_start(&shell_killall_process, commandline);*/
if(front_process != &shell_process) {
process_exit(front_process);
}
} else {
if(process_is_running(front_process)) {
input.data1 = commandline;
input.len1 = commandline_len;
input.data2 = "";
input.len2 = 0;
process_post_synch(front_process, shell_event_input, &input);
}
}
}
/*---------------------------------------------------------------------------*/
void
shell_output_str(struct shell_command *c, char *text1, const char *text2)
{
if(c != NULL && c->child != NULL) {
input_to_child_command(c->child, text1, strlen(text1),
text2, strlen(text2));
} else {
shell_default_output(text1, strlen(text1),
text2, strlen(text2));
}
}
/*---------------------------------------------------------------------------*/
void
shell_output(struct shell_command *c,
void *data1, int len1,
const void *data2, int len2)
{
if(c != NULL && c->child != NULL) {
input_to_child_command(c->child, data1, len1, data2, len2);
} else {
shell_default_output(data1, len1, data2, len2);
}
}
/*---------------------------------------------------------------------------*/
void
shell_unregister_command(struct shell_command *c)
{
list_remove(commands, c);
}
/*---------------------------------------------------------------------------*/
void
shell_register_command(struct shell_command *c)
{
struct shell_command *i, *p;
p = NULL;
for(i = list_head(commands);
i != NULL &&
strcmp(i->command, c->command) < 0;
i = i->next) {
p = i;
}
if(p == NULL) {
list_push(commands, c);
} else if(i == NULL) {
list_add(commands, c);
} else {
list_insert(commands, p, c);
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_process, ev, data)
{
static struct process *started_process;
PROCESS_BEGIN();
/* Let the system start up before showing the prompt. */
PROCESS_PAUSE();
while(1) {
shell_prompt("Contiki> ");
PROCESS_WAIT_EVENT_UNTIL(ev == shell_event_input);
{
struct shell_input *input = data;
int ret;
ret = shell_start_command(input->data1, input->len1, NULL,
&started_process);
if(started_process != NULL &&
ret == SHELL_FOREGROUND &&
process_is_running(started_process)) {
front_process = started_process;
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXITED &&
data == started_process);
}
front_process = &shell_process;
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_server_process, ev, data)
{
struct process *p;
struct shell_command *c;
static struct etimer etimer;
PROCESS_BEGIN();
etimer_set(&etimer, CLOCK_SECOND * 10);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == PROCESS_EVENT_EXITED) {
p = data;
/* printf("process exited '%s' (front '%s')\n", p->name,
front_process->name);*/
for(c = list_head(commands);
c != NULL && c->process != p;
c = c->next);
while(c != NULL) {
if(c->child != NULL && c->child->process != NULL) {
/* printf("Killing '%s'\n", c->process->name);*/
input_to_child_command(c->child, "", 0, "", 0);
/* process_exit(c->process);*/
}
c = c->child;
}
} else if(ev == PROCESS_EVENT_TIMER) {
etimer_reset(&etimer);
shell_set_time(shell_time());
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
shell_init(void)
{
}
/*-----------------------------------------------------------------------------------*/
void
shell_start(void)
{
showingdir = 0;
shell_output("Contiki command shell", "");
shell_output("Type '?' and return for help", "");
shell_prompt("contiki> ");
}
/*-----------------------------------------------------------------------------------*/
void
shell_input(char *cmd)
{
if(showingdir != 0) {
showingdir = 0;
shell_output("Directory stopped", "");
cfs_closedir(&dir);
}
parse(cmd, configparsetab);
if(showingdir == 0) {
shell_prompt("contiki> ");
}
}
/*-----------------------------------------------------------------------------------*/
void
shell_eventhandler(process_event_t ev, process_data_t data)
{
static struct cfs_dirent dirent;
static char size[10];
list_init(commands);
shell_register_command(&help_command);
shell_register_command(&question_command);
shell_register_command(&killall_command);
shell_register_command(&kill_command);
shell_register_command(&null_command);
shell_event_input = process_alloc_event();
process_start(&shell_process, NULL);
process_start(&shell_server_process, NULL);
if(ev == PROCESS_EVENT_CONTINUE) {
if(showingdir != 0) {
if(cfs_readdir(&dir, &dirent) != 0) {
cfs_closedir(&dir);
showingdir = 0;
inttostr(size, totsize);
shell_output("Total number of blocks: ", size);
shell_prompt("contiki> ");
} else {
totsize += dirent.size;
inttostr(size, dirent.size);
shell_output(size, dirent.name);
process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL);
}
front_process = &shell_process;
}
/*---------------------------------------------------------------------------*/
unsigned long
shell_strtolong(const char *str, const char **retstr)
{
int i;
unsigned long num = 0;
const char *strptr = str;
if(str == NULL) {
return 0;
}
while(*strptr == ' ') {
++strptr;
}
for(i = 0; i < 10 && isdigit(strptr[i]); ++i) {
num = num * 10 + strptr[i] - '0';
}
if(retstr != NULL) {
if(i == 0) {
*retstr = str;
} else {
*retstr = strptr + i;
}
}
return num;
}
/*-----------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
unsigned long
shell_time(void)
{
return clock_time() / CLOCK_SECOND + time_offset;
}
/*---------------------------------------------------------------------------*/
void
shell_set_time(unsigned long seconds)
{
time_offset = seconds - clock_time() / CLOCK_SECOND;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,114 +1,113 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* $Id: shell.h,v 1.2 2008/02/04 23:42:18 adamdunkels Exp $
*/
/**
* \file
* Interface for the Contiki shell.
* \author Adam Dunkels <adam@dunkels.com>
*
* Some of the functions declared in this file must be implemented as
* a shell back-end in the architecture specific files of a Contiki
* port.
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
/*
* Copyright (c) 2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the Contiki desktop OS.
*
* $Id: shell.h,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#ifndef __SHELL_H__
#define __SHELL_H__
/**
* Initialize the shell.
*
* Called when the shell front-end process starts. This function may
* be used to start listening for signals.
*/
#include "sys/process.h"
struct shell_command {
struct shell_command *next;
char *command;
char *description;
struct process *process;
struct shell_command *child;
};
void shell_init(void);
/**
* Start the shell back-end.
*
* Called by the front-end when a new shell is started.
*/
void shell_start(void);
void shell_input(char *commandline, int commandline_len);
int shell_start_command(char *commandline, int commandline_len,
struct shell_command *child,
struct process **started_process);
void shell_output(struct shell_command *c,
void *data1, int size1,
const void *data2, int size2);
void shell_output_str(struct shell_command *c,
char *str1, const char *str2);
/**
* The shell event handler.
*
* This function will be called when an event is received.
*/
void shell_eventhandler(process_event_t ev, process_data_t data);
void shell_default_output(const char *text1, int len1,
const char *text2, int len2);
/**
* Process a shell command.
*
* This function will be called by the shell GUI / telnet server whan
* a command has been entered that should be processed by the shell
* back-end.
*
* \param command The command to be processed.
*/
void shell_input(char *command);
/**
* Quit the shell.
*
*/
void shell_quit(char *);
/**
* Print a string to the shell window.
*
* This function is implemented by the shell GUI / telnet server and
* can be called by the shell back-end to output a string in the
* shell window. The string is automatically appended with a linebreak.
*
* \param str1 The first half of the string to be output.
* \param str2 The second half of the string to be output.
*/
void shell_output(char *str1, char *str2);
/**
* Print a prompt to the shell window.
*
* This function can be used by the shell back-end to print out a
* prompt to the shell window.
*
* \param prompt The prompt to be printed.
*
*/
void shell_prompt(char *prompt);
void shell_register_command(struct shell_command *c);
void shell_unregister_command(struct shell_command *c);
unsigned long shell_strtolong(const char *str, const char **retstr);
unsigned long shell_time(void);
void shell_set_time(unsigned long seconds);
#define SHELL_COMMAND(name, command, description, process) \
static struct shell_command name = { NULL, command, \
description, process }
enum {
SHELL_FOREGROUND,
SHELL_BACKGROUND,
SHELL_NOTHING,
};
extern int shell_event_input;
struct shell_input {
char *data1;
const char *data2;
int len1, len2;
};
#include "shell-blink.h"
#include "shell-exec.h"
#include "shell-file.h"
#include "shell-netfile.h"
#include "shell-ps.h"
#include "shell-reboot.h"
#include "shell-rime.h"
#include "shell-rime-ping.h"
#include "shell-rime-sniff.h"
#include "shell-rsh.h"
#include "shell-sendtest.h"
#include "shell-sky.h"
#include "shell-text.h"
#include "shell-time.h"
#include "shell-vars.h"
#endif /* __SHELL_H__ */