Import of the contiki-2.x development code from the SICS internal CVS server

This commit is contained in:
adamdunkels 2006-06-17 22:41:10 +00:00
commit c9e808d638
671 changed files with 95332 additions and 0 deletions

128
Makefile.include Normal file
View file

@ -0,0 +1,128 @@
ifndef CONTIKI
$(error CONTIKI not defined! You must specify where CONTIKI resides!)
endif
OBJECTDIR = obj_$(TARGET)
ifeq ($(TARGET),)
-include Makefile.target
ifeq ($(TARGET),)
$(warning TARGET not defined, using netsim target)
TARGET=netsim
else
$(warning using saved target '$(TARGET)')
endif
endif
usage:
@echo "make MAKETARGETS... [TARGET=(TARGET)] [savetarget]"
savetarget:
-@rm -f Makefile.target
@echo >Makefile.target "TARGET = $(TARGET)"
ifeq (${wildcard $(OBJECTDIR)},)
DUMMY := ${shell mkdir $(OBJECTDIR)}
endif
SYSTEM = process.c procinit.c service.c autostart.c
THREADS = mt.c
LIBS = memb.c timer.c list.c etimer.c
CFS = cfs.c cfs-ram.c
CTK = ctk.c
UIP = uip.c uiplib.c resolv.c tcpip.c psock.c hc.c uip-split.c \
uip-fw.c uip-fw-service.c uipbuf.c uip_arp.c uiplib.c tcpdump.c \
uip-neighbor.c
NET = $(UIP) uaodv.c uaodv-rt.c
CTKVNC = $(CTK) ctk-vncserver.c libconio.c vnc-server.c vnc-out.c \
ctk-vncfont.c
CTKTERM = $(CTK) libconio.c ctk-term.c ctk-term-in.c ctk-term-out.c \
ctk-termtelnet.c
CONTIKIFILES = $(SYSTEM) $(THREADS) $(CFS) $(LIBS) $(NET) $(DHCP)
CONTIKI_SOURCEFILES += $(CONTIKIFILES)
# contiki.a: ${addprefix $(OBJECTDIR)/, $(CONTIKIFILES:.c=.o)}
# @$(AR) rcf $@ $^
# contikiapps.a: ${addprefix $(OBJECTDIR)/, $(APPSFILES:.c=.o)}
# @$(AR) rcf $@ $^
CONTIKIDIRS = ${addprefix $(CONTIKI)/core/,dev lib net sys \
cfs ctk lib/ctk loader . }
#APPDIRS += ${filter-out $(CONTIKI)/apps/CVS,${wildcard ${addprefix $(CONTIKI)/,apps/*}}}
PROJECT_OBJECTFILES = ${addprefix $(OBJECTDIR)/,$(PROJECT_SOURCEFILES:.c=.o)}
### Include application makefiles
ifdef APPS
APPDIRS += $(addprefix $(CONTIKI)/apps/, $(APPS))
APPINCLUDES = $(foreach APP, $(APPS), $(CONTIKI)/apps/$(APP)/Makefile.$(APP))
-include $(APPINCLUDES)
CONTIKI_SOURCEFILES += $(APP_SOURCES) $(DSC_SOURCES)
endif
### Include target makefile (TODO Unsafe?)
include $(CONTIKI)/platform/$(TARGET)/Makefile.$(TARGET)
### Automatic dependency generation
ifneq ($(MAKECMDGOALS),clean)
-include $(addprefix $(OBJECTDIR)/,$(CONTIKI_SOURCEFILES:.c=.d) \
$(PROJECT_SOURCEFILES:.c=.d))
endif
clean:
rm -f *~ *core core *.srec node-id.c \
*.lst *.map \
*.cprg *.bin *.data contiki*.a *.firmware core-labels.S *.ihex *.ini \
*.ce *.co
-rm -rf $(OBJECTDIR)
%.ce: %.c
$(CC) $(CFLAGS) -DAUTOSTART_ENABLE -c $< -o $@
$(STRIP) --strip-unneeded -g -x $@
$(OBJECTDIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
%.co: %.c
$(CC) $(CFLAGS) -DAUTOSTART_ENABLE -c $< -o $@
contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/, $(CONTIKI_SOURCEFILES:.c=.o)}
$(AR) rcf $@ $^
ifndef CCDEP
CCDEP = $(CC)
endif
ifndef CDEPFLAGS
CDEPFLAGS = $(CFLAGS)
endif
$(OBJECTDIR)/%.d: %.c
@set -e; rm -f $@; \
$(CCDEP) -MM $(CDEPFLAGS) $< > $@.$$$$; \
sed 's,\($*\)\.o[ :]*,$(OBJECTDIR)/\1.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
# The line below is needed so that GNU make does not remove the
# generated file.
.PRECIOUS: %.$(TARGET)
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) contiki-$(TARGET).a
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(filter-out %.a,$^) $(filter %.a,$^)
# The target below looks weird, but I had to add the @ to avoid complaints
# from GNU make about "*** No rule to make target `XXX'. Stop."
%: %.$(TARGET)
@

View file

@ -0,0 +1,2 @@
APP_SOURCES += about.c
DSC_SOURCES += about-dsc.c

74
apps/about/about-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: about-dsc.c,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon about_icon;
/*-----------------------------------------------------------------------------------*/
DSC(about_dsc,
"About Contiki",
"about.prg",
about_process,
&about_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char abouticon_bitmap[3*3*8] = {
0x00, 0x7f, 0x43, 0x4c, 0x58, 0x53, 0x60, 0x6f,
0x00, 0xff, 0x00, 0x7e, 0x00, 0xff, 0x00, 0xff,
0x00, 0xfe, 0xc2, 0x32, 0x1a, 0xca, 0x06, 0xf6,
0x40, 0x5f, 0x40, 0x5f, 0x40, 0x5f, 0x40, 0x4f,
0x00, 0xff, 0x00, 0xff, 0x00, 0xfc, 0x01, 0xf3,
0x02, 0xfa, 0x02, 0x82, 0x3e, 0xfe, 0xfe, 0xfe,
0x60, 0x67, 0x50, 0x59, 0x4c, 0x43, 0x7f, 0x00,
0x07, 0xe7, 0x0f, 0xef, 0x0f, 0x0f, 0xff, 0x00,
0x8e, 0x06, 0x06, 0x06, 0x8e, 0xfe, 0xfe, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char abouticon_textmap[9] = {
' ', ' ', 'c',
' ', '?', ' ',
'.', ' ', ' '
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon about_icon =
{CTK_ICON("About Contiki", abouticon_bitmap, abouticon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/about/about-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: about-dsc.h,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#ifndef __ABOUT_DSC_H__
#define __ABOUT_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(about_dsc);
#endif /* __ABOUT_DSC_H__ */

127
apps/about/about.c Normal file
View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2002, 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 environment
*
* $Id: about.c,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#include <string.h>
#include "contiki.h"
#include "ctk/ctk.h"
static struct ctk_window aboutdialog;
static struct ctk_label aboutlabel1 =
{CTK_LABEL(2, 0, 28, 1, "The Contiki Operating System")};
static struct ctk_label aboutlabel2 =
{CTK_LABEL(3, 2, 28, 1, "A modern, Internet-enabled")};
static struct ctk_label aboutlabel3 =
{CTK_LABEL(6, 3, 20, 1, "operating system and")};
static struct ctk_label aboutlabel4 =
{CTK_LABEL(6, 4, 20, 1, "desktop environment.")};
static char abouturl_petscii[] = "http://www.sics.se/~adam/contiki/";
static char abouturl_ascii[40];
static struct ctk_hyperlink abouturl =
{CTK_HYPERLINK(0, 6, 32, "http://www.sics.se/~adam/contiki/",
abouturl_ascii)};
static struct ctk_button aboutclose =
{CTK_BUTTON(12, 8, 5, "Close")};
PROCESS(about_process, "About Contiki");
/*-----------------------------------------------------------------------------------*/
static void
about_quit(void)
{
ctk_dialog_close();
process_exit(&about_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(about_process, ev, data)
{
unsigned char width;
PROCESS_BEGIN();
width = ctk_desktop_width(NULL);
strcpy(abouturl_ascii, abouturl_petscii);
petsciiconv_toascii(abouturl_ascii, sizeof(abouturl_ascii));
if(width > 34) {
ctk_dialog_new(&aboutdialog, 32, 9);
} else {
ctk_dialog_new(&aboutdialog, width - 2, 9);
}
CTK_WIDGET_ADD(&aboutdialog, &aboutlabel1);
CTK_WIDGET_ADD(&aboutdialog, &aboutlabel2);
CTK_WIDGET_ADD(&aboutdialog, &aboutlabel3);
CTK_WIDGET_ADD(&aboutdialog, &aboutlabel4);
if(width > 34) {
CTK_WIDGET_ADD(&aboutdialog, &abouturl);
CTK_WIDGET_SET_FLAG(&abouturl, CTK_WIDGET_FLAG_MONOSPACE);
} else {
CTK_WIDGET_SET_XPOS(&aboutlabel1, 0);
CTK_WIDGET_SET_XPOS(&aboutlabel2, 0);
CTK_WIDGET_SET_XPOS(&aboutlabel3, 0);
CTK_WIDGET_SET_XPOS(&aboutlabel4, 0);
CTK_WIDGET_SET_XPOS(&aboutclose, 0);
}
CTK_WIDGET_ADD(&aboutdialog, &aboutclose);
CTK_WIDGET_FOCUS(&aboutdialog, &aboutclose);
ctk_dialog_open(&aboutdialog);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == PROCESS_EVENT_EXIT) {
about_quit();
PROCESS_EXIT();
} else if(ev == ctk_signal_button_activate) {
if(data == (process_data_t)&aboutclose) {
about_quit();
PROCESS_EXIT();
}
} else if(ev == ctk_signal_hyperlink_activate) {
if((struct ctk_widget *)data == (struct ctk_widget *)&abouturl) {
about_quit();
PROCESS_EXIT();
}
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/

2
apps/calc/Makefile.calc Normal file
View file

@ -0,0 +1,2 @@
APP_SOURCES += calc.c
DSC_SOURCES += calc-dsc.c

74
apps/calc/calc-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: calc-dsc.c,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon calc_icon;
/*-----------------------------------------------------------------------------------*/
DSC(calc_dsc,
"Simple calculator",
"calc.prg",
calc_process,
&calc_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char calcicon_bitmap[3*3*8] = {
0x00, 0x7f, 0x43, 0x4c, 0x58, 0x53, 0x60, 0x6f,
0x00, 0xff, 0x00, 0x7e, 0x00, 0xff, 0x00, 0xff,
0x00, 0xfe, 0xc2, 0x32, 0x1a, 0xca, 0x06, 0xf6,
0x40, 0x5f, 0x40, 0x5f, 0x40, 0x5f, 0x40, 0x4f,
0x00, 0xff, 0x00, 0xff, 0x00, 0xfc, 0x01, 0xf3,
0x02, 0xfa, 0x02, 0x82, 0x3e, 0xfe, 0xfe, 0xfe,
0x60, 0x67, 0x50, 0x59, 0x4c, 0x43, 0x7f, 0x00,
0x07, 0xe7, 0x0f, 0xef, 0x0f, 0x0f, 0xff, 0x00,
0x8e, 0x06, 0x06, 0x06, 0x8e, 0xfe, 0xfe, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char calcicon_textmap[9] = {
'+', ' ', '-',
' ', '*', ' ',
'=', ' ', '/'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon calc_icon =
{CTK_ICON("Calculator", calcicon_bitmap, calcicon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/calc/calc-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: calc-dsc.h,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#ifndef __CALC_DSC_H__
#define __CALC_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(calc_dsc);
#endif /* __CALC_DSC_H__ */

293
apps/calc/calc.c Normal file
View file

@ -0,0 +1,293 @@
/*
* 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 an example program for the Contiki desktop OS
*
* $Id: calc.c,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#include "contiki.h"
#include "ctk/ctk.h"
static struct ctk_window window;
static char input[16];
static struct ctk_label inputlabel =
{CTK_LABEL(0, 0, 12, 1, input)};
static struct ctk_button button7 =
{CTK_BUTTON(0, 3, 1, "7")};
static struct ctk_button button8 =
{CTK_BUTTON(3, 3, 1, "8")};
static struct ctk_button button9 =
{CTK_BUTTON(6, 3, 1, "9")};
static struct ctk_button button4 =
{CTK_BUTTON(0, 4, 1, "4")};
static struct ctk_button button5 =
{CTK_BUTTON(3, 4, 1, "5")};
static struct ctk_button button6 =
{CTK_BUTTON(6, 4, 1, "6")};
static struct ctk_button button1 =
{CTK_BUTTON(0, 5, 1, "1")};
static struct ctk_button button2 =
{CTK_BUTTON(3, 5, 1, "2")};
static struct ctk_button button3 =
{CTK_BUTTON(6, 5, 1, "3")};
static struct ctk_button button0 =
{CTK_BUTTON(0, 6, 3, " 0 ")};
static struct ctk_button cbutton =
{CTK_BUTTON(0, 2, 1, "C")};
static struct ctk_button divbutton =
{CTK_BUTTON(9, 2, 1, "/")};
static struct ctk_button mulbutton =
{CTK_BUTTON(9, 3, 1, "*")};
static struct ctk_button subbutton =
{CTK_BUTTON(9, 4, 1, "-")};
static struct ctk_button addbutton =
{CTK_BUTTON(9, 5, 1, "+")};
static struct ctk_button calcbutton =
{CTK_BUTTON(9, 6, 1, "=")};
PROCESS(calc_process, "Calculator");
static unsigned long operand1, operand2;
static unsigned char op;
#define OP_ADD 1
#define OP_SUB 2
#define OP_MUL 3
#define OP_DIV 4
/*-----------------------------------------------------------------------------------*/
static void
calc_quit(void)
{
process_exit(&calc_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
static void
add_to_input(char c)
{
unsigned char i;
for(i = 0; i < 11; ++i) {
input[i] = input[i + 1];
}
input[11] = c;
}
/*-----------------------------------------------------------------------------------*/
static void
clear_input(void)
{
unsigned char i;
for(i = 0; i < sizeof(input); ++i) {
input[i] = ' ';
}
}
/*-----------------------------------------------------------------------------------*/
static void
input_to_operand1(void)
{
unsigned int m;
unsigned char i;
operand1 = 0;
for(m = 1, i = 11;
i > 7; --i, m *= 10) {
if(input[i] >= '0' &&
input[i] <= '9') {
operand1 += (input[i] - '0') * m;
}
}
clear_input();
}
/*-----------------------------------------------------------------------------------*/
static void
operand2_to_input(void)
{
unsigned char i;
input[7] = (operand2/10000) % 10 + '0';
input[8] = (operand2/1000) % 10 + '0';
input[9] = (operand2/100) % 10 + '0';
input[10] = (operand2/10) % 10 + '0';
input[11] = operand2 % 10 + '0';
for(i = 0; i < 4; ++i) {
if(input[7 + i] == '0') {
input[7 + i] = ' ';
} else {
break;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
calculate(void)
{
operand2 = operand1;
input_to_operand1();
switch(op) {
case OP_ADD:
operand2 = operand2 + operand1;
break;
case OP_SUB:
operand2 = operand2 - operand1;
break;
case OP_MUL:
operand2 = operand2 * operand1;
break;
case OP_DIV:
operand2 = operand2 / operand1;
break;
}
operand2_to_input();
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(calc_process, ev, data)
{
PROCESS_BEGIN();
ctk_window_new(&window, 12, 7, "Calc");
CTK_WIDGET_ADD(&window, &inputlabel);
CTK_WIDGET_SET_FLAG(&inputlabel, CTK_WIDGET_FLAG_MONOSPACE);
CTK_WIDGET_ADD(&window, &cbutton);
CTK_WIDGET_ADD(&window, &divbutton);
CTK_WIDGET_ADD(&window, &button7);
CTK_WIDGET_ADD(&window, &button8);
CTK_WIDGET_ADD(&window, &button9);
CTK_WIDGET_ADD(&window, &mulbutton);
CTK_WIDGET_ADD(&window, &button4);
CTK_WIDGET_ADD(&window, &button5);
CTK_WIDGET_ADD(&window, &button6);
CTK_WIDGET_ADD(&window, &subbutton);
CTK_WIDGET_ADD(&window, &button1);
CTK_WIDGET_ADD(&window, &button2);
CTK_WIDGET_ADD(&window, &button3);
CTK_WIDGET_ADD(&window, &addbutton);
CTK_WIDGET_ADD(&window, &button0);
CTK_WIDGET_ADD(&window, &calcbutton);
clear_input();
ctk_window_open(&window);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == ctk_signal_keypress) {
if((char)data >= '0' &&
(char)data <= '9') {
add_to_input((char)data);
} else if((char)data == ' ') {
clear_input();
} else if((char)data == '+') {
input_to_operand1();
op = OP_ADD;
} else if((char)data == '-') {
input_to_operand1();
op = OP_SUB;
} else if((char)data == '*') {
input_to_operand1();
op = OP_MUL;
} else if((char)data == '/') {
input_to_operand1();
op = OP_DIV;
} else if((char)data == '=' ||
(char)data == CH_ENTER) {
calculate();
}
CTK_WIDGET_REDRAW(&inputlabel);
} else if(ev == ctk_signal_button_activate) {
if(data == (process_data_t)&button0) {
add_to_input('0');
} else if(data == (process_data_t)&button1) {
add_to_input('1');
} else if(data == (process_data_t)&button2) {
add_to_input('2');
} else if(data == (process_data_t)&button3) {
add_to_input('3');
} else if(data == (process_data_t)&button4) {
add_to_input('4');
} else if(data == (process_data_t)&button5) {
add_to_input('5');
} else if(data == (process_data_t)&button6) {
add_to_input('6');
} else if(data == (process_data_t)&button7) {
add_to_input('7');
} else if(data == (process_data_t)&button8) {
add_to_input('8');
} else if(data == (process_data_t)&button9) {
add_to_input('9');
} else if(data == (process_data_t)&cbutton) {
clear_input();
} else if(data == (process_data_t)&calcbutton) {
calculate();
} else if(data == (process_data_t)&addbutton) {
input_to_operand1();
op = OP_ADD;
} else if(data == (process_data_t)&subbutton) {
input_to_operand1();
op = OP_SUB;
} else if(data == (process_data_t)&mulbutton) {
input_to_operand1();
op = OP_MUL;
} else if(data == (process_data_t)&divbutton) {
input_to_operand1();
op = OP_DIV;
}
CTK_WIDGET_REDRAW(&inputlabel);
} else if(ev == ctk_signal_window_close &&
data == (process_data_t)&window) {
calc_quit();
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/

2
apps/cmdd/Makefile.cmdd Normal file
View file

@ -0,0 +1,2 @@
APP_SOURCES += cmdd.c
DSC_SOURCES +=

168
apps/cmdd/cmdd.c Normal file
View file

@ -0,0 +1,168 @@
#include "contiki.h"
#include "psock.h"
#include "memb.h"
#include <string.h>
struct cmdd_state {
struct psock s;
char inputbuf[8];
struct timer timer;
int i;
char command;
};
#define COMMAND_NONE 0
#define COMMAND_PS 1
MEMB(conns, struct cmdd_state, 1);
PROCESS(cmdd_process, "Command server");
static struct uip_udp_conn *udpconn;
static char send_udp = 0;
static const char *prompt = "contiki> ";
/*---------------------------------------------------------------------------*/
static char * CC_FASTCALL
n(u16_t num, char *ptr)
{
u16_t d;
u8_t a, f;
if(num == 0) {
*ptr = '0';
return ptr + 1;
} else {
f = 0;
for(d = 10000; d >= 1; d /= 10) {
a = (num / d) % 10;
if(f == 1 || a > 0) {
*ptr = a + '0';
++ptr;
f = 1;
}
}
}
return ptr;
}
/*---------------------------------------------------------------------------*/
static unsigned short
ps_generate(void *state)
{
struct ek_proc *p = (struct ek_proc *)state;
char *ptr = (char *)uip_appdata;
ptr = n(EK_PROC_ID(p), ptr);
*ptr++ = ' ';
strncpy(ptr, p->name, 40);
ptr += strlen(p->name);
*ptr++ = '\n';
return ptr - (char *)uip_appdata;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_connection(struct cmdd_state *s))
{
PSOCK_BEGIN(&s->s);
while(1) {
PSOCK_SEND(&s->s, prompt, strlen(prompt));
PSOCK_WAIT_UNTIL(&s->s, PSOCK_NEWDATA(&s->s) ||
s->command != COMMAND_NONE);
if(PSOCK_NEWDATA(&s->s)) {
PSOCK_READTO(&s->s, '\n');
if(strncmp(s->inputbuf, "quit", 4) == 0) {
PSOCK_CLOSE_EXIT(&s->s);
memb_free(&conns, s);
tcp_markconn(uip_conn, NULL);
} else if(strncmp(s->inputbuf, "ps", 2) == 0) {
PSOCK_GENERATOR_SEND(&s->s, ps_generate, ek_procs);
for(s->i = 0; s->i < 40; s->i++) {
if(ek_process(s->i) != NULL) {
PSOCK_GENERATOR_SEND(&s->s, ps_generate, ek_process(s->i));
}
}
} else if(strncmp(s->inputbuf, "send", 4) == 0) {
send_udp = 1;
PSOCK_WAIT_UNTIL(&s->s, send_udp == 0);
} else {
PSOCK_SEND(&s->s, "?\n", 2);
}
} else {
switch(s->command) {
}
}
}
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static void
appcall(void *state)
{
struct cmdd_state *s = (struct cmdd_state *)state;
if(uip_udpconnection()) {
if(send_udp) {
uip_udp_send(8);
send_udp = 0;
}
} else {
if(uip_closed() || uip_timedout() || uip_aborted()) {
if(state != NULL) {
memb_free(&conns, state);
}
} else if(uip_connected()) {
s = (struct cmdd_state *)memb_alloc(&conns);
if(s == NULL) {
uip_abort();
} else {
tcp_markconn(uip_conn, s);
PSOCK_INIT(&s->s, s->inputbuf, sizeof(s->inputbuf) - 1);
timer_set(&s->timer, CLOCK_SECOND * 60);
handle_connection(s);
}
} else if(s != NULL) {
if(uip_poll()) {
if(timer_expired(&s->timer)) {
memb_free(&conns, state);
uip_abort();
return;
}
}
timer_reset(&s->timer);
handle_connection(s);
} else {
uip_abort();
}
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(cmdd_process, ev, data)
{
u16_t ipaddr[2];
PROCESS_BEGIN();
tcp_listen(HTONS(6581));
memb_init(&conns);
uip_ipaddr(ipaddr, 255,255,255,255);
udpconn = udp_new(ipaddr, HTONS(6712), NULL);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
appcall(data);
} else if(ev == PROCESS_EVENT_EXIT) {
process_exit(&cmdd_process);
LOADER_UNLOAD();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

10
apps/cmdd/cmdd.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef __CMDD_H__
#define __CMDD_H__
#include "contiki.h"
/*EK_PROCESS_INIT(cmdd_init, arg);*/
PROCESS_NAME(cmdd_process);
#endif /* __CMDD_H__ */

2
apps/dhcp/Makefile.dhcp Normal file
View file

@ -0,0 +1,2 @@
APP_SOURCES += dhcp.c dhcpc.c
DSC_SOURCES += dhcp-dsc.c

74
apps/dhcp/dhcp-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: dhcp-dsc.c,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon dhcp_icon;
/*-----------------------------------------------------------------------------------*/
DSC(dhcp_dsc,
"Obtain IP address automatically",
"dhcp.prg",
dhcp_process,
&dhcp_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char tcpipconficon_bitmap[3*3*8] = {
0x00, 0x79, 0x43, 0x73, 0x47, 0x77, 0x47, 0x6f,
0x00, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xfb,
0x00, 0x16, 0x02, 0x00, 0x02, 0x00, 0x00, 0xc2,
0x48, 0x4c, 0x5f, 0x5f, 0x1f, 0x3f, 0x3f, 0x03,
0x79, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xfe, 0xfc,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x77, 0x47, 0x70, 0x43, 0x79, 0x41, 0x7c, 0x00,
0xfc, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xf7, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x84, 0xf0, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char tcpipconficon_textmap[9] = {
'T', 'C', 'P',
'/', 'I', 'P',
'C', 'f', 'g'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon dhcp_icon =
{CTK_ICON("DHCP client", tcpipconficon_bitmap, tcpipconficon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/dhcp/dhcp-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: dhcp-dsc.h,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#ifndef __DHCP_DSC_H__
#define __DHCP_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(dhcp_dsc);
#endif /* __DHCP_DSC_H__ */

153
apps/dhcp/dhcp.c Normal file
View file

@ -0,0 +1,153 @@
#include "contiki-net.h"
#include "ctk/ctk.h"
#include "net/dhcpc.h"
PROCESS(dhcp_process, "DHCP");
static struct ctk_window window;
static struct ctk_button getbutton =
{CTK_BUTTON(0, 0, 16, "Request address")};
static struct ctk_label statuslabel =
{CTK_LABEL(0, 1, 16, 1, "")};
static struct ctk_label ipaddrlabel =
{CTK_LABEL(0, 3, 10, 1, "IP address")};
static char ipaddr[17];
static struct ctk_textentry ipaddrentry =
{CTK_LABEL(11, 3, 16, 1, ipaddr)};
static struct ctk_label netmasklabel =
{CTK_LABEL(0, 4, 10, 1, "Netmask")};
static char netmask[17];
static struct ctk_textentry netmaskentry =
{CTK_LABEL(11, 4, 16, 1, netmask)};
static struct ctk_label gatewaylabel =
{CTK_LABEL(0, 5, 10, 1, "Gateway")};
static char gateway[17];
static struct ctk_textentry gatewayentry =
{CTK_LABEL(11, 5, 16, 1, gateway)};
static struct ctk_label dnsserverlabel =
{CTK_LABEL(0, 6, 10, 1, "DNS server")};
static char dnsserver[17];
static struct ctk_textentry dnsserverentry =
{CTK_LABEL(11, 6, 16, 1, dnsserver)};
enum {
SHOWCONFIG
};
/*---------------------------------------------------------------------------*/
static void
set_statustext(char *text)
{
ctk_label_set_text(&statuslabel, text);
CTK_WIDGET_REDRAW(&statuslabel);
}
/*---------------------------------------------------------------------------*/
static char *
makebyte(u8_t byte, char *str)
{
if(byte >= 100) {
*str++ = (byte / 100 ) % 10 + '0';
}
if(byte >= 10) {
*str++ = (byte / 10) % 10 + '0';
}
*str++ = (byte % 10) + '0';
return str;
}
/*---------------------------------------------------------------------------*/
static void
makeaddr(u16_t *addr, char *str)
{
str = makebyte(HTONS(addr[0]) >> 8, str);
*str++ = '.';
str = makebyte(HTONS(addr[0]) & 0xff, str);
*str++ = '.';
str = makebyte(HTONS(addr[1]) >> 8, str);
*str++ = '.';
str = makebyte(HTONS(addr[1]) & 0xff, str);
*str++ = 0;
}
/*---------------------------------------------------------------------------*/
static void
makestrings(void)
{
u16_t addr[2], *addrptr;
uip_gethostaddr(addr);
makeaddr(addr, ipaddr);
uip_getnetmask(addr);
makeaddr(addr, netmask);
uip_getdraddr(addr);
makeaddr(addr, gateway);
addrptr = resolv_getserver();
if(addrptr != NULL) {
makeaddr(addrptr, dnsserver);
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(dhcp_process, ev, data)
{
PROCESS_BEGIN();
ctk_window_new(&window, 28, 7, "DHCP");
CTK_WIDGET_ADD(&window, &getbutton);
CTK_WIDGET_ADD(&window, &statuslabel);
CTK_WIDGET_ADD(&window, &ipaddrlabel);
CTK_WIDGET_ADD(&window, &ipaddrentry);
CTK_WIDGET_ADD(&window, &netmasklabel);
CTK_WIDGET_ADD(&window, &netmaskentry);
CTK_WIDGET_ADD(&window, &gatewaylabel);
CTK_WIDGET_ADD(&window, &gatewayentry);
CTK_WIDGET_ADD(&window, &dnsserverlabel);
CTK_WIDGET_ADD(&window, &dnsserverentry);
CTK_WIDGET_FOCUS(&window, &getbutton);
ctk_window_open(&window);
dhcpc_init(uip_ethaddr.addr, sizeof(uip_ethaddr.addr));
while(1) {
PROCESS_WAIT_EVENT();
if(ev == ctk_signal_widget_activate) {
if(data == (process_data_t)&getbutton) {
dhcpc_request();
set_statustext("Requesting...");
}
} else if(ev == tcpip_event) {
dhcpc_appcall(ev, data);
} else if(ev == PROCESS_EVENT_EXIT ||
ev == ctk_signal_window_close) {
ctk_window_close(&window);
process_exit(&dhcp_process);
LOADER_UNLOAD();
} else if(ev == SHOWCONFIG) {
makestrings();
ctk_window_redraw(&window);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
dhcpc_configured(const struct dhcpc_state *s)
{
uip_sethostaddr(s->ipaddr);
uip_setnetmask(s->netmask);
uip_setdraddr(s->default_router);
resolv_conf(s->dnsaddr);
set_statustext("Configured.");
process_post(PROCESS_CURRENT(), SHOWCONFIG, NULL);
}
/*---------------------------------------------------------------------------*/

0
apps/dhcp/dhcp.h Normal file
View file

View file

@ -0,0 +1,2 @@
APP_SOURCES += directory.c
DSC_SOURCES += directory-dsc.c

View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: directory-dsc.c,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon directory_icon;
/*-----------------------------------------------------------------------------------*/
DSC(directory_dsc,
"Directory reader",
"directory.prg",
directory_process,
&directory_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char directoryicon_bitmap[3*3*8] = {
0x00, 0x7f, 0x43, 0x4c, 0x58, 0x53, 0x60, 0x6f,
0x00, 0xff, 0x00, 0x7e, 0x00, 0xff, 0x00, 0xff,
0x00, 0xfe, 0xc2, 0x32, 0x1a, 0xca, 0x06, 0xf6,
0x40, 0x5f, 0x40, 0x5f, 0x40, 0x5f, 0x40, 0x4f,
0x00, 0xff, 0x00, 0xff, 0x00, 0xfc, 0x01, 0xf3,
0x02, 0xfa, 0x02, 0x82, 0x3e, 0xfe, 0xfe, 0xfe,
0x60, 0x67, 0x50, 0x59, 0x4c, 0x43, 0x7f, 0x00,
0x07, 0xe7, 0x0f, 0xef, 0x0f, 0x0f, 0xff, 0x00,
0x8e, 0x06, 0x06, 0x06, 0x8e, 0xfe, 0xfe, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char directoryicon_textmap[9] = {
'+', '-', '+',
'|', 'o', '|',
'+', '-', '+'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon directory_icon =
{CTK_ICON("Directory", directoryicon_bitmap, directoryicon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: directory-dsc.h,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#ifndef __DIRECTORY_DSC_H__
#define __DIRECTORY_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(directory_dsc);
#endif /* __DIRECTORY_DSC_H__ */

308
apps/directory/directory.c Normal file
View file

@ -0,0 +1,308 @@
/*
* 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 environment
*
* $Id: directory.c,v 1.1 2006/06/17 22:41:10 adamdunkels Exp $
*
*/
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "cfs/cfs.h"
#include "ctk/ctk.h"
#include "program-handler.h"
#define FILENAMELEN 24
#define MAX_NUMFILES 40
#define WIDTH 36
#define HEIGHT 22
static char (filenames[FILENAMELEN + 1])[MAX_NUMFILES];
static struct dsc *dscs[MAX_NUMFILES];
static unsigned char numfiles, morestart, filenameptr;
static struct ctk_window window;
static struct ctk_label description =
{CTK_LABEL(0, HEIGHT - 1, WIDTH, 1, "")};
static char autoexit = 1;
static struct ctk_button autoexitbutton =
{CTK_BUTTON(WIDTH/2 - 9, 20, 9, "Auto-exit")};
static char autoexiton[] = "is On ";
static char autoexitoff[] = "is Off";
static struct ctk_label autoexitlabel =
{CTK_LABEL(WIDTH/2 - 9 + 12, 20, 6, 1, autoexiton)};
static struct ctk_button morebutton =
{CTK_BUTTON(0, 20, 4, "More")};
static struct ctk_button backbutton =
{CTK_BUTTON(0, 20, 4, "Back")};
static struct ctk_button reloadbutton =
{CTK_BUTTON(30, 20, 6, "Reload")};
PROCESS(directory_process, "Directory browser");
static unsigned char width, height;
#define LOADING_DIR 1
#define LOADING_DSC 2
static char loading = 0;
static struct cfs_dir dir;
/*-----------------------------------------------------------------------------------*/
static void
show_statustext(char *text)
{
ctk_label_set_text(&description, text);
CTK_WIDGET_REDRAW(&description);
}
/*-----------------------------------------------------------------------------------*/
static void
startloading(void)
{
if(cfs_opendir(&dir, "/") != 0) {
show_statustext("Cannot open directory");
loading = 0;
} else {
loading = 1;
process_post(&directory_process, PROCESS_EVENT_CONTINUE, NULL);
numfiles = 0;
}
}
/*-----------------------------------------------------------------------------------*/
static void
makewindow(unsigned char i)
{
unsigned char x, y;
ctk_window_clear(&window);
CTK_WIDGET_SET_YPOS(&description, height - 3);
CTK_WIDGET_SET_WIDTH(&description, width);
CTK_WIDGET_ADD(&window, &description);
morestart = i;
x = 0; y = 1;
for(; dscs[i] != NULL; ++i) {
if(x + strlen(dscs[i]->icon->title) >= width) {
y += 5;
x = 0;
if(y >= height - 2 - 4) {
morestart = i;
break;
}
}
CTK_WIDGET_SET_XPOS(dscs[i]->icon, x);
CTK_WIDGET_SET_YPOS(dscs[i]->icon, y);
CTK_WIDGET_ADD(&window, dscs[i]->icon);
x += strlen(dscs[i]->icon->title) + 2;
}
CTK_WIDGET_SET_YPOS(&autoexitbutton, height - 2);
CTK_WIDGET_ADD(&window, &autoexitbutton);
CTK_WIDGET_SET_YPOS(&autoexitlabel, height - 2);
CTK_WIDGET_ADD(&window, &autoexitlabel);
CTK_WIDGET_FOCUS(&window, &autoexitbutton);
if(i != morestart) {
CTK_WIDGET_SET_YPOS(&backbutton, height - 1);
CTK_WIDGET_ADD(&window, &backbutton);
} else {
CTK_WIDGET_SET_YPOS(&morebutton, height - 1);
CTK_WIDGET_ADD(&window, &morebutton);
}
CTK_WIDGET_SET_XPOS(&reloadbutton, width - 8);
CTK_WIDGET_SET_YPOS(&reloadbutton, height - 1);
CTK_WIDGET_ADD(&window, &reloadbutton);
}
/*-----------------------------------------------------------------------------------*/
static void
quit(void)
{
unsigned char i;
cfs_closedir(&dir);
ctk_window_close(&window);
for(i = 0; dscs[i] != NULL; ++i) {
LOADER_UNLOAD_DSC(dscs[i]);
}
process_exit(&directory_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
static void
read_dirent(void)
{
static struct cfs_dirent dirent;
static char message[40];
if(loading == LOADING_DIR) {
if(cfs_readdir(&dir, &dirent)) {
cfs_closedir(&dir);
loading = LOADING_DSC;
filenameptr = 0;
} else if(strcasecmp(&dirent.name[strlen(dirent.name) - 4], ".dsc") == 0) {
strncpy(filenames[numfiles], dirent.name, FILENAMELEN);
++numfiles;
if(numfiles == MAX_NUMFILES) {
cfs_closedir(&dir);
loading = LOADING_DSC;
filenameptr = 0;
return;
}
strcpy(message, "Found \"");
strcpy(message + 7, dirent.name);
strcpy(message + 7 + strlen(dirent.name), "\"...");
show_statustext(message);
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
load_dirent(void)
{
static char message[40];
char *name;
if(loading == LOADING_DSC) {
name = filenames[filenameptr];
dscs[filenameptr] = LOADER_LOAD_DSC(name);
if(dscs[filenameptr] == NULL || filenameptr + 1 >= numfiles) {
loading = 0;
makewindow(0);
show_statustext("Directory loaded");
ctk_window_redraw(&window);
return;
}
++filenameptr;
strcpy(message, "Loading \"");
strcpy(message + 9, name);
strcpy(message + 9 + strlen(name), "\"...");
show_statustext(message);
}
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(directory_process, ev, data)
{
unsigned char i;
PROCESS_BEGIN();
width = ctk_draw_width() - 2;
height = ctk_draw_height() - 3;
ctk_window_new(&window, width, height, "Directory");
/* loaddirectory();*/
makewindow(0);
show_statustext("Loading directory...");
startloading();
ctk_window_open(&window);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == PROCESS_EVENT_CONTINUE) {
read_dirent();
load_dirent();
if(loading != 0) {
process_post(&directory_process, PROCESS_EVENT_CONTINUE, NULL);
}
} else if(ev == ctk_signal_widget_activate) {
if(data == (process_data_t)&reloadbutton) {
for(i = 0; dscs[i] != NULL; ++i) {
LOADER_UNLOAD_DSC(dscs[i]);
dscs[i] = NULL;
}
/* loaddirectory();*/
startloading();
makewindow(0);
ctk_window_open(&window);
} else if(data == (process_data_t)&morebutton) {
makewindow(morestart);
ctk_window_open(&window);
} else if(data == (process_data_t)&backbutton) {
makewindow(0);
ctk_window_open(&window);
} else if(data == (process_data_t)&autoexitbutton) {
autoexit = 1 - autoexit;
if(autoexit == 1) {
ctk_label_set_text(&autoexitlabel, autoexiton);
} else {
ctk_label_set_text(&autoexitlabel, autoexitoff);
}
CTK_WIDGET_REDRAW(&autoexitlabel);
} else {
for(i = 0; dscs[i] != NULL; ++i) {
if(data == (process_data_t)(dscs[i]->icon)) {
/* program_handler_load(dscs[i]->prgname, NULL);*/
if(autoexit) {
ctk_window_close(&window);
quit();
}
break;
}
}
}
} else if(ev == ctk_signal_widget_select) {
if(data == (process_data_t)&reloadbutton) {
show_statustext("Reload directory");
} else if(data == (process_data_t)&morebutton) {
show_statustext("Show more files");
} else if(data == (process_data_t)&backbutton) {
show_statustext("Show first files");
} else if(data == (process_data_t)&autoexitbutton) {
show_statustext("Exit when loading program");
} else {
for(i = 0; dscs[i] != NULL; ++i) {
if(data == (process_data_t)(dscs[i]->icon)) {
show_statustext(dscs[i]->description);
break;
}
}
}
} else if(ev == ctk_signal_window_close &&
data == (process_data_t)&window) {
quit();
} else if(ev == PROCESS_EVENT_EXIT) {
ctk_window_close(&window);
quit();
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,2 @@
APP_SOURCES += editor.c memb.c ctk-filedialog.c
DSC_SOURCES += editor-dsc.c

74
apps/editor/editor-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2004, 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 environment
*
* $Id: editor-dsc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon editor_icon;
/*-----------------------------------------------------------------------------------*/
DSC(editor_dsc,
"A simple text editor",
"editor.prg",
editor_process,
&editor_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char editoricon_bitmap[3*3*8] = {
0x00, 0x7e, 0x40, 0x73, 0x46, 0x4c, 0x18, 0x13,
0x00, 0x00, 0xff, 0x81, 0x34, 0xc9, 0x00, 0xb6,
0x00, 0x7e, 0x02, 0xce, 0x72, 0x32, 0x18, 0x48,
0x30, 0x27, 0x24, 0x20, 0x37, 0x24, 0x20, 0x33,
0x00, 0x7b, 0x42, 0x00, 0x7b, 0x42, 0x00, 0x3b,
0x0c, 0x24, 0x24, 0x04, 0xa4, 0x24, 0x04, 0x4c,
0x12, 0x19, 0x4c, 0x46, 0x63, 0x40, 0x7c, 0x00,
0x22, 0x91, 0x00, 0xc4, 0x81, 0xff, 0x00, 0x00,
0x08, 0x18, 0x32, 0x62, 0xc6, 0x02, 0x3e, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char editoricon_textmap[9] = {
't', 'x', 't',
'e', 'd', 'i',
't', 'o', 'r'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon editor_icon =
{CTK_ICON("Editor", editoricon_bitmap, editoricon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/editor/editor-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2004, 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 environment
*
* $Id: editor-dsc.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#ifndef __EDITOR_DSC_H__
#define __EDITOR_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(editor_dsc);
#endif /* __EDITOR_DSC_H__ */

338
apps/editor/editor.c Normal file
View file

@ -0,0 +1,338 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: editor.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
#define EDITOR_CONF_WIDTH 32
#define EDITOR_CONF_HEIGHT 16
#define EDITOR_CONF_MAX_FILENAME_LEN 16
#include "contiki.h"
#include "contiki-lib.h"
#include "ctk/ctk.h"
#include "cfs/cfs.h"
#include "lib/ctk-filedialog.h"
#define ISO_nl 0x0a
PROCESS(editor_process, "Editor");
static struct ctk_window window;
#define LINE_LEN 60
#define NUM_LINES EDITOR_CONF_HEIGHT
struct line {
struct line *next, *prev;
char text[LINE_LEN];
};
MEMB(linesmem, struct line, NUM_LINES);
static struct line *lines;
static struct {
unsigned char x, y;
struct ctk_label labels[NUM_LINES];
} editor_state;
static struct ctk_button openbutton =
{CTK_BUTTON(0, 0, 4, "Open")};
static char statustext[EDITOR_CONF_WIDTH + 1];
static struct ctk_label statuslabel =
{CTK_LABEL(0, EDITOR_CONF_HEIGHT + 2, EDITOR_CONF_WIDTH, 1, statustext)};
static struct ctk_menu menu;
static unsigned char menuitem_new, menuitem_open, menuitem_save;
static char filename[EDITOR_CONF_MAX_FILENAME_LEN];
static struct ctk_filedialog_state filedialog;
enum {
OPEN_EVENT
};
/*---------------------------------------------------------------------------*/
static void
show_statustext(char *text1, char *text2)
{
int len;
len = strlen(text1);
if(len < sizeof(statustext)) {
strncpy(statustext, text1, sizeof(statustext));
strncpy(statustext + len, text2, sizeof(statustext) - len);
CTK_WIDGET_REDRAW(&statuslabel);
}
}
/*---------------------------------------------------------------------------*/
static void
editor_start(void)
{
unsigned char i;
register struct ctk_label *label;
struct line *l, *m;
m = NULL;
for(i = 0; i < NUM_LINES; ++i) {
label = &editor_state.labels[i];
l = (struct line *)memb_alloc(&linesmem);
if(l != NULL) {
l->next = NULL;
l->prev = m;
if(m == NULL) {
/* First line */
lines = l;
} else {
m->next = l;
}
CTK_LABEL_NEW(label, 0, i + 1, EDITOR_CONF_WIDTH, 1, l->text);
CTK_WIDGET_SET_FLAG(label, CTK_WIDGET_FLAG_MONOSPACE);
CTK_WIDGET_ADD(&window, label);
}
m = l;
}
}
/*---------------------------------------------------------------------------*/
static void
editor_eventhandler(process_event_t ev, process_data_t data)
{
char *textptr, *textptr2;
unsigned char len;
if(ev == ctk_signal_keypress) {
/* CTK_WIDGET_FOCUS(t->label.window, &t->label);*/
textptr = &(editor_state.labels[editor_state.y].text[editor_state.x]);
*textptr &= 0x7f;
CTK_WIDGET_REDRAW(&(editor_state.labels[editor_state.y]));
switch((ctk_arch_key_t)data) {
case CH_CURS_DOWN:
++editor_state.y;
if(editor_state.y >= EDITOR_CONF_HEIGHT) {
editor_state.y = EDITOR_CONF_HEIGHT - 1;
}
break;
case CH_CURS_UP:
if(editor_state.y > 0) {
--editor_state.y;
}
break;
case CH_CURS_RIGHT:
if(editor_state.x < strlen(editor_state.labels[editor_state.y].text)) {
++editor_state.x;
}
break;
case CH_CURS_LEFT:
if(editor_state.x > 0) {
--editor_state.x;
} else {
if(editor_state.y > 0) {
--editor_state.y;
editor_state.x = strlen(editor_state.labels[editor_state.y].text);
}
}
break;
case CH_ENTER:
editor_state.x = 0;
++editor_state.y;
if(editor_state.y >= EDITOR_CONF_HEIGHT) {
editor_state.y = EDITOR_CONF_HEIGHT - 1;
}
break;
case CH_DEL:
/* len = t->label.w - t->xpos;
if(t->xpos > 0 && len > 0) {
strncpy(textptr - 1, textptr,
len);
*(textptr + len - 1) = 0;
--t->xpos;
}*/
break;
default:
len = EDITOR_CONF_WIDTH - editor_state.x;
if(len > 0) {
textptr2 = textptr + len - 1;
while(textptr2 + 1 > textptr) {
*(textptr2 + 1) = *textptr2;
--textptr2;
}
*textptr = (char)data;
++editor_state.x;
if(editor_state.x == EDITOR_CONF_WIDTH) {
editor_state.x = 0;
if(editor_state.y < EDITOR_CONF_HEIGHT - 1) {
++editor_state.y;
}
}
}
break;
}
textptr = &(editor_state.labels[editor_state.y].text[editor_state.x]);
*textptr |= 0x80;
CTK_WIDGET_REDRAW(&(editor_state.labels[editor_state.y]));
/* } else if(s == ctk_signal_widget_activate &&
data == (process_data_t)t) {
textptr = &(t->label.text[t->ypos * t->label.w + t->xpos]);
*textptr &= 0x7f;
t->xpos = 0;
if(t->ypos < t->label.h - 1) {
++t->ypos;
}
textptr = &(t->label.text[t->ypos * t->label.w + t->xpos]);
*textptr |= 0x80;
CTK_WIDGET_REDRAW(&t->label);*/
}
}
/*---------------------------------------------------------------------------*/
static void
open_file(char *name)
{
int fd;
struct line *l;
char line[LINE_LEN];
char *cptr;
int i, len, clen;
fd = cfs_open(name, 0);
if(fd < 0) {
show_statustext("Could not open file ", name);
return;
}
l = lines;
cptr = l->text;
clen = LINE_LEN;
do {
/* Read a portion of the input file */
len = cfs_read(fd, line, LINE_LEN);
/* Split the input into lines. */
for(i = 0; i < len; ++i) {
if(line[i] == ISO_nl ||
clen == 0) {
*cptr = 0;
l = l->next;
if(l != NULL) {
cptr = l->text;
clen = LINE_LEN;
} else {
len = -1;
break;
}
} else {
*cptr++ = line[i];
--clen;
}
}
} while(len > 0);
cfs_close(fd);
}
/*---------------------------------------------------------------------------*/
static void
quit(void)
{
ctk_window_close(&window);
process_exit(&editor_process);
LOADER_UNLOAD();
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(editor_process, ev, data)
{
PROCESS_BEGIN();
memb_init(&linesmem);
ctk_window_new(&window,
EDITOR_CONF_WIDTH + 2,
EDITOR_CONF_HEIGHT + 3,
"Editor");
CTK_WIDGET_ADD(&window, &openbutton);
CTK_WIDGET_ADD(&window, &statuslabel);
CTK_WIDGET_FOCUS(&window, &openbutton);
editor_start();
ctk_window_open(&window);
while(1) {
PROCESS_WAIT_EVENT();
if(ctk_filedialog_eventhandler(&filedialog, ev, data)) {
} else {
if(ev == PROCESS_EVENT_EXIT) {
quit();
} else if(ev == OPEN_EVENT) {
/* printf("Open file '%s'\n", (char *)data);*/
open_file((char *)data);
ctk_window_redraw(&window);
} else {
if(ev == ctk_signal_window_close &&
data == (process_data_t)&window) {
quit();
} else if(ev == ctk_signal_widget_activate) {
if(data == (process_data_t)&openbutton) {
ctk_filedialog_open(&filedialog, "Open", OPEN_EVENT);
}
} else {
editor_eventhandler(ev, data);
}
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/*LOADER_INIT_FUNC(editor_init, arg)
{
arg_free(arg);
id = ek_start(&p);
}*/
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,3 @@
APP_SOURCES += email.c smtp-socket.c smtp-strings.c ctk-textentry-multiline.c \
psock.c uipbuf.c memb.c
DSC_SOURCES += email-dsc.c

74
apps/email/email-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: email-dsc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon email_icon;
/*-----------------------------------------------------------------------------------*/
DSC(email_dsc,
"Unfinished e-mail client",
"email.prg",
email_process,
&email_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char tcpipconficon_bitmap[3*3*8] = {
0x00, 0x79, 0x43, 0x73, 0x47, 0x77, 0x47, 0x6f,
0x00, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xfb,
0x00, 0x16, 0x02, 0x00, 0x02, 0x00, 0x00, 0xc2,
0x48, 0x4c, 0x5f, 0x5f, 0x1f, 0x3f, 0x3f, 0x03,
0x79, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xfe, 0xfc,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x77, 0x47, 0x70, 0x43, 0x79, 0x41, 0x7c, 0x00,
0xfc, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xf7, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x84, 0xf0, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char tcpipconficon_textmap[9] = {
'+', '-', '+',
'|', 'v', '|',
'+', '-', '+'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon email_icon =
{CTK_ICON("E-mail", tcpipconficon_bitmap, tcpipconficon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/email/email-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: email-dsc.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#ifndef __EMAIL_DSC_H__
#define __EMAIL_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(email_dsc);
#endif /* __EMAIL_DSC_H__ */

335
apps/email/email.c Normal file
View file

@ -0,0 +1,335 @@
/*
* Copyright (c) 2002, 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 environment for the C64.
*
* $Id: email.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#include "contiki.h"
#include "ctk/ctk.h"
#include "smtp.h"
#include "lib/petsciiconv.h"
#include "lib/ctk-textentry-multiline.h"
#include <string.h>
#ifdef EMAIL_CONF_WIDTH
#define MAIL_WIDTH EMAIL_CONF_WIDTH
#else
#define MAIL_WIDTH 37
#endif
#ifdef EMAIL_CONF_HEIGHT
#define MAIL_HEIGHT EMAIL_CONF_HEIGHT
#else
#define MAIL_HEIGHT 17
#endif
#if (MAIL_WIDTH - 9) < 39
#define TEXTENTRY_WIDTH (MAIL_WIDTH - 9)
#else
#define TEXTENTRY_WIDTH 39
#endif
static struct ctk_menu menu;
unsigned char menuitem_compose, menuitem_setup, menuitem_quit;
/* The main window. */
static struct ctk_window composewindow;
static struct ctk_separator sep1 =
{CTK_SEPARATOR(0, MAIL_HEIGHT + 3, MAIL_WIDTH + 1)};
static struct ctk_label statuslabel =
{CTK_LABEL(7, MAIL_HEIGHT + 4, MAIL_WIDTH - 14, 1, "")};
static struct ctk_label tolabel =
{CTK_LABEL(0, 0, 3, 1, "To:")};
static char to[40];
static struct ctk_textentry totextentry =
{CTK_TEXTENTRY(8, 0, TEXTENTRY_WIDTH, 1, to, 39)};
static struct ctk_label cclabel =
{CTK_LABEL(0, 1, 3, 1, "Cc:")};
static char cc[40];
static struct ctk_textentry cctextentry =
{CTK_TEXTENTRY(8, 1, TEXTENTRY_WIDTH, 1, cc, 39)};
static struct ctk_label subjectlabel =
{CTK_LABEL(0, 2, 8, 1, "Subject:")};
static char subject[40];
static struct ctk_textentry subjecttextentry =
{CTK_TEXTENTRY(8, 2, TEXTENTRY_WIDTH, 1, subject, 39)};
static char mail[MAIL_WIDTH * MAIL_HEIGHT];
struct ctk_textentry mailtextentry =
{CTK_TEXTENTRY_INPUT(0, 3, MAIL_WIDTH - 1, MAIL_HEIGHT, mail, MAIL_WIDTH - 1, \
ctk_textentry_multiline_input)};
static struct ctk_button sendbutton =
{CTK_BUTTON(0, MAIL_HEIGHT + 4, 4, "Send")};
static struct ctk_button erasebutton =
{CTK_BUTTON(MAIL_WIDTH - 6, MAIL_HEIGHT + 4, 5, "Erase")};
/* The "Really erase message?" dialog. */
static struct ctk_window erasedialog;
static struct ctk_label erasedialoglabel1 =
{CTK_LABEL(2, 1, 22, 1, "Really erase message?")};
static struct ctk_label erasedialoglabel2 =
{CTK_LABEL(0, 2, 26, 1, "All contents will be lost.")};
static struct ctk_button eraseyesbutton =
{CTK_BUTTON(4, 4, 3, "Yes")};
static struct ctk_button erasenobutton =
{CTK_BUTTON(18, 4, 2, "No")};
/* The setup window. */
static struct ctk_window setupwindow;
static struct ctk_label fromaddresslabel =
{CTK_LABEL(0, 0, 25, 1, "Name and e-mail address")};
static char fromaddress[40];
static struct ctk_textentry fromaddresstextentry =
{CTK_TEXTENTRY(0, 1, 26, 1, fromaddress, 39)};
static struct ctk_label smtpserverlabel =
{CTK_LABEL(0, 3, 20, 1, "Outgoing mailserver")};
static char smtpserver[40];
static struct ctk_textentry smtpservertextentry =
{CTK_TEXTENTRY(0, 4, 26, 1, smtpserver, 39)};
static struct ctk_label pop3serverlabel =
{CTK_LABEL(0, 6, 20, 1, "Incoming mailserver")};
static char pop3server[40];
static struct ctk_textentry pop3servertextentry =
{CTK_TEXTENTRY(0, 7, 26, 1, pop3server, 39)};
static struct ctk_label pop3userlabel =
{CTK_LABEL(0, 9, 20, 1, "Mailserver username")};
static char pop3user[40];
static struct ctk_textentry pop3usertextentry =
{CTK_TEXTENTRY(0, 10, 26, 1, pop3user, 39)};
static struct ctk_label pop3passwordlabel =
{CTK_LABEL(0, 12, 20, 1, "Mailserver password")};
static char pop3password[40];
static struct ctk_textentry pop3passwordtextentry =
{CTK_TEXTENTRY(0, 13, 26, 1, pop3password, 39)};
static struct ctk_button setupokbutton =
{CTK_BUTTON(24, 15, 2, "Ok")};
PROCESS(email_process, "E-mail client");
/*-----------------------------------------------------------------------------------*/
static void
email_quit(void)
{
ctk_window_close(&setupwindow);
ctk_window_close(&composewindow);
ctk_menu_remove(&menu);
process_exit(&email_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
static void
applyconfig(void)
{
u16_t addr[2], *addrptr;
char *cptr;
for(cptr = smtpserver; *cptr != ' ' && *cptr != 0; ++cptr);
*cptr = 0;
addrptr = &addr[0];
if(uiplib_ipaddrconv(smtpserver, (unsigned char *)addr) == 0) {
addrptr = resolv_lookup(smtpserver);
if(addrptr == NULL) {
resolv_query(smtpserver);
ctk_label_set_text(&statuslabel, "Resolving host...");
return;
}
}
smtp_configure("contiki", addrptr);
}
/*-----------------------------------------------------------------------------------*/
static void
prepare_message(void)
{
/* Convert fields to ASCII. */
petsciiconv_toascii(to, sizeof(to));
petsciiconv_toascii(cc, sizeof(cc));
petsciiconv_toascii(subject, sizeof(subject));
petsciiconv_toascii(mail, sizeof(mail));
}
/*-----------------------------------------------------------------------------------*/
static void
erase_message(void)
{
CTK_TEXTENTRY_CLEAR(&totextentry);
CTK_TEXTENTRY_CLEAR(&cctextentry);
CTK_TEXTENTRY_CLEAR(&subjecttextentry);
CTK_TEXTENTRY_CLEAR(&mailtextentry);
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(email_process, ev, data)
{
struct ctk_widget *w;
PROCESS_BEGIN();
/* Create the "Really erase message?" dialog. */
ctk_dialog_new(&erasedialog, 26, 6);
CTK_WIDGET_ADD(&erasedialog, &erasedialoglabel1);
CTK_WIDGET_ADD(&erasedialog, &erasedialoglabel2);
CTK_WIDGET_ADD(&erasedialog, &eraseyesbutton);
CTK_WIDGET_ADD(&erasedialog, &erasenobutton);
CTK_WIDGET_FOCUS(&erasedialog, &erasenobutton);
/* Create setup window. */
ctk_window_new(&setupwindow, 28, 16, "E-mail setup");
CTK_WIDGET_ADD(&setupwindow, &fromaddresslabel);
CTK_WIDGET_ADD(&setupwindow, &fromaddresstextentry);
CTK_WIDGET_ADD(&setupwindow, &smtpserverlabel);
CTK_WIDGET_ADD(&setupwindow, &smtpservertextentry);
/* CTK_WIDGET_ADD(&setupwindow, &pop3serverlabel);*/
/* CTK_WIDGET_ADD(&setupwindow, &pop3servertextentry);*/
/* CTK_WIDGET_ADD(&setupwindow, &pop3userlabel);*/
/* CTK_WIDGET_ADD(&setupwindow, &pop3usertextentry);*/
/* CTK_WIDGET_ADD(&setupwindow, &pop3passwordlabel);*/
/* CTK_WIDGET_ADD(&setupwindow, &pop3passwordtextentry);*/
CTK_WIDGET_ADD(&setupwindow, &setupokbutton);
CTK_WIDGET_FOCUS(&setupwindow, &fromaddresstextentry);
/* Create compose window. */
ctk_window_new(&composewindow, MAIL_WIDTH + 1, MAIL_HEIGHT + 5, "Compose e-mail");
CTK_WIDGET_ADD(&composewindow, &tolabel);
CTK_WIDGET_ADD(&composewindow, &cclabel);
CTK_WIDGET_ADD(&composewindow, &subjectlabel);
CTK_WIDGET_ADD(&composewindow, &totextentry);
CTK_WIDGET_FOCUS(&composewindow, &totextentry);
CTK_WIDGET_ADD(&composewindow, &cctextentry);
CTK_WIDGET_ADD(&composewindow, &subjecttextentry);
CTK_WIDGET_ADD(&composewindow, &mailtextentry);
CTK_WIDGET_ADD(&composewindow, &sep1);
CTK_WIDGET_ADD(&composewindow, &statuslabel);
CTK_WIDGET_ADD(&composewindow, &sendbutton);
CTK_WIDGET_ADD(&composewindow, &erasebutton);
erase_message();
/* Create and add the menu */
ctk_menu_new(&menu, "E-mail");
menuitem_setup = ctk_menuitem_add(&menu, "Setup");
menuitem_compose = ctk_menuitem_add(&menu, "Compose");
menuitem_quit = ctk_menuitem_add(&menu, "Quit");
ctk_menu_add(&menu);
/* Open setup window */
ctk_window_open(&setupwindow);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
smtp_appcall(data);
} else if(ev == ctk_signal_widget_activate) {
w = (struct ctk_widget *)data;
if(w == (struct ctk_widget *)&sendbutton) {
prepare_message();
smtp_send(to, cc, fromaddress, subject, mail, MAIL_WIDTH, MAIL_HEIGHT);
ctk_label_set_text(&statuslabel, "Sending message...");
CTK_WIDGET_REDRAW(&statuslabel);
} else if(w == (struct ctk_widget *)&erasebutton) {
ctk_dialog_open(&erasedialog);
} else if(w == (struct ctk_widget *)&eraseyesbutton) {
erase_message();
ctk_dialog_close();
} else if(w == (struct ctk_widget *)&erasenobutton) {
ctk_dialog_close();
} else if(w == (struct ctk_widget *)&setupokbutton) {
applyconfig();
ctk_window_close(&setupwindow);
ctk_window_open(&composewindow);
}
} else if(ev == ctk_signal_menu_activate) {
if((struct ctk_menu *)data == &menu) {
if(menu.active == menuitem_compose) {
ctk_window_open(&composewindow);
} else if(menu.active == menuitem_setup) {
ctk_window_open(&setupwindow);
} else if(menu.active == menuitem_quit) {
email_quit();
}
}
} else if(ev == resolv_event_found) {
if(strcmp(data, smtpserver) == 0) {
if(resolv_lookup(smtpserver) != NULL) {
applyconfig();
ctk_label_set_text(&statuslabel, "");
} else {
ctk_label_set_text(&statuslabel, "Host not found");
}
CTK_WIDGET_REDRAW(&statuslabel);
}
} else if(ev == PROCESS_EVENT_EXIT) {
email_quit();
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/
void
smtp_done(unsigned char error)
{
if(error == SMTP_ERR_OK) {
ctk_label_set_text(&statuslabel, "Mail sent");
erase_message();
ctk_window_open(&composewindow);
} else {
ctk_label_set_text(&statuslabel, "Mail error");
}
CTK_WIDGET_REDRAW(&statuslabel);
}
/*-----------------------------------------------------------------------------------*/

40
apps/email/email.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2002, 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 environment for the C64.
*
* $Id: email.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#ifndef __EMAIL_H__
#define __EMAIL_H__
void email_init(void);
#endif /* __EMAIL_H__ */

241
apps/email/smtp-socket.c Normal file
View file

@ -0,0 +1,241 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: smtp-socket.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
#include "smtp.h"
#include "smtp-strings.h"
#include "contiki-net.h"
#include <string.h>
struct smtp_state {
char connected;
struct psock psock;
char inputbuffer[4];
char *to;
char *cc;
char *from;
char *subject;
char *msg;
u8_t msgwidth;
u8_t msgheight;
u8_t line;
};
static struct smtp_state s;
static char *localhostname;
static u16_t smtpserver[2];
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define ISO_period 0x2e
#define ISO_2 0x32
#define ISO_3 0x33
#define ISO_4 0x34
#define ISO_5 0x35
#define SEND_STRING(s, str) PSOCK_SEND(s, str, strlen(str))
/*---------------------------------------------------------------------------*/
static
PT_THREAD(smtp_thread(void))
{
PSOCK_BEGIN(&s.psock);
PSOCK_READTO(&s.psock, ISO_nl);
if(strncmp(s.inputbuffer, smtp_220, 3) != 0) {
PSOCK_CLOSE(&s.psock);
smtp_done(2);
PSOCK_EXIT(&s.psock);
}
SEND_STRING(&s.psock, (char *)smtp_helo);
SEND_STRING(&s.psock, localhostname);
SEND_STRING(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(3);
PSOCK_EXIT(&s.psock);
}
SEND_STRING(&s.psock, (char *)smtp_mail_from);
SEND_STRING(&s.psock, s.from);
SEND_STRING(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(4);
PSOCK_EXIT(&s.psock);
}
SEND_STRING(&s.psock, (char *)smtp_rcpt_to);
SEND_STRING(&s.psock, s.to);
SEND_STRING(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(5);
PSOCK_EXIT(&s.psock);
}
if(*s.cc != 0) {
SEND_STRING(&s.psock, (char *)smtp_rcpt_to);
SEND_STRING(&s.psock, s.cc);
SEND_STRING(&s.psock, (char *)smtp_crnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(6);
PSOCK_EXIT(&s.psock);
}
}
SEND_STRING(&s.psock, (char *)smtp_data);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_3) {
PSOCK_CLOSE(&s.psock);
smtp_done(7);
PSOCK_EXIT(&s.psock);
}
SEND_STRING(&s.psock, (char *)smtp_to);
SEND_STRING(&s.psock, s.to);
SEND_STRING(&s.psock, (char *)smtp_crnl);
if(*s.cc != 0) {
SEND_STRING(&s.psock, (char *)smtp_cc);
SEND_STRING(&s.psock, s.cc);
SEND_STRING(&s.psock, (char *)smtp_crnl);
}
SEND_STRING(&s.psock, (char *)smtp_from);
SEND_STRING(&s.psock, s.from);
SEND_STRING(&s.psock, (char *)smtp_crnl);
SEND_STRING(&s.psock, (char *)smtp_subject);
SEND_STRING(&s.psock, s.subject);
SEND_STRING(&s.psock, (char *)smtp_crnl);
for(s.line = 0; s.line < s.msgheight; ++s.line) {
SEND_STRING(&s.psock, (char *)smtp_crnl);
SEND_STRING(&s.psock, &s.msg[s.line * s.msgwidth]);
}
SEND_STRING(&s.psock, (char *)smtp_crnlperiodcrnl);
PSOCK_READTO(&s.psock, ISO_nl);
if(s.inputbuffer[0] != ISO_2) {
PSOCK_CLOSE(&s.psock);
smtp_done(8);
PSOCK_EXIT(&s.psock);
}
SEND_STRING(&s.psock, (char *)smtp_quit);
smtp_done(SMTP_ERR_OK);
PSOCK_END(&s.psock);
}
/*---------------------------------------------------------------------------*/
void
smtp_appcall(void *state)
{
if(uip_closed()) {
s.connected = 0;
return;
}
if(uip_aborted() || uip_timedout()) {
s.connected = 0;
smtp_done(1);
return;
}
smtp_thread();
}
/*---------------------------------------------------------------------------*/
void
smtp_configure(char *lhostname, u16_t *server)
{
localhostname = lhostname;
smtpserver[0] = server[0];
smtpserver[1] = server[1];
}
/*---------------------------------------------------------------------------*/
unsigned char
smtp_send(char *to, char *cc, char *from, char *subject,
char *msg, u8_t msgwidth, u8_t msgheight)
{
struct uip_conn *conn;
conn = tcp_connect(smtpserver, HTONS(25), NULL);
if(conn == NULL) {
return 0;
}
s.connected = 1;
s.to = to;
s.cc = cc;
s.from = from;
s.subject = subject;
s.msg = msg;
s.msgwidth = msgwidth;
s.msgheight = msgheight;
PSOCK_INIT(&s.psock, s.inputbuffer, sizeof(s.inputbuffer));
return 1;
}
/*---------------------------------------------------------------------------*/
void
smtp_init(void)
{
s.connected = 0;
}
/*---------------------------------------------------------------------------*/

11
apps/email/smtp-strings Normal file
View file

@ -0,0 +1,11 @@
smtp_220 "220"
smtp_helo "HELO "
smtp_mail_from "MAIL FROM: "
smtp_rcpt_to "RCPT TO: "
smtp_data "DATA\r\n"
smtp_to "To: "
smtp_from "From: "
smtp_subject "Subject: "
smtp_quit "QUIT\r\n"
smtp_crnl "\r\n"
smtp_crnlperiodcrnl "\r\n.\r\n"

70
apps/email/smtp-strings.c Normal file
View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: smtp-strings.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
const char smtp_220[4] =
/* "220" */
{0x32, 0x32, 0x30, };
const char smtp_helo[6] =
/* "HELO " */
{0x48, 0x45, 0x4c, 0x4f, 0x20, };
const char smtp_mail_from[12] =
/* "MAIL FROM: " */
{0x4d, 0x41, 0x49, 0x4c, 0x20, 0x46, 0x52, 0x4f, 0x4d, 0x3a, 0x20, };
const char smtp_rcpt_to[10] =
/* "RCPT TO: " */
{0x52, 0x43, 0x50, 0x54, 0x20, 0x54, 0x4f, 0x3a, 0x20, };
const char smtp_data[7] =
/* "DATA\r\n" */
{0x44, 0x41, 0x54, 0x41, 0xd, 0xa, };
const char smtp_to[5] =
/* "To: " */
{0x54, 0x6f, 0x3a, 0x20, };
const char smtp_cc[5] =
/* "Cc: " */
{0x43, 0x63, 0x3a, 0x20, };
const char smtp_from[7] =
/* "From: " */
{0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x20, };
const char smtp_subject[10] =
/* "Subject: " */
{0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, };
const char smtp_quit[7] =
/* "QUIT\r\n" */
{0x51, 0x55, 0x49, 0x54, 0xd, 0xa, };
const char smtp_crnl[3] =
/* "\r\n" */
{0xd, 0xa, };
const char smtp_crnlperiodcrnl[6] =
/* "\r\n.\r\n" */
{0xd, 0xa, 0x2e, 0xd, 0xa, };

46
apps/email/smtp-strings.h Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: smtp-strings.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
extern const char smtp_220[4];
extern const char smtp_helo[6];
extern const char smtp_mail_from[12];
extern const char smtp_rcpt_to[10];
extern const char smtp_data[7];
extern const char smtp_to[5];
extern const char smtp_cc[5];
extern const char smtp_from[7];
extern const char smtp_subject[10];
extern const char smtp_quit[7];
extern const char smtp_crnl[3];
extern const char smtp_crnlperiodcrnl[6];

68
apps/email/smtp.h Normal file
View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2002, 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 uIP TCP/IP stack.
*
* $Id: smtp.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#ifndef __SMTP_H__
#define __SMTP_H__
#include "contiki-net.h"
/* Callbacks. */
#define SMTP_ERR_OK 0
void smtp_done(unsigned char error);
/* Functions. */
void smtp_configure(char *localhostname, u16_t *smtpserver);
/*
unsigned char smtp_send(char *to, char *cc, char *from,
char *subject, char *msg,
u8_t msgwidth, u8_t msgheight);
*/
unsigned char smtp_send(char *to, char *from,
char *subject, char *msg,
u16_t msglen);
void smtp_appcall(void *state);
#ifndef UIP_APPCALL
#define UIP_APPCALL smtp_appcall
#endif
#ifndef UIP_APPSTATE_SIZE
#define UIP_APPSTATE_SIZE (sizeof(struct smtp_state))
#endif
void smtp_init(void);
#endif /* __SMTP_H__ */

2
apps/ftp/Makefile.ftp Normal file
View file

@ -0,0 +1,2 @@
APP_SOURCES += ftp.c ftpc.c memb.c
DSC_SOURCES += ftp-dsc.c

74
apps/ftp/ftp-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2004, 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 environment
*
* $Id: ftp-dsc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon ftp_icon;
/*-----------------------------------------------------------------------------------*/
DSC(ftp_dsc,
"FTP client",
"ftp.prg",
ftp_process,
&ftp_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char ftpicon_bitmap[3*3*8] = {
0x00, 0x7e, 0x40, 0x73, 0x46, 0x4c, 0x18, 0x13,
0x00, 0x00, 0xff, 0x81, 0x34, 0xc9, 0x00, 0xb6,
0x00, 0x7e, 0x02, 0xce, 0x72, 0x32, 0x18, 0x48,
0x30, 0x27, 0x24, 0x20, 0x37, 0x24, 0x20, 0x33,
0x00, 0x7b, 0x42, 0x00, 0x7b, 0x42, 0x00, 0x3b,
0x0c, 0x24, 0x24, 0x04, 0xa4, 0x24, 0x04, 0x4c,
0x12, 0x19, 0x4c, 0x46, 0x63, 0x40, 0x7c, 0x00,
0x22, 0x91, 0x00, 0xc4, 0x81, 0xff, 0x00, 0x00,
0x08, 0x18, 0x32, 0x62, 0xc6, 0x02, 0x3e, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char ftpicon_textmap[9] = {
'F', 'T', 'P',
' ', ' ', ' ',
'F', 'T', 'P'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon ftp_icon =
{CTK_ICON("FTP client", ftpicon_bitmap, ftpicon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/ftp/ftp-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2004, 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 environment
*
* $Id: ftp-dsc.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#ifndef __FTP_DSC_H__
#define __FTP_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(ftp_dsc);
#endif /* __FTP_DSC_H__ */

577
apps/ftp/ftp.c Normal file
View file

@ -0,0 +1,577 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ftp.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
/* Note to self: It would be nice to have a "View" option in the download dialog. */
#include "ftpc.h"
#include "contiki.h"
#include "ctk/ctk.h"
#include "cfs/cfs.h"
#include "net/resolv.h"
#include <string.h>
#define MAX_USERNAMELEN 16
#define MAX_PASSWORDLEN 16
#define MAX_HOSTNAMELEN 32
#define MAX_FILENAMELEN 16
#define FILES_WIDTH 17
#define FILES_HEIGHT 18
PROCESS(ftp_process, "FTP client");
static void *connection;
/* --- The main window --- */
static struct ctk_window window;
static struct ctk_label localtextlabel =
{CTK_LABEL(1, 0, FILES_WIDTH, 1, "Local files")};
static struct ctk_label remotetextlabel =
{CTK_LABEL(1 + FILES_WIDTH + 1, 0,
FILES_WIDTH, 1, "Remote files")};
static char leftptr[FILES_HEIGHT];
static struct ctk_label leftptrlabel =
{CTK_LABEL(0, 1, 1, FILES_HEIGHT, leftptr)};
static char midptr[FILES_HEIGHT];
static struct ctk_label midptrlabel =
{CTK_LABEL(1 + FILES_WIDTH, 1, 1, FILES_HEIGHT, midptr)};
static char rightptr[FILES_HEIGHT];
static struct ctk_label rightptrlabel =
{CTK_LABEL(1 + FILES_WIDTH + 1 + FILES_WIDTH, 1,
1, FILES_HEIGHT, rightptr)};
static char localfiles[FILES_WIDTH * FILES_HEIGHT];
static struct ctk_label localfileslabel =
{CTK_LABEL(1, 1,
FILES_WIDTH, FILES_HEIGHT, localfiles)};
static char remotefiles[FILES_WIDTH * FILES_HEIGHT];
static struct ctk_label remotefileslabel =
{CTK_LABEL(FILES_WIDTH + 1 + 1, 1,
FILES_WIDTH, FILES_HEIGHT, remotefiles)};
static struct ctk_button reloadbutton =
{CTK_BUTTON(0, 1 + FILES_HEIGHT, 6, "Reload")};
static struct ctk_button connectionbutton =
{CTK_BUTTON(8, 1 + FILES_HEIGHT, 13, "Connection...")};
static struct ctk_button quitbutton =
{CTK_BUTTON(1 + FILES_WIDTH + 1 + FILES_WIDTH - 5,
1 + FILES_HEIGHT, 4, "Quit")};
static char statustext[3 + FILES_WIDTH * 2 + 1];
static struct ctk_label statuslabel =
{CTK_LABEL(0, FILES_HEIGHT + 2, 3 + FILES_WIDTH * 2, 1, statustext)};
/* --- The download/upload dialogs --- */
static char remotefilename[MAX_FILENAMELEN + 1];
static char localfilename[MAX_FILENAMELEN + 1];
static struct ctk_window dialog;
static struct ctk_label downloadlabel =
{CTK_LABEL(6, 1, 13, 1, "Download file")};
static struct ctk_label uploadlabel =
{CTK_LABEL(7, 1, 11, 1, "Upload file")};
static struct ctk_label localfilenametextlabel =
{CTK_LABEL(2, 3, 15, 1, "Local filename")};
static struct ctk_label localfilenamelabel =
{CTK_LABEL(3, 5, 16, 1, localfilename)};
static struct ctk_textentry localfilenameentry =
{CTK_TEXTENTRY(2, 5, 16, 1, localfilename, sizeof(localfilename) - 1)};
static struct ctk_label remotefilenametextlabel =
{CTK_LABEL(2, 7, 15, 1, "Remote filename")};
static struct ctk_label remotefilenamelabel =
{CTK_LABEL(3, 9, 16, 1, remotefilename)};
static struct ctk_textentry remotefilenameentry =
{CTK_TEXTENTRY(2, 9, 16, 1, remotefilename, sizeof(remotefilename) - 1)};
static struct ctk_button downloadbutton =
{CTK_BUTTON(0, 11, 13, "Download file")};
static struct ctk_button uploadbutton =
{CTK_BUTTON(0, 11, 11, "Upload file")};
static struct ctk_button cancelbutton =
{CTK_BUTTON(16, 11, 6, "Cancel")};
/* --- The connection window --- */
static char hostname[MAX_HOSTNAMELEN + 1];
static char username[MAX_USERNAMELEN + 1];
static char password[MAX_PASSWORDLEN + 1];
static struct ctk_window connectionwindow;
static struct ctk_label serverlabel =
{CTK_LABEL(0, 1, 10, 1, "FTP server")};
static struct ctk_textentry serverentry =
{CTK_TEXTENTRY(0, 2, 16, 1, hostname, MAX_HOSTNAMELEN)};
static struct ctk_button anonymousbutton =
{CTK_BUTTON(10, 4, 9, "Anonymous")};
static struct ctk_label userlabel =
{CTK_LABEL(0, 4, 8, 1, "Username")};
static struct ctk_textentry userentry =
{CTK_TEXTENTRY(0, 5, 16, 1, username, sizeof(username) - 1)};
static struct ctk_label passwordlabel =
{CTK_LABEL(0, 7, 8, 1, "Password")};
static struct ctk_textentry passwordentry =
{CTK_TEXTENTRY(0, 8, 16, 1, password, sizeof(password) - 1)};
static struct ctk_button connectbutton =
{CTK_BUTTON(0, 10, 7, "Connect")};
static struct ctk_button closeconnectionbutton =
{CTK_BUTTON(0, 10, 16, "Close connection")};
static struct ctk_button closebutton =
{CTK_BUTTON(18, 10, 5, "Close")};
static struct cfs_dir dir;
static struct cfs_dirent dirent;
static unsigned char localfileptr = 0;
static unsigned char remotefileptr = 0;
static unsigned char ptrstate;
#define PTRSTATE_LOCALFILES 0
#define PTRSTATE_REMOTEFILES 1
static unsigned char localptr, remoteptr;
static int fd = -1;
/*---------------------------------------------------------------------------*/
static void
make_uploaddialog(void)
{
ctk_dialog_new(&dialog, 24, 13);
CTK_WIDGET_ADD(&dialog, &uploadlabel);
CTK_WIDGET_ADD(&dialog, &localfilenametextlabel);
CTK_WIDGET_ADD(&dialog, &localfilenamelabel);
CTK_WIDGET_ADD(&dialog, &remotefilenametextlabel);
CTK_WIDGET_ADD(&dialog, &remotefilenameentry);
CTK_WIDGET_ADD(&dialog, &uploadbutton);
CTK_WIDGET_ADD(&dialog, &cancelbutton);
CTK_WIDGET_FOCUS(&dialog, &uploadbutton);
}
/*---------------------------------------------------------------------------*/
static void
make_downloaddialog(void)
{
ctk_dialog_new(&dialog, 24, 13);
CTK_WIDGET_ADD(&dialog, &downloadlabel);
CTK_WIDGET_ADD(&dialog, &localfilenametextlabel);
CTK_WIDGET_ADD(&dialog, &localfilenameentry);
CTK_WIDGET_ADD(&dialog, &remotefilenametextlabel);
CTK_WIDGET_ADD(&dialog, &remotefilenamelabel);
CTK_WIDGET_ADD(&dialog, &downloadbutton);
CTK_WIDGET_ADD(&dialog, &cancelbutton);
CTK_WIDGET_FOCUS(&dialog, &downloadbutton);
}
/*---------------------------------------------------------------------------*/
static void
show_statustext(char *text1, char *text2)
{
int len;
len = strlen(text1);
if(len < sizeof(statustext)) {
strncpy(statustext, text1, sizeof(statustext));
strncpy(statustext + len, text2, sizeof(statustext) - len);
CTK_WIDGET_REDRAW(&statuslabel);
}
}
/*---------------------------------------------------------------------------*/
static void
close_file(void)
{
if(fd != -1) {
cfs_close(fd);
fd = -1;
}
}
/*---------------------------------------------------------------------------*/
static void
quit(void)
{
close_file();
ctk_window_close(&window);
process_exit(&ftp_process);
LOADER_UNLOAD();
}
/*---------------------------------------------------------------------------*/
static void
clearptr(void)
{
rightptr[remoteptr] = ' ';
midptr[remoteptr] = ' ';
leftptr[localptr] = ' ';
midptr[localptr] = ' ';
}
/*---------------------------------------------------------------------------*/
static void
showptr(void)
{
if(ptrstate == PTRSTATE_LOCALFILES) {
rightptr[remoteptr] = ' ';
midptr[remoteptr] = ' ';
leftptr[localptr] = '>';
midptr[localptr] = '<';
} else {
leftptr[localptr] = ' ';
midptr[localptr] = ' ';
rightptr[remoteptr] = '<';
midptr[remoteptr] = '>';
}
CTK_WIDGET_REDRAW(&leftptrlabel);
CTK_WIDGET_REDRAW(&midptrlabel);
CTK_WIDGET_REDRAW(&rightptrlabel);
}
/*---------------------------------------------------------------------------*/
static void
start_loaddir(void)
{
memset(localfiles, 0, sizeof(localfiles));
localfileptr = 0;
cfs_opendir(&dir, ".");
process_post(&ftp_process, PROCESS_EVENT_CONTINUE, NULL);
}
/*---------------------------------------------------------------------------*/
static void
start_loadremote(void)
{
memset(remotefiles, 0, sizeof(remotefiles));
remotefileptr = 0;
clearptr();
remoteptr = 0;
showptr();
ftpc_list(connection);
}
/*---------------------------------------------------------------------------*/
static void
make_connectionwindow(void)
{
ctk_dialog_new(&connectionwindow, 25, 11);
CTK_WIDGET_ADD(&connectionwindow, &serverlabel);
CTK_WIDGET_ADD(&connectionwindow, &serverentry);
CTK_WIDGET_ADD(&connectionwindow, &userlabel);
CTK_WIDGET_ADD(&connectionwindow, &anonymousbutton);
CTK_WIDGET_ADD(&connectionwindow, &userentry);
CTK_WIDGET_ADD(&connectionwindow, &passwordlabel);
CTK_WIDGET_ADD(&connectionwindow, &passwordentry);
if(connection == NULL) {
CTK_WIDGET_ADD(&connectionwindow, &connectbutton);
} else {
CTK_WIDGET_ADD(&connectionwindow, &closeconnectionbutton);
}
CTK_WIDGET_ADD(&connectionwindow, &closebutton);
CTK_WIDGET_FOCUS(&connectionwindow, &serverentry);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(ftp_process, ev, data)
{
u16_t ipaddr[2], *ipaddrptr;
PROCESS_BEGIN();
ftpc_init();
memset(statustext, 0, sizeof(statustext));
memset(remotefiles, 0, sizeof(remotefiles));
memset(localfiles, 0, sizeof(localfiles));
memset(leftptr, 0, sizeof(leftptr));
memset(midptr, 0, sizeof(midptr));
memset(rightptr, 0, sizeof(rightptr));
ptrstate = PTRSTATE_REMOTEFILES;
localptr = remoteptr = 0;
connection = NULL;
ctk_window_new(&window,
3 + FILES_WIDTH * 2, 3 + FILES_HEIGHT,
"FTP Client");
CTK_WIDGET_ADD(&window, &localtextlabel);
CTK_WIDGET_ADD(&window, &remotetextlabel);
CTK_WIDGET_ADD(&window, &leftptrlabel);
CTK_WIDGET_ADD(&window, &localfileslabel);
CTK_WIDGET_ADD(&window, &midptrlabel);
CTK_WIDGET_ADD(&window, &remotefileslabel);
CTK_WIDGET_ADD(&window, &rightptrlabel);
CTK_WIDGET_ADD(&window, &reloadbutton);
CTK_WIDGET_ADD(&window, &connectionbutton);
CTK_WIDGET_ADD(&window, &quitbutton);
CTK_WIDGET_ADD(&window, &statuslabel);
CTK_WIDGET_FOCUS(&window, &connectionbutton);
ctk_window_open(&window);
showptr();
start_loaddir();
while(1) {
PROCESS_WAIT_EVENT();
if(ev == PROCESS_EVENT_CONTINUE) {
if(cfs_readdir(&dir, &dirent) == 0 &&
localfileptr < FILES_HEIGHT) {
strncpy(&localfiles[localfileptr * FILES_WIDTH],
dirent.name, FILES_WIDTH);
CTK_WIDGET_REDRAW(&localfileslabel);
++localfileptr;
process_post(&ftp_process, PROCESS_EVENT_CONTINUE, NULL);
} else{
cfs_closedir(&dir);
}
} else if(ev == PROCESS_EVENT_EXIT) {
quit();
} else if(ev == tcpip_event) {
ftpc_appcall(data);
} else if(ev == resolv_event_found) {
/* Either found a hostname, or not. */
if((char *)data != NULL &&
(ipaddrptr = resolv_lookup((char *)data)) != NULL) {
connection = ftpc_connect(ipaddrptr, HTONS(21));
show_statustext("Connecting to ", hostname);
} else {
show_statustext("Host not found: ", hostname);
}
} else if(ev == ctk_signal_window_close &&
data == (process_data_t)&window) {
quit();
} else if(ev == ctk_signal_widget_activate) {
if((struct ctk_button *)data == &quitbutton) {
quit();
} else if((struct ctk_button *)data == &cancelbutton) {
ctk_dialog_close();
} else if((struct ctk_button *)data == &downloadbutton) {
ctk_dialog_close();
close_file();
fd = cfs_open(localfilename, CFS_WRITE);
if(fd != -1) {
show_statustext("Downloading ", remotefilename);
ftpc_get(connection, remotefilename);
} else {
show_statustext("Could not create ", localfilename);
}
} else if((struct ctk_button *)data == &reloadbutton) {
start_loaddir();
} else if((struct ctk_button *)data == &connectionbutton) {
make_connectionwindow();
ctk_dialog_open(&connectionwindow);
} else if((struct ctk_button *)data == &closebutton) {
ctk_dialog_close();
} else if((struct ctk_button *)data == &anonymousbutton) {
strcpy(username, "ftp");
strcpy(password, "contiki@ftp");
CTK_WIDGET_REDRAW(&userentry);
CTK_WIDGET_REDRAW(&passwordentry);
} else if((struct ctk_button *)data == &closeconnectionbutton) {
ctk_dialog_close();
ftpc_close(connection);
} else if((struct ctk_button *)data == &connectbutton) {
ctk_dialog_close();
if(uiplib_ipaddrconv(hostname, (unsigned char *)ipaddr) == 0) {
ipaddrptr = resolv_lookup(hostname);
if(ipaddrptr == NULL) {
resolv_query(hostname);
show_statustext("Resolving host ", hostname);
break;
}
connection = ftpc_connect(ipaddrptr, HTONS(21));
show_statustext("Connecting to ", hostname);
} else {
connection = ftpc_connect(ipaddr, HTONS(21));
show_statustext("Connecting to ", hostname);
}
}
/* if((struct ctk_button *)data == &closebutton) {
ftpc_close(connection);
}*/
} else if(ev == ctk_signal_keypress) {
/* if((ctk_arch_key_t)data == ' ') {
if(ptrstate == PTRSTATE_LOCALFILES) {
ptrstate = PTRSTATE_REMOTEFILES;
} else {
ptrstate = PTRSTATE_LOCALFILES;
}
} else */ if((ctk_arch_key_t)data == CH_CURS_UP) {
clearptr();
if(ptrstate == PTRSTATE_LOCALFILES) {
if(localptr > 0) {
--localptr;
}
} else {
if(remoteptr > 0) {
--remoteptr;
}
}
} else if((ctk_arch_key_t)data == CH_CURS_DOWN) {
clearptr();
if(ptrstate == PTRSTATE_LOCALFILES) {
if(localptr < FILES_HEIGHT - 1) {
++localptr;
}
} else {
if(remoteptr < FILES_HEIGHT - 1) {
++remoteptr;
}
}
} else if((ctk_arch_key_t)data == CH_ENTER) {
if(ptrstate == PTRSTATE_LOCALFILES) {
strncpy(localfilename,
&localfiles[localptr * FILES_WIDTH], FILES_WIDTH);
strncpy(remotefilename,
&localfiles[localptr * FILES_WIDTH], FILES_WIDTH);
make_uploaddialog();
ctk_dialog_open(&dialog);
} else {
strncpy(localfilename,
&remotefiles[remoteptr * FILES_WIDTH], FILES_WIDTH);
strncpy(remotefilename,
&remotefiles[remoteptr * FILES_WIDTH], FILES_WIDTH);
ftpc_cwd(connection, remotefilename);
/* make_downloaddialog();
ctk_dialog_open(&dialog);*/
}
} else if((ctk_arch_key_t)data == 'u') {
ftpc_cdup(connection);
}
showptr();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
ftpc_closed(void)
{
strcpy(statustext, "Connection closed");
CTK_WIDGET_REDRAW(&statuslabel);
connection = NULL;
}
/*---------------------------------------------------------------------------*/
void
ftpc_aborted(void)
{
strcpy(statustext, "Connection reset");
CTK_WIDGET_REDRAW(&statuslabel);
connection = NULL;
}
/*---------------------------------------------------------------------------*/
void
ftpc_timedout(void)
{
strcpy(statustext, "Connection timed out");
CTK_WIDGET_REDRAW(&statuslabel);
connection = NULL;
}
/*---------------------------------------------------------------------------*/
char *
ftpc_username(void)
{
return username;
}
/*---------------------------------------------------------------------------*/
char *
ftpc_password(void)
{
return password;
}
/*---------------------------------------------------------------------------*/
void
ftpc_list_file(char *filename)
{
if(remotefileptr < FILES_HEIGHT && filename != NULL) {
strncpy(&remotefiles[remotefileptr * FILES_WIDTH], filename, FILES_WIDTH);
CTK_WIDGET_REDRAW(&remotefileslabel);
++remotefileptr;
}
if(filename == NULL) {
strcpy(statustext, "Connected");
CTK_WIDGET_REDRAW(&statuslabel);
}
}
/*---------------------------------------------------------------------------*/
void
ftpc_cwd_done(unsigned short status)
{
if(status == FTPC_COMPLETED ||
status == FTPC_OK) {
start_loadremote();
} else {
make_downloaddialog();
ctk_dialog_open(&dialog);
}
}
/*---------------------------------------------------------------------------*/
void
ftpc_connected(void *connection)
{
strcpy(statustext, "Loading remote directory");
CTK_WIDGET_REDRAW(&statuslabel);
start_loadremote();
}
/*---------------------------------------------------------------------------*/
void
ftpc_data(u8_t *data, u16_t len)
{
if(data == NULL) {
show_statustext("Download complete", "");
close_file();
start_loaddir();
} else {
cfs_write(fd, data, len);
}
}
/*---------------------------------------------------------------------------*/

506
apps/ftp/ftpc.c Normal file
View file

@ -0,0 +1,506 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ftpc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
#include "contiki.h"
#include "ftpc.h"
#include <string.h>
#include <stdio.h>
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define DATAPORT 6510
#define MAX_FILENAMELEN 32
struct ftp_dataconn {
unsigned char type;
unsigned char conntype;
#define CONNTYPE_LIST 0
#define CONNTYPE_FILE 1
u16_t port;
unsigned char filenameptr;
char filename[MAX_FILENAMELEN];
};
struct ftp_connection {
unsigned char type;
#define TYPE_CONTROL 1
#define TYPE_DATA 2
#define TYPE_ABORT 3
#define TYPE_CLOSE 4
unsigned char state;
#define STATE_NONE 0
#define STATE_INITIAL 1
#define STATE_SEND_USER 2
#define STATE_USER_SENT 3
#define STATE_SEND_PASS 4
#define STATE_PASS_SENT 5
#define STATE_SEND_PORT 6
#define STATE_PORT_SENT 7
#define STATE_SEND_OPTIONS 8
#define STATE_OPTION_SENT 9
#define STATE_CONNECTED 10
#define STATE_SEND_NLST 11
#define STATE_NLST_SENT 12
#define STATE_SEND_RETR 13
#define STATE_RETR_SENT 14
#define STATE_SEND_CWD 15
#define STATE_CWD_SENT 16
#define STATE_SEND_CDUP 17
#define STATE_CDUP_SENT 18
#define STATE_SEND_QUIT 19
#define STATE_QUIT_SENT 20
unsigned char connected_confirmed;
struct ftp_dataconn dataconn;
char code[3];
unsigned char codeptr;
unsigned char optionsptr;
char filename[MAX_FILENAMELEN];
};
#define NUM_OPTIONS 1
static const struct {
unsigned char num;
char *commands[NUM_OPTIONS];
} options = {
NUM_OPTIONS,
{"TYPE I\r\n"}
};
static struct ftp_connection *waiting_for_dataconn;
MEMB(connections, struct ftp_connection, 1);
/*---------------------------------------------------------------------------*/
void
ftpc_init(void)
{
memb_init(&connections);
/* tcp_listen(HTONS(DATAPORT));*/
}
/*---------------------------------------------------------------------------*/
void *
ftpc_connect(u16_t *ipaddr, u16_t port)
{
struct ftp_connection *c;
c = (struct ftp_connection *)memb_alloc(&connections);
if(c == NULL) {
return NULL;
}
c->type = TYPE_CONTROL;
c->state = STATE_INITIAL;
c->connected_confirmed = 0;
c->codeptr = 0;
c->dataconn.type = TYPE_DATA;
c->dataconn.port = DATAPORT;
tcp_listen(HTONS(DATAPORT));
if(tcp_connect(ipaddr, port, c) == NULL) {
memb_free(&connections, c);
return NULL;
}
return c;
}
/*---------------------------------------------------------------------------*/
static void
handle_input(struct ftp_connection *c)
{
int code;
code = (c->code[0] - '0') * 100 +
(c->code[1] - '0') * 10 +
(c->code[2] - '0');
/* printf("Handle input code %d state %d\n", code, c->state);*/
if(c->state == STATE_INITIAL) {
if(code == 220) {
c->state = STATE_SEND_USER;
}
} else if(c->state == STATE_USER_SENT) {
if(code == 331) {
c->state = STATE_SEND_PASS;
}
} else if(c->state == STATE_PASS_SENT) {
if(code == 230) {
c->state = STATE_SEND_OPTIONS;
c->optionsptr = 0;
}
} else if(c->state == STATE_PORT_SENT) {
c->state = STATE_CONNECTED;
if(c->connected_confirmed == 0) {
ftpc_connected(c);
c->connected_confirmed = 1;
}
} else if(c->state == STATE_OPTION_SENT) {
if(c->optionsptr >= options.num) {
c->state = STATE_SEND_PORT;
} else {
c->state = STATE_SEND_OPTIONS;
}
} else if((c->state == STATE_NLST_SENT ||
c->state == STATE_RETR_SENT ||
c->state == STATE_CONNECTED)) {
if(code == 226 || code == 550) {
tcp_unlisten(htons(c->dataconn.port));
++c->dataconn.port;
tcp_listen(htons(c->dataconn.port));
c->state = STATE_SEND_PORT;
}
if(code == 550) {
ftpc_list_file(NULL);
}
} else if(c->state == STATE_CWD_SENT ||
c->state == STATE_CDUP_SENT) {
c->state = STATE_CONNECTED;
ftpc_cwd_done(code);
/* } else if(c->state == STATE_) {
c->state = STATE_CONNECTED;*/
}
}
/*---------------------------------------------------------------------------*/
static void
newdata(struct ftp_connection *c)
{
u16_t i;
u8_t d;
for(i = 0; i < uip_datalen(); ++i) {
d = ((char *)uip_appdata)[i];
if(c->codeptr < sizeof(c->code)) {
c->code[c->codeptr] = d;
++c->codeptr;
}
if(d == ISO_nl) {
handle_input(c);
c->codeptr = 0;
}
}
}
/*---------------------------------------------------------------------------*/
static void
acked(struct ftp_connection *c)
{
switch(c->state) {
case STATE_SEND_USER:
c->state = STATE_USER_SENT;
break;
case STATE_SEND_PASS:
c->state = STATE_PASS_SENT;
break;
case STATE_SEND_PORT:
c->state = STATE_PORT_SENT;
break;
case STATE_SEND_OPTIONS:
++c->optionsptr;
c->state = STATE_OPTION_SENT;
break;
case STATE_SEND_NLST:
c->state = STATE_NLST_SENT;
break;
case STATE_SEND_RETR:
c->state = STATE_RETR_SENT;
break;
case STATE_SEND_CWD:
c->state = STATE_CWD_SENT;
break;
case STATE_SEND_CDUP:
c->state = STATE_CDUP_SENT;
break;
case STATE_SEND_QUIT:
c->state = STATE_QUIT_SENT;
uip_close();
break;
}
}
/*---------------------------------------------------------------------------*/
static void
senddata(struct ftp_connection *c)
{
u16_t len;
switch(c->state) {
case STATE_SEND_USER:
strcpy(uip_appdata, "USER ");
strncpy((char *)uip_appdata + 5, ftpc_username(), uip_mss() - 7);
len = strlen(ftpc_username());
strcpy((char *)uip_appdata + 5 + len, "\r\n");
uip_send(uip_appdata, len + 2 + 5);
break;
case STATE_SEND_PASS:
strcpy(uip_appdata, "PASS ");
strncpy((char *)uip_appdata + 5, ftpc_password(), uip_mss() - 7);
len = strlen(ftpc_password());
strcpy((char *)uip_appdata + 5 + len, "\r\n");
uip_send(uip_appdata, len + 2 + 5);
break;
case STATE_SEND_PORT:
len = sprintf(uip_appdata, "PORT %d,%d,%d,%d,%d,%d\n",
uip_ipaddr1(uip_hostaddr),
uip_ipaddr2(uip_hostaddr),
uip_ipaddr3(uip_hostaddr),
uip_ipaddr4(uip_hostaddr),
(c->dataconn.port) >> 8,
(c->dataconn.port) & 0xff);
uip_send(uip_appdata, len);
break;
case STATE_SEND_OPTIONS:
len = strlen(options.commands[c->optionsptr]);
uip_send(options.commands[c->optionsptr], len);
break;
case STATE_SEND_NLST:
uip_send("NLST\r\n", 6);
break;
case STATE_SEND_RETR:
len = sprintf(uip_appdata, "RETR %s\r\n", c->filename);
uip_send(uip_appdata, len);
break;
case STATE_SEND_CWD:
len = sprintf(uip_appdata, "CWD %s\r\n", c->filename);
uip_send(uip_appdata, len);
break;
case STATE_SEND_CDUP:
uip_send("CDUP\r\n", 6);
break;
case STATE_SEND_QUIT:
uip_send("QUIT\r\n", 6);
break;
}
}
/*---------------------------------------------------------------------------*/
void
ftpc_appcall(void *state)
{
int i, t;
struct ftp_connection *c = (struct ftp_connection *)state;
struct ftp_dataconn *d = (struct ftp_dataconn *)state;
if(uip_connected()) {
if(state == NULL) {
if(waiting_for_dataconn != NULL) {
d = &waiting_for_dataconn->dataconn;
waiting_for_dataconn = NULL;
tcp_markconn(uip_conn, d);
d->filenameptr = 0;
} else {
uip_abort();
}
} else {
/* tcp_listen(uip_conn->lport);*/
senddata(c);
}
return;
}
if(c->type == TYPE_ABORT) {
uip_abort();
return;
}
if(c->type == TYPE_CLOSE) {
uip_close();
c->type = TYPE_CONTROL;
return;
}
if(c->type == TYPE_CONTROL) {
if(uip_closed()) {
c->dataconn.type = TYPE_ABORT;
ftpc_closed();
memb_free(&connections, c);
}
if(uip_aborted()) {
c->dataconn.type = TYPE_ABORT;
ftpc_aborted();
memb_free(&connections, c);
}
if(uip_timedout()) {
c->dataconn.type = TYPE_ABORT;
ftpc_timedout();
memb_free(&connections, c);
}
if(uip_acked()) {
acked(c);
}
if(uip_newdata()) {
newdata(c);
}
if(uip_rexmit() ||
uip_newdata() ||
uip_acked()) {
senddata(c);
} else if(uip_poll()) {
senddata(c);
}
} else {
if(d->conntype == CONNTYPE_LIST) {
if(uip_newdata()) {
for(i = 0; i < uip_datalen(); ++i) {
t = ((char *)uip_appdata)[i];
if(d->filenameptr < sizeof(d->filename) - 1 &&
t != ISO_cr &&
t != ISO_nl) {
d->filename[d->filenameptr] = t;
++d->filenameptr;
}
if(t == ISO_nl) {
d->filename[d->filenameptr] = 0;
ftpc_list_file(d->filename);
d->filenameptr = 0;
}
}
}
if(uip_closed()) {
ftpc_list_file(NULL);
}
} else {
if(uip_newdata()) {
ftpc_data(uip_appdata, uip_datalen());
/* printf("Received %d data bytes: '%s'\n",
uip_datalen(), uip_appdata);*/
} else if(uip_closed() || uip_timedout() || uip_aborted()) {
ftpc_data(NULL, 0);
}
}
}
}
/*---------------------------------------------------------------------------*/
char
ftpc_list(void *conn)
{
struct ftp_connection *c;
c = conn;
if(c == NULL ||
c->state != STATE_CONNECTED) {
return 0;
}
c->state = STATE_SEND_NLST;
c->dataconn.conntype = CONNTYPE_LIST;
waiting_for_dataconn = c;
return 1;
}
/*---------------------------------------------------------------------------*/
char
ftpc_get(void *conn, char *filename)
{
struct ftp_connection *c;
c = conn;
if(c == NULL ||
c->state != STATE_CONNECTED) {
return 0;
}
strncpy(c->filename, filename, sizeof(c->filename));
c->state = STATE_SEND_RETR;
c->dataconn.conntype = CONNTYPE_FILE;
waiting_for_dataconn = c;
return 1;
}
/*---------------------------------------------------------------------------*/
void
ftpc_close(void *conn)
{
struct ftp_connection *c;
c = conn;
if(c == NULL) {
return;
}
c->type = TYPE_CLOSE;
}
/*---------------------------------------------------------------------------*/
void
ftpc_cwd(void *conn, char *dirname)
{
struct ftp_connection *c;
c = conn;
if(c == NULL ||
c->state != STATE_CONNECTED) {
return;
}
strncpy(c->filename, dirname, sizeof(c->filename));
c->state = STATE_SEND_CWD;
}
/*---------------------------------------------------------------------------*/
void
ftpc_cdup(void *conn)
{
struct ftp_connection *c;
c = conn;
if(c == NULL ||
c->state != STATE_CONNECTED) {
return;
}
c->state = STATE_SEND_CDUP;
}
/*---------------------------------------------------------------------------*/

68
apps/ftp/ftpc.h Normal file
View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ftpc.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
#ifndef __FTPC_H__
#define __FTPC_H__
#include "contiki-net.h"
void ftpc_init(void);
void *ftpc_connect(u16_t *ipaddr, u16_t port);
char ftpc_list(void *connection);
void ftpc_cwd(void *connection, char *dir);
void ftpc_cdup(void *connection);
char ftpc_get(void *connection, char *filename);
void ftpc_close(void *connection);
void ftpc_appcall(void *state);
#define FTPC_OK 200
#define FTPC_COMPLETED 250
#define FTPC_NODIR 431
#define FTPC_NOTDIR 550
/* Functions to be implemented by the calling module: */
void ftpc_connected(void *connection);
void ftpc_cwd_done(unsigned short status);
char *ftpc_username(void);
char *ftpc_password(void);
void ftpc_closed(void);
void ftpc_aborted(void);
void ftpc_timedout(void);
void ftpc_list_file(char *filename);
void ftpc_data(u8_t *data, u16_t len);
#endif /* __FTPC_H__ */

3
apps/irc/Makefile.irc Normal file
View file

@ -0,0 +1,3 @@
APP_SOURCES += irc.c ircc.c psock.c uipbuf.c ircc-strings.c \
ctk-textentry-cmdline.c
DSC_SOURCES += irc-dsc.c

74
apps/irc/irc-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: irc-dsc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon irc_icon;
/*-----------------------------------------------------------------------------------*/
DSC(irc_dsc,
"Internet Relay Chat client",
"irc.prg",
irc_process,
&irc_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char irc_icon_bitmap[3*3*8] = {
0x00, 0x79, 0x43, 0x73, 0x47, 0x77, 0x47, 0x6f,
0x00, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xfb,
0x00, 0x16, 0x02, 0x00, 0x02, 0x00, 0x00, 0xc2,
0x48, 0x4c, 0x5f, 0x5f, 0x1f, 0x3f, 0x3f, 0x03,
0x79, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xfe, 0xfc,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x77, 0x47, 0x70, 0x43, 0x79, 0x41, 0x7c, 0x00,
0xfc, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xf7, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x84, 0xf0, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char irc_icon_textmap[9] = {
'I', 'R', 'C',
'-', '-', '-',
'I', 'R', 'C'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon irc_icon =
{CTK_ICON("IRC client", irc_icon_bitmap, irc_icon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/irc/irc-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 OS
*
* $Id: irc-dsc.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#ifndef __IRC_DSC_H__
#define __IRC_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(irc_dsc);
#endif /* __IRC_DSC_H__ */

293
apps/irc/irc.c Normal file
View file

@ -0,0 +1,293 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: irc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
#include "contiki-conf.h"
#include "contiki.h"
#include "contiki-net.h"
#include "ircc.h"
#include "ctk/ctk.h"
#include "lib/ctk-textedit.h"
#include "lib/ctk-textentry-cmdline.h"
#include "lib/petsciiconv.h"
#include <string.h>
#ifdef IRC_CONF_WIDTH
#define LOG_WIDTH IRC_CONF_WIDTH
#else
#define LOG_WIDTH 37
#endif
#ifdef IRC_CONF_HEIGHT
#define LOG_HEIGHT IRC_CONF_HEIGHT
#else
#define LOG_HEIGHT 17
#endif
PROCESS(irc_process, "IRC client");
static struct ctk_window window;
static char log[LOG_WIDTH * LOG_HEIGHT];
static char line[LOG_WIDTH*2];
static struct ctk_label loglabel =
{CTK_LABEL(0, 0, LOG_WIDTH, LOG_HEIGHT, log)};
static struct ctk_textentry lineedit =
{CTK_TEXTENTRY_INPUT(0, LOG_HEIGHT, LOG_WIDTH - 2, 1, line, sizeof(line) - 1,
ctk_textentry_cmdline_input)};
static struct ctk_window setupwindow;
#define SETUPWINDOW_WIDTH 18
#define SETUPWINDOW_HEIGHT 9
#define MAX_SERVERLEN 32
#define MAX_NICKLEN 16
static u16_t serveraddr[2];
static char server[MAX_SERVERLEN + 1];
static char nick[MAX_NICKLEN + 1];
static struct ctk_label serverlabel =
{CTK_LABEL(1, 1, 11, 1, "IRC server: ")};
static struct ctk_textentry serverentry =
{CTK_TEXTENTRY(0, 2, 16, 1, server, MAX_SERVERLEN)};
static struct ctk_label nicklabel =
{CTK_LABEL(1, 4, 13, 1, "IRC nickname: ")};
static struct ctk_textentry nickentry =
{CTK_TEXTENTRY(0, 5, 16, 1, nick, MAX_NICKLEN)};
static struct ctk_button connectbutton =
{CTK_BUTTON(0, 7, 7, "Connect")};
static struct ctk_button quitbutton =
{CTK_BUTTON(12, 7, 4, "Quit")};
/*static char nick[] = "asdf";
static char server[] = "efnet.demon.co.uk";*/
static struct ircc_state s;
/*---------------------------------------------------------------------------*/
static void
quit(void)
{
ctk_window_close(&window);
ctk_window_close(&setupwindow);
process_exit(&irc_process);
LOADER_UNLOAD();
}
/*---------------------------------------------------------------------------*/
void
ircc_text_output(struct ircc_state *s, char *text1, char *text2)
{
char *ptr;
int len;
if(text1 == NULL) {
text1 = "";
}
if(text2 == NULL) {
text2 = "";
}
/* Scroll previous entries upwards */
memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
ptr = &log[LOG_WIDTH * (LOG_HEIGHT - 1)];
len = strlen(text1);
memset(ptr, 0, LOG_WIDTH);
strncpy(ptr, text1, LOG_WIDTH);
if(len < LOG_WIDTH) {
ptr += len;
*ptr = ':';
++len;
if(LOG_WIDTH - len > 0) {
strncpy(ptr + 1, text2, LOG_WIDTH - len);
}
} else {
len = 0;
}
if(strlen(text2) > LOG_WIDTH - len) {
memcpy(log, &log[LOG_WIDTH], LOG_WIDTH * (LOG_HEIGHT - 1));
strncpy(&log[LOG_WIDTH * (LOG_HEIGHT - 1)],
text2 + LOG_WIDTH - len, LOG_WIDTH);
}
CTK_WIDGET_REDRAW(&loglabel);
}
/*---------------------------------------------------------------------------*/
static void
parse_line(void)
{
int i;
for(i = 0; i < strlen(line); ++i) {
line[i] &= 0x7f;
}
if(line[0] == '/') {
if(strncmp(&line[1], "join", 4) == 0) {
ircc_join(&s, &line[6]);
ircc_text_output(&s, "Join", &line[6]);
} else if(strncmp(&line[1], "list", 4) == 0) {
ircc_list(&s);
ircc_text_output(&s, "Channel list", "");
} else if(strncmp(&line[1], "part", 4) == 0) {
ircc_part(&s);
ircc_text_output(&s, "Leaving channel", "");
} else if(strncmp(&line[1], "quit", 4) == 0) {
ircc_quit(&s);
} else if(strncmp(&line[1], "me", 2) == 0) {
petsciiconv_toascii(&line[4], strlen(&line[4]));
ircc_actionmsg(&s, &line[4]);
ircc_text_output(&s, "*", &line[4]);
} else {
ircc_text_output(&s, &line[1], "Not implemented");
ircc_sent(&s);
}
} else {
petsciiconv_toascii(line, sizeof(line) - 1);
ircc_msg(&s, &line[0]);
ircc_text_output(&s, nick, line);
}
}
/*---------------------------------------------------------------------------*/
void
ircc_sent(struct ircc_state *s)
{
/* ctk_textedit_init(&lineedit);*/
CTK_TEXTENTRY_CLEAR(&lineedit);
CTK_WIDGET_REDRAW(&lineedit);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(irc_process, ev, data)
{
ctk_arch_key_t c;
u16_t *ipaddr;
PROCESS_BEGIN();
/* ctk_textedit_init(&lineedit);*/
CTK_TEXTENTRY_CLEAR(&lineedit);
memset(log, 0, sizeof(log));
ctk_window_new(&window, LOG_WIDTH, LOG_HEIGHT + 1, "IRC");
CTK_WIDGET_ADD(&window, &loglabel);
/* ctk_textedit_add(&window, &lineedit); */
CTK_WIDGET_ADD(&window, &lineedit);
CTK_WIDGET_FOCUS(&window, &lineedit);
ctk_window_new(&setupwindow, SETUPWINDOW_WIDTH, SETUPWINDOW_HEIGHT,
"IRC setup");
CTK_WIDGET_ADD(&setupwindow, &serverlabel);
CTK_WIDGET_ADD(&setupwindow, &serverentry);
CTK_WIDGET_ADD(&setupwindow, &nicklabel);
CTK_WIDGET_ADD(&setupwindow, &nickentry);
CTK_WIDGET_ADD(&setupwindow, &connectbutton);
CTK_WIDGET_ADD(&setupwindow, &quitbutton);
CTK_WIDGET_FOCUS(&setupwindow, &serverentry);
ctk_window_open(&setupwindow);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == PROCESS_EVENT_EXIT) {
quit();
} else if(ev == ctk_signal_window_close) {
quit();
} else if(ev == tcpip_event) {
ircc_appcall(data);
} else if(ev == ctk_signal_widget_activate) {
if(data == (process_data_t)&lineedit) {
parse_line();
} else if(data == (process_data_t)&quitbutton) {
quit();
} else if(data == (process_data_t)&connectbutton) {
ctk_window_close(&setupwindow);
ctk_window_open(&window);
ipaddr = serveraddr;
if(uiplib_ipaddrconv(server, (u8_t *)serveraddr) == 0) {
ipaddr = resolv_lookup(server);
if(ipaddr == NULL) {
resolv_query(server);
} else {
uip_ipaddr_copy(serveraddr, ipaddr);
}
}
if(ipaddr != NULL) {
ircc_connect(&s, server, serveraddr, nick);
}
}
} else if(ev == resolv_event_found) {
ipaddr = resolv_lookup(server);
if(ipaddr == NULL) {
ircc_text_output(&s, server, "hostname not found");
} else {
uip_ipaddr_copy(serveraddr, ipaddr);
ircc_connect(&s, server, serveraddr, nick);
}
} else if(ev == ctk_signal_keypress) {
c = (ctk_arch_key_t)data;
if(c == CH_ENTER) {
parse_line();
} else {
/* ctk_textedit_eventhandler(&lineedit, ev, data);*/
CTK_WIDGET_FOCUS(&window, &lineedit);
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
ircc_closed(struct ircc_state *s)
{
ircc_text_output(s, server, "connection closed");
}
/*---------------------------------------------------------------------------*/
void
ircc_connected(struct ircc_state *s)
{
ircc_text_output(s, server, "connected");
}
/*---------------------------------------------------------------------------*/

17
apps/irc/ircc-strings Normal file
View file

@ -0,0 +1,17 @@
ircc_strings_nick "NICK "
ircc_strings_crnl_user "\r\nUSER "
ircc_strings_contiki " contiki "
ircc_strings_colon_contiki " :Contiki\r\n"
ircc_strings_join "JOIN "
ircc_strings_crnl "\r\n"
ircc_strings_part "PART "
ircc_strings_list "LIST "
ircc_strings_privmsg "PRIVMSG "
ircc_strings_colon " :"
ircc_strings_ping "PING "
ircc_strings_notice "NOTICE "
ircc_strings_action "\01ACTION "
ircc_strings_version "\01VERSION"
ircc_strings_version_query "\01VERSION\01"
ircc_strings_ctcpcrnl "\01\r\n"
ircc_strings_version_string " Contiki 1.2-devel1 "

51
apps/irc/ircc-strings.c Normal file
View file

@ -0,0 +1,51 @@
const char ircc_strings_nick[6] =
/* "NICK " */
{0x4e, 0x49, 0x43, 0x4b, 0x20, };
const char ircc_strings_crnl_user[8] =
/* "\r\nUSER " */
{0xd, 0xa, 0x55, 0x53, 0x45, 0x52, 0x20, };
const char ircc_strings_contiki[10] =
/* " contiki " */
{0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x20, };
const char ircc_strings_colon_contiki[12] =
/* " :Contiki\r\n" */
{0x20, 0x3a, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0xd, 0xa, };
const char ircc_strings_join[6] =
/* "JOIN " */
{0x4a, 0x4f, 0x49, 0x4e, 0x20, };
const char ircc_strings_crnl[3] =
/* "\r\n" */
{0xd, 0xa, };
const char ircc_strings_part[6] =
/* "PART " */
{0x50, 0x41, 0x52, 0x54, 0x20, };
const char ircc_strings_list[6] =
/* "LIST " */
{0x4c, 0x49, 0x53, 0x54, 0x20, };
const char ircc_strings_privmsg[9] =
/* "PRIVMSG " */
{0x50, 0x52, 0x49, 0x56, 0x4d, 0x53, 0x47, 0x20, };
const char ircc_strings_colon[3] =
/* " :" */
{0x20, 0x3a, };
const char ircc_strings_ping[6] =
/* "PING " */
{0x50, 0x49, 0x4e, 0x47, 0x20, };
const char ircc_strings_notice[8] =
/* "NOTICE " */
{0x4e, 0x4f, 0x54, 0x49, 0x43, 0x45, 0x20, };
const char ircc_strings_action[9] =
/* "\01ACTION " */
{0x1, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x20, };
const char ircc_strings_version[9] =
/* "\01VERSION" */
{0x1, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, };
const char ircc_strings_version_query[10] =
/* "\01VERSION\01" */
{0x1, 0x56, 0x45, 0x52, 0x53, 0x49, 0x4f, 0x4e, 0x1, };
const char ircc_strings_ctcpcrnl[4] =
/* "\01\r\n" */
{0x1, 0xd, 0xa, };
const char ircc_strings_version_string[14] =
/* " Contiki 1.2 " */
{0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x20, 0x31, 0x2e, 0x32, 0x20, };

17
apps/irc/ircc-strings.h Normal file
View file

@ -0,0 +1,17 @@
extern const char ircc_strings_nick[6];
extern const char ircc_strings_crnl_user[8];
extern const char ircc_strings_contiki[10];
extern const char ircc_strings_colon_contiki[12];
extern const char ircc_strings_join[6];
extern const char ircc_strings_crnl[3];
extern const char ircc_strings_part[6];
extern const char ircc_strings_list[6];
extern const char ircc_strings_privmsg[9];
extern const char ircc_strings_colon[3];
extern const char ircc_strings_ping[6];
extern const char ircc_strings_notice[8];
extern const char ircc_strings_action[9];
extern const char ircc_strings_version[9];
extern const char ircc_strings_version_query[10];
extern const char ircc_strings_ctcpcrnl[4];
extern const char ircc_strings_version_string[14];

531
apps/irc/ircc.c Normal file
View file

@ -0,0 +1,531 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ircc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
#include "contiki.h"
#include "ircc.h"
#include "ircc-strings.h"
#include "lib/petsciiconv.h"
#include <string.h>
#ifdef IRC_CONF_SYSTEM_STRING
#define IRC_SYSTEM_STRING IRC_CONF_SYSTEM_STRING
#else
#define IRC_SYSTEM_STRING "Contiki"
#endif
#define PORT 6667
#define SEND_STRING(s, str) PSOCK_SEND(s, str, strlen(str))
#define ISO_space 0x20
#define ISO_bang 0x21
#define ISO_at 0x40
#define ISO_cr 0x0d
#define ISO_nl 0x0a
#define ISO_colon 0x3a
#define ISO_O 0x4f
enum {
COMMAND_NONE,
COMMAND_JOIN,
COMMAND_PART,
COMMAND_MSG,
COMMAND_ACTIONMSG,
COMMAND_LIST,
COMMAND_QUIT
};
/*---------------------------------------------------------------------------*/
void
ircc_init(void)
{
}
/*---------------------------------------------------------------------------*/
static char *
copystr(char *dest, const char *src, int n)
{
int len;
len = strlen(src);
strncpy(dest, src, n);
if(len > n) {
return dest + n;
} else {
return dest + len;
}
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(setup_connection(struct ircc_state *s))
{
char *ptr;
PSOCK_BEGIN(&s->s);
ptr = s->outputbuf;
ptr = copystr(ptr, ircc_strings_nick, sizeof(s->outputbuf));
ptr = copystr(ptr, s->nick, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_crnl_user, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, s->nick, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_contiki, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, s->server, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_colon_contiki, sizeof(s->outputbuf) - (ptr - s->outputbuf));
SEND_STRING(&s->s, s->outputbuf);
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(join_channel(struct ircc_state *s))
{
PSOCK_BEGIN(&s->s);
SEND_STRING(&s->s, ircc_strings_join);
SEND_STRING(&s->s, s->channel);
SEND_STRING(&s->s, ircc_strings_crnl);
ircc_sent(s);
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(part_channel(struct ircc_state *s))
{
PSOCK_BEGIN(&s->s);
SEND_STRING(&s->s, ircc_strings_part);
SEND_STRING(&s->s, s->channel);
SEND_STRING(&s->s, ircc_strings_crnl);
ircc_sent(s);
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(list_channel(struct ircc_state *s))
{
PSOCK_BEGIN(&s->s);
SEND_STRING(&s->s, ircc_strings_list);
SEND_STRING(&s->s, s->channel);
SEND_STRING(&s->s, ircc_strings_crnl);
ircc_sent(s);
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_message(struct ircc_state *s))
{
char *ptr;
PSOCK_BEGIN(&s->s);
ptr = s->outputbuf;
ptr = copystr(ptr, ircc_strings_privmsg, sizeof(s->outputbuf));
ptr = copystr(ptr, s->channel, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_colon, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, s->msg, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_crnl, sizeof(s->outputbuf) - (ptr - s->outputbuf));
SEND_STRING(&s->s, s->outputbuf);
ircc_sent(s);
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(send_actionmessage(struct ircc_state *s))
{
char *ptr;
PSOCK_BEGIN(&s->s);
ptr = s->outputbuf;
ptr = copystr(ptr, ircc_strings_privmsg, sizeof(s->outputbuf));
ptr = copystr(ptr, s->channel, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_colon, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_action, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, s->msg, sizeof(s->outputbuf) - (ptr - s->outputbuf));
ptr = copystr(ptr, ircc_strings_ctcpcrnl, sizeof(s->outputbuf) - (ptr - s->outputbuf));
SEND_STRING(&s->s, s->outputbuf);
ircc_sent(s);
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
struct parse_result {
char *msg;
char *user;
char *host;
char *name;
char *command;
char *middle;
char *trailing;
};
static struct parse_result r;
static void
parse_whitespace(void)
{
while(*r.msg == ISO_space) ++r.msg;
}
static void
parse_word(void)
{
char *ptr;
ptr = strchr(r.msg, ISO_space);
if(ptr != NULL) {
r.msg = ptr;
}
}
static void
parse_user(void)
{
parse_whitespace();
r.user = r.msg;
parse_word();
*r.msg = 0;
++r.msg;
}
static void
parse_host(void)
{
parse_whitespace();
r.host = r.msg;
parse_word();
*r.msg = 0;
++r.msg;
}
static void
parse_name(void)
{
parse_whitespace();
r.name = r.msg;
parse_word();
*r.msg = 0;
++r.msg;
}
static void
parse_prefix(void)
{
parse_name();
if(*r.msg == ISO_bang) {
++r.msg;
parse_user();
}
if(*r.msg == ISO_at) {
++r.msg;
parse_host();
}
}
static void
parse_command(void)
{
parse_whitespace();
r.command = r.msg;
parse_word();
*r.msg = 0;
++r.msg;
}
/*static void
parse_trailing(void)
{
r.trailing = r.msg;
while(*r.msg != 0 && *r.msg != ISO_cr && *r.msg != ISO_nl) ++r.msg;
*r.msg = 0;
++r.msg;
}*/
static void
parse_params(void)
{
char *ptr;
parse_whitespace();
ptr = strchr(r.msg, ISO_colon);
if(ptr != NULL) {
r.trailing = ptr + 1;
ptr = strchr(ptr, ISO_cr);
if(ptr != NULL) {
*ptr = 0;
}
}
}
static void
parse(char *msg, struct parse_result *dummy)
{
r.msg = msg;
if(*r.msg == ISO_cr || *r.msg == ISO_nl) {
return;
}
if(*r.msg == ISO_colon) {
++r.msg;
parse_prefix();
}
parse_command();
parse_params();
/* printf("user %s host %s name %s command %s middle %s trailing %s\n",
r.user, r.host, r.name, r.command, r.middle, r.trailing);*/
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_input(struct ircc_state *s))
{
char *ptr;
/* struct parse_result r;*/
PSOCK_BEGIN(&s->s);
PSOCK_READTO(&s->s, ISO_nl);
if(PSOCK_DATALEN(&s->s) > 0) {
s->inputbuf[PSOCK_DATALEN(&s->s)] = 0;
if(strncmp(s->inputbuf, ircc_strings_ping, 5) == 0) {
strncpy(s->outputbuf, s->inputbuf, sizeof(s->outputbuf));
/* Turn "PING" into "PONG" */
s->outputbuf[1] = ISO_O;
SEND_STRING(&s->s, s->outputbuf);
} else {
memset(&r, 0, sizeof(r));
parse(s->inputbuf, &r);
if(r.name != NULL) {
ptr = strchr(r.name, ISO_bang);
if(ptr != NULL) {
*ptr = 0;
}
}
if(r.command != NULL && strncmp(r.command, ircc_strings_join, 4) == 0) {
ircc_text_output(s, "Joined channel", r.name);
} else if(r.command != NULL && strncmp(r.command, ircc_strings_part, 4) == 0) {
ircc_text_output(s, "Left channel", r.name);
} else if(r.trailing != NULL) {
if(strncmp(r.trailing, ircc_strings_action,
strlen(ircc_strings_action)) == 0) {
ptr = strchr(&r.trailing[1], 1);
if(ptr != NULL) {
*ptr = 0;
}
ptr = &r.trailing[strlen(ircc_strings_action)];
petsciiconv_topetscii(r.name, strlen(r.name));
petsciiconv_topetscii(ptr, strlen(ptr));
ircc_text_output(s, r.name, ptr);
} else if(strncmp(r.trailing, ircc_strings_version_query,
strlen(ircc_strings_version_query)) == 0) {
if(r.name != NULL) {
strncpy(s->outputbuf, r.name, sizeof(s->outputbuf));
SEND_STRING(&s->s, ircc_strings_notice);
/* user is temporarily stored in outputbuf. */
SEND_STRING(&s->s, s->outputbuf);
SEND_STRING(&s->s, ircc_strings_colon);
SEND_STRING(&s->s, ircc_strings_version);
SEND_STRING(&s->s, ircc_strings_version_string);
SEND_STRING(&s->s, IRC_SYSTEM_STRING);
SEND_STRING(&s->s, ircc_strings_ctcpcrnl);
}
} else {
petsciiconv_topetscii(r.name, strlen(r.name));
petsciiconv_topetscii(r.trailing, strlen(r.trailing));
ircc_text_output(s, r.name, r.trailing);
}
}
}
}
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(data_or_command(struct ircc_state *s))
{
PSOCK_BEGIN(&s->s);
PSOCK_WAIT_UNTIL(&s->s, PSOCK_NEWDATA(&s->s) ||
(s->command != COMMAND_NONE));
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_connection(struct ircc_state *s))
{
PT_BEGIN(&s->pt);
PSOCK_INIT(&s->s, s->inputbuf, sizeof(s->inputbuf) - 1);
PT_WAIT_THREAD(&s->pt, setup_connection(s));
while(1) {
PT_WAIT_UNTIL(&s->pt, data_or_command(s));
if(PSOCK_NEWDATA(&s->s)) {
PT_WAIT_THREAD(&s->pt, handle_input(s));
}
switch(s->command) {
case COMMAND_JOIN:
s->command = COMMAND_NONE;
PT_WAIT_THREAD(&s->pt, join_channel(s));
break;
case COMMAND_PART:
s->command = COMMAND_NONE;
PT_WAIT_THREAD(&s->pt, part_channel(s));
break;
case COMMAND_MSG:
s->command = COMMAND_NONE;
PT_WAIT_THREAD(&s->pt, send_message(s));
break;
case COMMAND_ACTIONMSG:
s->command = COMMAND_NONE;
PT_WAIT_THREAD(&s->pt, send_actionmessage(s));
break;
case COMMAND_LIST:
s->command = COMMAND_NONE;
PT_WAIT_THREAD(&s->pt, list_channel(s));
break;
case COMMAND_QUIT:
s->command = COMMAND_NONE;
tcp_markconn(uip_conn, NULL);
PSOCK_CLOSE(&s->s);
process_post(PROCESS_CURRENT(), PROCESS_EVENT_EXIT, NULL);
PT_EXIT(&s->pt);
break;
default:
break;
}
}
PT_END(&s->pt);
}
/*---------------------------------------------------------------------------*/
void
ircc_appcall(void *s)
{
if(uip_closed() || uip_aborted() || uip_timedout()) {
ircc_closed(s);
} else if(uip_connected()) {
ircc_connected(s);
PT_INIT(&((struct ircc_state *)s)->pt);
memset(((struct ircc_state *)s)->channel, 0,
sizeof(((struct ircc_state *)s)->channel));
((struct ircc_state *)s)->command = COMMAND_NONE;
handle_connection(s);
} else if(s != NULL) {
handle_connection(s);
}
}
/*---------------------------------------------------------------------------*/
struct ircc_state *
ircc_connect(struct ircc_state *s, char *servername, u16_t *ipaddr,
char *nick)
{
s->conn = tcp_connect(ipaddr, HTONS(PORT), s);
if(s->conn == NULL) {
return NULL;
}
s->server = servername;
s->nick = nick;
return s;
}
/*---------------------------------------------------------------------------*/
void
ircc_list(struct ircc_state *s)
{
s->command = COMMAND_LIST;
}
/*---------------------------------------------------------------------------*/
void
ircc_join(struct ircc_state *s, char *channel)
{
strncpy(s->channel, channel, sizeof(s->channel));
s->command = COMMAND_JOIN;
}
/*---------------------------------------------------------------------------*/
void
ircc_part(struct ircc_state *s)
{
s->command = COMMAND_PART;
}
/*---------------------------------------------------------------------------*/
void
ircc_quit(struct ircc_state *s)
{
s->command = COMMAND_QUIT;
}
/*---------------------------------------------------------------------------*/
void
ircc_msg(struct ircc_state *s, char *msg)
{
s->msg = msg;
s->command = COMMAND_MSG;
}
/*---------------------------------------------------------------------------*/
void
ircc_actionmsg(struct ircc_state *s, char *msg)
{
s->msg = msg;
s->command = COMMAND_ACTIONMSG;
}
/*---------------------------------------------------------------------------*/

79
apps/irc/ircc.h Normal file
View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: ircc.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*/
#ifndef __IRCC_H__
#define __IRCC_H__
#include "contiki-net.h"
struct ircc_state {
struct pt pt;
struct psock s;
struct uip_conn *conn;
unsigned char command;
char *msg;
char channel[32];
char outputbuf[200];
char inputbuf[400];
char *nick;
char *server;
};
void ircc_init(void);
void ircc_appcall(void *s);
struct ircc_state *ircc_connect(struct ircc_state *s,
char *server, u16_t *ipaddr, char *nick);
void ircc_join(struct ircc_state *s, char *channel);
void ircc_part(struct ircc_state *s);
void ircc_list(struct ircc_state *s);
void ircc_msg(struct ircc_state *s, char *msg);
void ircc_actionmsg(struct ircc_state *s, char *msg);
void ircc_sent(struct ircc_state *s);
void ircc_text_output(struct ircc_state *s, char *text1, char *text2);
void ircc_connected(struct ircc_state *s);
void ircc_closed(struct ircc_state *s);
void ircc_quit(struct ircc_state *s);
#endif /* __IRCC_H__ */

View file

@ -0,0 +1,2 @@
APP_SOURCES += netconf.c
DSC_SOURCES += netconf-dsc.c

View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: netconf-dsc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon netconf_icon;
/*-----------------------------------------------------------------------------------*/
DSC(netconf_dsc,
"Network configuration",
"netconf.prg",
netconf_process,
&netconf_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char tcpipconficon_bitmap[3*3*8] = {
0x00, 0x79, 0x43, 0x73, 0x47, 0x77, 0x47, 0x6f,
0x00, 0xfe, 0xfe, 0xfc, 0xfc, 0xfc, 0xf8, 0xfb,
0x00, 0x16, 0x02, 0x00, 0x02, 0x00, 0x00, 0xc2,
0x48, 0x4c, 0x5f, 0x5f, 0x1f, 0x3f, 0x3f, 0x03,
0x79, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xfe, 0xfc,
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x77, 0x47, 0x70, 0x43, 0x79, 0x41, 0x7c, 0x00,
0xfc, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xf7, 0x00,
0x00, 0x80, 0x00, 0x00, 0x00, 0x84, 0xf0, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char tcpipconficon_textmap[9] = {
'T', 'C', 'P',
'/', 'I', 'P',
'C', 'f', 'g'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon netconf_icon =
{CTK_ICON("Network setup", tcpipconficon_bitmap, tcpipconficon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: netconf-dsc.h,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#ifndef __NETCONF_DSC_H__
#define __NETCONF_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(netconf_dsc);
#endif /* __NETCONF_DSC_H__ */

246
apps/netconf/netconf.c Normal file
View file

@ -0,0 +1,246 @@
/*
* Copyright (c) 2002, 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 environment
*
* $Id: netconf.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $
*
*/
#include "contiki-net.h"
#include "ctk/ctk.h"
/* TCP/IP configuration window. */
static struct ctk_window tcpipwindow;
#ifdef WITH_ETHERNET
static struct ctk_label ipaddrlabel =
{CTK_LABEL(0, 1, 10, 1, "IP address")};
static char ipaddr[17];
static struct ctk_textentry ipaddrtextentry =
{CTK_TEXTENTRY(11, 1, 16, 1, ipaddr, 16)};
static struct ctk_label netmasklabel =
{CTK_LABEL(0, 3, 10, 1, "Netmask")};
static char netmask[17];
static struct ctk_textentry netmasktextentry =
{CTK_TEXTENTRY(11, 3, 16, 1, netmask, 16)};
static struct ctk_label gatewaylabel =
{CTK_LABEL(0, 5, 10, 1, "Gateway")};
static char gateway[17];
static struct ctk_textentry gatewaytextentry =
{CTK_TEXTENTRY(11, 5, 16, 1, gateway, 16)};
static struct ctk_label dnsserverlabel =
{CTK_LABEL(0, 7, 10, 1, "DNS server")};
static char dnsserver[17];
static struct ctk_textentry dnsservertextentry =
{CTK_TEXTENTRY(11, 7, 16, 1, dnsserver, 16)};
#else /* WITH_ETHERNET */
static struct ctk_label ipaddrlabel =
{CTK_LABEL(0, 2, 10, 1, "IP address")};
static char ipaddr[17];
static struct ctk_textentry ipaddrtextentry =
{CTK_TEXTENTRY(11, 2, 16, 1, ipaddr, 16)};
static struct ctk_label dnsserverlabel =
{CTK_LABEL(0, 4, 10, 1, "DNS server")};
static char dnsserver[17];
static struct ctk_textentry dnsservertextentry =
{CTK_TEXTENTRY(11, 4, 16, 1, dnsserver, 16)};
#endif /* WITH_ETHERNET */
static struct ctk_button tcpipclosebutton =
{CTK_BUTTON(0, 9, 2, "Ok")};
PROCESS(netconf_process, "Network configurator");
static void makestrings(void);
/*-----------------------------------------------------------------------------------*/
static char *
makebyte(u8_t byte, char *str)
{
if(byte >= 100) {
*str++ = (byte / 100 ) % 10 + '0';
}
if(byte >= 10) {
*str++ = (byte / 10) % 10 + '0';
}
*str++ = (byte % 10) + '0';
return str;
}
/*-----------------------------------------------------------------------------------*/
static void
makeaddr(u16_t *addr, char *str)
{
str = makebyte(HTONS(addr[0]) >> 8, str);
*str++ = '.';
str = makebyte(HTONS(addr[0]) & 0xff, str);
*str++ = '.';
str = makebyte(HTONS(addr[1]) >> 8, str);
*str++ = '.';
str = makebyte(HTONS(addr[1]) & 0xff, str);
*str++ = 0;
}
/*-----------------------------------------------------------------------------------*/
static void
makestrings(void)
{
u16_t addr[2], *addrptr;
#ifdef WITH_UIP
uip_gethostaddr(addr);
makeaddr(addr, ipaddr);
#ifdef WITH_ETHERNET
uip_getnetmask(addr);
makeaddr(addr, netmask);
uip_getdraddr(addr);
makeaddr(addr, gateway);
#endif /* WITH_ETHERNET */
addrptr = resolv_getserver();
if(addrptr != NULL) {
makeaddr(addrptr, dnsserver);
}
#endif /* WITH_UIP */
}
/*-----------------------------------------------------------------------------------*/
static void
nullterminate(char *cptr)
{
/* Find the first space character in the ipaddr and put a zero there
to end the string. */
for(; *cptr != ' ' && *cptr != 0; ++cptr);
*cptr = 0;
}
/*-----------------------------------------------------------------------------------*/
static void
apply_tcpipconfig(void)
{
u16_t addr[2];
#ifdef WITH_UIP
nullterminate(ipaddr);
if(uiplib_ipaddrconv(ipaddr, (unsigned char *)addr)) {
uip_sethostaddr(addr);
}
#ifdef WITH_ETHERNET
nullterminate(netmask);
if(uiplib_ipaddrconv(netmask, (unsigned char *)addr)) {
uip_setnetmask(addr);
}
nullterminate(gateway);
if(uiplib_ipaddrconv(gateway, (unsigned char *)addr)) {
uip_setdraddr(addr);
}
#endif /* WITH_ETHERNET */
nullterminate(dnsserver);
if(uiplib_ipaddrconv(dnsserver, (unsigned char *)addr)) {
resolv_conf(addr);
}
#endif /* WITH_UIP */
}
/*-----------------------------------------------------------------------------------*/
static void
netconf_quit(void)
{
process_exit(&netconf_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(netconf_process, ev, data)
{
PROCESS_BEGIN();
/* Create TCP/IP configuration window. */
ctk_window_new(&tcpipwindow, 30, 10, "TCP/IP config");
/* if(ctk_desktop_width(tcpipwindow.desktop) < 30) {
ctk_window_move(&tcpipwindow, 0,
(ctk_desktop_height(tcpipwindow.desktop) - 10) / 2 - 2);
} else {
ctk_window_move(&tcpipwindow,
(ctk_desktop_width(tcpipwindow.desktop) - 30) / 2,
(ctk_desktop_height(tcpipwindow.desktop) - 10) / 2 - 2);
}*/
#ifdef WITH_ETHERNET
CTK_WIDGET_ADD(&tcpipwindow, &ipaddrlabel);
CTK_WIDGET_ADD(&tcpipwindow, &ipaddrtextentry);
CTK_WIDGET_ADD(&tcpipwindow, &netmasklabel);
CTK_WIDGET_ADD(&tcpipwindow, &netmasktextentry);
CTK_WIDGET_ADD(&tcpipwindow, &gatewaylabel);
CTK_WIDGET_ADD(&tcpipwindow, &gatewaytextentry);
CTK_WIDGET_ADD(&tcpipwindow, &dnsserverlabel);
CTK_WIDGET_ADD(&tcpipwindow, &dnsservertextentry);
#else
CTK_WIDGET_ADD(&tcpipwindow, &ipaddrlabel);
CTK_WIDGET_ADD(&tcpipwindow, &ipaddrtextentry);
CTK_WIDGET_ADD(&tcpipwindow, &dnsserverlabel);
CTK_WIDGET_ADD(&tcpipwindow, &dnsservertextentry);
#endif /* WITH_ETHERNET */
CTK_WIDGET_ADD(&tcpipwindow, &tcpipclosebutton);
CTK_WIDGET_FOCUS(&tcpipwindow, &ipaddrtextentry);
/* Fill the configuration strings with values from the current
configuration */
makestrings();
ctk_window_open(&tcpipwindow);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == ctk_signal_button_activate) {
if(data == (process_data_t)&tcpipclosebutton) {
apply_tcpipconfig();
ctk_window_close(&tcpipwindow);
netconf_quit();
/* ctk_desktop_redraw(tcpipwindow.desktop);*/
}
} else if(ev == ctk_signal_window_close ||
ev == PROCESS_EVENT_EXIT) {
ctk_window_close(&tcpipwindow);
netconf_quit();
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,2 @@
APP_SOURCES += process-list.c
DSC_SOURCES += process-list-dsc.c

View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: process-list-dsc.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon processes_icon;
/*-----------------------------------------------------------------------------------*/
DSC(processes_dsc,
"Process information",
"processes.prg",
processes_process,
&processes_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char processesicon_bitmap[3*3*8] = {
0x00, 0x7f, 0x43, 0x4c, 0x58, 0x53, 0x60, 0x6f,
0x00, 0xff, 0x00, 0x7e, 0x00, 0xff, 0x00, 0xff,
0x00, 0xfe, 0xc2, 0x32, 0x1a, 0xca, 0x06, 0xf6,
0x40, 0x5f, 0x40, 0x5f, 0x40, 0x5f, 0x40, 0x4f,
0x00, 0xff, 0x00, 0xff, 0x00, 0xfc, 0x01, 0xf3,
0x02, 0xfa, 0x02, 0x82, 0x3e, 0xfe, 0xfe, 0xfe,
0x60, 0x67, 0x50, 0x59, 0x4c, 0x43, 0x7f, 0x00,
0x07, 0xe7, 0x0f, 0xef, 0x0f, 0x0f, 0xff, 0x00,
0x8e, 0x06, 0x06, 0x06, 0x8e, 0xfe, 0xfe, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char processesicon_textmap[9] = {
'0', '1', ' ',
' ', '0', '1',
'1', '0', '/'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon processes_icon =
{CTK_ICON("Processes", processesicon_bitmap, processesicon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: process-list-dsc.h,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#ifndef __PROCESSES_DSC_H__
#define __PROCESSES_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(processes_dsc);
#endif /* __PROCESSES_DSC_H__ */

View file

@ -0,0 +1,194 @@
/*
* Copyright (c) 2002, 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 environment
*
* $Id: process-list.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include "ctk/ctk.h"
#include "contiki.h"
#include <string.h>
#define MAX_PROCESSLABELS 13
static struct ctk_window processwindow;
static unsigned char ids[MAX_PROCESSLABELS][4];
static struct ctk_label processidlabels[MAX_PROCESSLABELS];
static struct ctk_label processnamelabels[MAX_PROCESSLABELS];
static struct ctk_label killlabel =
{CTK_LABEL(0, 14, 12, 1, "Kill process")};
static char killprocnum[4];
static struct ctk_textentry killtextentry =
{CTK_TEXTENTRY(13, 14, 3, 1, killprocnum, 3)};
static struct ctk_button killbutton =
{CTK_BUTTON(19, 14, 2, "Ok")};
static struct ctk_button processupdatebutton =
{CTK_BUTTON(0, 15, 6, "Update")};
static struct ctk_button processclosebutton =
{CTK_BUTTON(19, 15, 5, "Close")};
PROCESS(processes_process, "Process listing");
enum {
EVENT_UPDATE
};
/*-----------------------------------------------------------------------------------*/
static void
update_processwindow(void)
{
unsigned char i, j, *idsptr;
struct process *p;
/* Step through each possible process ID and see if there is a
matching process. */
j = 0;
for(p = PROCESS_LIST(); p != NULL && j < MAX_PROCESSLABELS; p = p->next) {
idsptr = ids[j];
i = (int)&p;
idsptr[0] = '0' + i / 100;
if(idsptr[0] == '0') {
idsptr[0] = ' ';
}
idsptr[1] = '0' + (i / 10) % 10;
idsptr[2] = '0' + i % 10;
idsptr[3] = 0;
CTK_LABEL_NEW(&processidlabels[j],
0, j + 1, 3, 1, idsptr);
CTK_WIDGET_ADD(&processwindow, &processidlabels[j]);
CTK_LABEL_NEW(&processnamelabels[j],
4, j + 1, 22, 1, (char *)p->name);
CTK_WIDGET_ADD(&processwindow, &processnamelabels[j]);
++j;
}
CTK_WIDGET_ADD(&processwindow, &killlabel);
CTK_WIDGET_ADD(&processwindow, &killtextentry);
CTK_WIDGET_ADD(&processwindow, &killbutton);
CTK_WIDGET_ADD(&processwindow, &processupdatebutton);
CTK_WIDGET_ADD(&processwindow, &processclosebutton);
CTK_WIDGET_FOCUS(&processwindow, &processupdatebutton);
}
/*-----------------------------------------------------------------------------------*/
static void
processes_quit(void)
{
process_exit(&processes_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
static void
killproc(void)
{
#if 0
int procnum;
unsigned char i, j;
struct ek_proc *p;
/* Find first zero char in killprocnum string. */
for(i = 0; killprocnum[i] != 0 &&
i < sizeof(killprocnum); ++i);
if(i == 0) {
return;
}
procnum = 0;
for(j = 0; j < i; ++j) {
procnum = procnum * 10 + (killprocnum[j] - '0');
killprocnum[j] = 0;
}
/* Make sure the process ID exists. */
for(p = EK_PROCS(); p != NULL; p = p->next) {
if(EK_PROC_ID(p) == procnum) {
break;
}
}
if(p != NULL) {
/* ek_post(procnum, EK_EVENT_REQUEST_EXIT, NULL);
ek_post(id, EVENT_UPDATE, NULL);*/
CTK_TEXTENTRY_CLEAR(&killtextentry);
CTK_WIDGET_REDRAW(&killtextentry);
CTK_WIDGET_FOCUS(&processwindow, &processupdatebutton);
CTK_WIDGET_REDRAW(&killbutton);
CTK_WIDGET_REDRAW(&processupdatebutton);
}
#endif
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(processes_process, ev, data)
{
PROCESS_BEGIN();
ctk_window_new(&processwindow, 26, 16, "Processes");
update_processwindow();
ctk_window_open(&processwindow);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == EVENT_UPDATE) {
ctk_window_clear(&processwindow);
update_processwindow();
ctk_window_open(&processwindow);
} else if(ev == ctk_signal_button_activate) {
if(data == (process_data_t)&processupdatebutton) {
ctk_window_clear(&processwindow);
update_processwindow();
ctk_window_open(&processwindow);
} else if(data == (process_data_t)&processclosebutton) {
ctk_window_close(&processwindow);
processes_quit();
/* ctk_desktop_redraw(processwindow.desktop); */
} else if(data == (process_data_t)&killbutton) {
killproc();
}
} else if(ev == PROCESS_EVENT_EXIT ||
(ev == ctk_signal_window_close &&
data == (process_data_t)&processwindow)) {
ctk_window_close(&processwindow);
processes_quit();
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,2 @@
APP_SOURCES += program-handler.c
DSC_SOURCES +=

View file

@ -0,0 +1,385 @@
/**
* \file
* The program handler, used for loading programs and starting the
* screensaver.
* \author Adam Dunkels <adam@dunkels.com>
*
* The Contiki program handler is responsible for the Contiki menu and
* the desktop icons, as well as for loading programs and displaying a
* dialog with a message telling which program that is loading.
*
* The program handler also is responsible for starting the
* screensaver when the CTK detects that it should be started.
*/
/*
* 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: program-handler.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include <string.h>
#include "contiki.h"
#include "ctk/ctk.h"
#include "ctk/ctk-draw.h"
#include "program-handler.h"
/* Menus */
static struct ctk_menu contikimenu;
#ifndef PROGRAM_HANDLER_CONF_MAX_NUMDSCS
#define MAX_NUMDSCS 10
#else /* PROGRAM_HANDLER_CONF_MAX_NUMDSCS */
#define MAX_NUMDSCS PROGRAM_HANDLER_CONF_MAX_NUMDSCS
#endif /* PROGRAM_HANDLER_CONF_MAX_NUMDSCS */
static struct dsc *contikidsc[MAX_NUMDSCS];
static unsigned char contikidsclast = 0;
#if WITH_LOADER_ARCH
/* "Run..." window */
static struct ctk_window runwindow;
static unsigned char runmenuitem;
static struct ctk_label namelabel =
{CTK_LABEL(0, 0, 13, 1, "Program name:")};
static char name[31];
static struct ctk_textentry nameentry =
{CTK_TEXTENTRY(0, 1, 14, 1, name, 30)};
static struct ctk_button loadbutton =
{CTK_BUTTON(10, 2, 4, "Load")};
static struct ctk_window loadingdialog;
static struct ctk_label loadingmsg =
{CTK_LABEL(0, 0, 8, 1, "Starting")};
static struct ctk_label loadingname =
{CTK_LABEL(9, 0, 16, 1, name)};
static struct ctk_window errordialog;
static struct ctk_label errormsg =
{CTK_LABEL(0, 1, 22, 1, "Error loading program:")};
static char errorfilename[22];
static struct ctk_label errorfilelabel =
{CTK_LABEL(0, 3, 22, 1, errorfilename)};
static struct ctk_label errortype =
{CTK_LABEL(4, 5, 16, 1, "")};
static struct ctk_button errorokbutton =
{CTK_BUTTON(9, 7, 2, "Ok")};
#endif /* WITH_LOADER_ARCH */
PROCESS(program_handler_process, "Program handler");
static const char * const errormsgs[] = {
"Ok",
"Read error",
"Header error",
"OS error",
"Data format error",
"Out of memory",
"File not found",
"No loader"
};
#define LOADER_EVENT_LOAD 1
#define LOADER_EVENT_DISPLAY_NAME 2
static char *displayname;
#if CTK_CONF_SCREENSAVER
char program_handler_screensaver[20];
#endif /* CTK_CONF_SCREENSAVER */
/*-----------------------------------------------------------------------------------*/
/**
* Add a program to the program handler.
*
* \param dsc The DSC description structure for the program to be added.
*
* \param menuname The name that the program should have in the
* Contiki menu.
*
* \param desktop Flag which specifies if the program should show up
* as an icon on the desktop or not.
*/
/*-----------------------------------------------------------------------------------*/
void
program_handler_add(struct dsc *dsc, char *menuname,
unsigned char desktop)
{
contikidsc[contikidsclast++] = dsc;
ctk_menuitem_add(&contikimenu, menuname);
if(desktop) {
CTK_ICON_ADD(dsc->icon, &program_handler_process);
}
}
/*-----------------------------------------------------------------------------------*/
/**
* Initializes the program handler.
*
* Is called by the initialization before any programs have been added
* with program_handler_add().
*
*/
/*-----------------------------------------------------------------------------------*/
#ifdef WITH_LOADER_ARCH
#define NUM_PNARGS 6
#define NAMELEN 32
struct pnarg {
char name[NAMELEN];
char *arg;
};
static struct pnarg pnargs[NUM_PNARGS];
static struct pnarg *
pnarg_copy(char *name, char *arg)
{
char i;
struct pnarg *pnargsptr;
pnargsptr = pnargs;
/* Allocate a place in the loadernames table. */
for(i = 0; i < NUM_PNARGS; ++i) {
if(*(pnargsptr->name) == 0) {
strncpy(pnargsptr->name, name, NAMELEN);
pnargsptr->arg = arg;
return pnargsptr;
}
++pnargsptr;
}
return NULL;
}
static void
pnarg_free(struct pnarg *pn)
{
*(pn->name) = 0;
}
#endif /* WITH_LOADER_ARCH */
/*-----------------------------------------------------------------------------------*/
/**
* Loads a program and displays a dialog telling the user about it.
*
* \param name The name of the program to be loaded.
*
* \param arg An argument which is passed to the new process when it
* is loaded.
*/
/*-----------------------------------------------------------------------------------*/
void
program_handler_load(char *name, char *arg)
{
#ifdef WITH_LOADER_ARCH
struct pnarg *pnarg;
pnarg = pnarg_copy(name, arg);
if(pnarg != NULL) {
process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, pnarg);
} else {
ctk_label_set_text(&errortype, "Out of memory");
ctk_dialog_open(&errordialog);
}
/* ctk_redraw(); */
/* ctk_window_redraw(&loadingdialog);*/
#endif /* WITH_LOADER_ARCH */
}
#ifdef WITH_LOADER_ARCH
#define RUN(prg, name, arg) program_handler_load(prg, arg)
#else /* WITH_LOADER_ARCH */
#define RUN(prg, process, arg) process_start(process, arg)
#endif /* WITH_LOADER_ARCH */
/*-----------------------------------------------------------------------------------*/
/**
* Configures the name of the screensaver to be loaded when
* appropriate.
*
* \param name The name of the screensaver or NULL if no screensaver
* should be used.
*/
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_SCREENSAVER
void
program_handler_setscreensaver(char *name)
{
if(name == NULL) {
program_handler_screensaver[0] = 0;
} else {
strncpy(program_handler_screensaver, name, sizeof(program_handler_screensaver));
}
}
#endif /* CTK_CONF_SCREENSAVER */
/*-----------------------------------------------------------------------------------*/
static void
make_windows(void)
{
#ifdef WITH_LOADER_ARCH
ctk_window_new(&runwindow, 16, 3, "Run");
CTK_WIDGET_ADD(&runwindow, &namelabel);
CTK_WIDGET_ADD(&runwindow, &nameentry);
CTK_WIDGET_ADD(&runwindow, &loadbutton);
CTK_WIDGET_FOCUS(&runwindow, &nameentry);
ctk_dialog_new(&loadingdialog, 25, 1);
CTK_WIDGET_ADD(&loadingdialog, &loadingmsg);
CTK_WIDGET_ADD(&loadingdialog, &loadingname);
ctk_dialog_new(&errordialog, 22, 8);
CTK_WIDGET_ADD(&errordialog, &errormsg);
CTK_WIDGET_ADD(&errordialog, &errorfilelabel);
CTK_WIDGET_ADD(&errordialog, &errortype);
CTK_WIDGET_ADD(&errordialog, &errorokbutton);
CTK_WIDGET_FOCUS(&errordialog, &errorokbutton);
#endif /* WITH_LOADER_ARCH */
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(program_handler_process, ev, data)
{
#ifdef WITH_LOADER_ARCH
unsigned char err;
struct dsc *dsc;
#endif /* WITH_LOADER_ARCH */
unsigned char i;
struct dsc **dscp;
PROCESS_BEGIN();
/* Create the menus */
ctk_menu_new(&contikimenu, "Contiki");
ctk_menu_add(&contikimenu);
#if WITH_LOADER_ARCH
runmenuitem = ctk_menuitem_add(&contikimenu, "Run program...");
make_windows();
#endif /* WITH_LOADER_ARCH */
displayname = NULL;
#if CTK_CONF_SCREENSAVER
program_handler_screensaver[0] = 0;
#endif /* CTK_CONF_SCREENSAVER */
while(1) {
PROCESS_WAIT_EVENT();
if(ev == ctk_signal_button_activate) {
#ifdef WITH_LOADER_ARCH
if(data == (process_data_t)&loadbutton) {
ctk_window_close(&runwindow);
program_handler_load(name, NULL);
} else if(data == (process_data_t)&errorokbutton) {
ctk_dialog_close();
}
#endif /* WITH_LOADER_ARCH */
dscp = &contikidsc[0];
for(i = 0; i < CTK_CONF_MAXMENUITEMS; ++i) {
if(*dscp != NULL &&
data == (process_data_t)(*dscp)->icon) {
RUN((*dscp)->prgname, (*dscp)->process, NULL);
break;
}
++dscp;
}
} else if(ev == ctk_signal_menu_activate) {
if((struct ctk_menu *)data == &contikimenu) {
#if WITH_LOADER_ARCH
dsc = contikidsc[contikimenu.active];
if(dsc != NULL) {
RUN(dsc->prgname, dsc->process, NULL);
} else if(contikimenu.active == runmenuitem) {
make_windows();
ctk_window_close(&runwindow);
ctk_window_open(&runwindow);
CTK_WIDGET_FOCUS(&runwindow, &nameentry);
}
#else /* WITH_LOADER_ARCH */
if(contikidsc[contikimenu.active] != NULL) {
RUN(contikidsc[contikimenu.active]->prgname,
contikidsc[contikimenu.active]->process,
NULL);
}
#endif /* WITH_LOADER_ARCH */
}
#if CTK_CONF_SCREENSAVER
} else if(ev == ctk_signal_screensaver_start) {
#if WITH_LOADER_ARCH
if(program_handler_screensaver[0] != 0) {
program_handler_load(program_handler_screensaver, NULL);
}
#endif /* WITH_LOADER_ARCH */
#endif /* CTK_CONF_SCREENSAVER */
} else if(ev == LOADER_EVENT_DISPLAY_NAME) {
#if WITH_LOADER_ARCH
if(displayname == NULL) {
make_windows();
ctk_label_set_text(&loadingname, ((struct pnarg *)data)->name);
ctk_dialog_open(&loadingdialog);
process_post(&program_handler_process, LOADER_EVENT_LOAD, data);
displayname = data;
} else {
/* Try again. */
process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data);
}
#endif /* WITH_LOADER_ARCH */
} else if(ev == LOADER_EVENT_LOAD) {
#if WITH_LOADER_ARCH
if(displayname == data) {
ctk_dialog_close();
displayname = NULL;
log_message("Loading ", ((struct pnarg *)data)->name);
err = LOADER_LOAD(((struct pnarg *)data)->name,
((struct pnarg *)data)->arg);
if(err != LOADER_OK) {
make_windows();
errorfilename[0] = '"';
strncpy(errorfilename + 1, ((struct pnarg *)data)->name,
sizeof(errorfilename) - 2);
errorfilename[1 + strlen(((struct pnarg *)data)->name)] = '"';
ctk_label_set_text(&errortype, (char *)errormsgs[err]);
ctk_dialog_open(&errordialog);
log_message((char *)errormsgs[err], errorfilename);
}
pnarg_free(data);
} else {
/* Try again. */
process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data);
}
#endif /* WITH_LOADEER_ARCH */
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,53 @@
/*
* Copyright (c) 2002, 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 environment for the C64.
*
* $Id: program-handler.h,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#ifndef __PROGRAM_HANDLER_H__
#define __PROGRAM_HANDLER_H__
#include "sys/dsc.h"
#define program_handler_getscreensaver() program_handler_screensaver
extern char program_handler_screensaver[];
void program_handler_init(void);
void program_handler_load(char *name, char *arg);
void program_handler_setscreensaver(char *name);
void program_handler_add(struct dsc *dsc, char *menuname,
unsigned char desktop);
PROCESS_NAME(program_handler_process);
#endif /* __PROGRAM_HANDLER_H__ */

View file

@ -0,0 +1,2 @@
APP_SOURCES += shell-gui.c shell.c ctk-textentry-cmdline.c
DSC_SOURCES += shell-dsc.c

74
apps/shell/shell-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: shell-dsc.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon shell_icon;
/*-----------------------------------------------------------------------------------*/
DSC(shell_dsc,
"The Contiki command shell",
"shell.prg",
shell_gui_process,
&shell_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char shellicon_bitmap[3*3*8] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char shellicon_textmap[9] = {
'C', 'o', 'n',
't', 'i', 'k',
'i', 'S', 'h'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon shell_icon =
{CTK_ICON("Command shell", shellicon_bitmap, shellicon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/shell/shell-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: shell-dsc.h,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#ifndef __SHELL_DSC_H__
#define __SHELL_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(shell_dsc);
#endif /* __SHELL_DSC_H__ */

144
apps/shell/shell-gui.c Normal file
View file

@ -0,0 +1,144 @@
/*
* 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-gui.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include "program-handler.h"
#include "contiki.h"
#include "shell.h"
#include "lib/ctk-textentry-cmdline.h"
#include <string.h>
#ifdef SHELL_GUI_CONF_XSIZE
#define SHELL_GUI_XSIZE SHELL_GUI_CONF_XSIZE
#else
#define SHELL_GUI_XSIZE 10
#endif
#ifdef SHELL_GUI_CONF_YSIZE
#define SHELL_GUI_YSIZE SHELL_GUI_CONF_YSIZE
#else
#define SHELL_GUI_YSIZE 10
#endif
static struct ctk_window window;
static char log[SHELL_GUI_XSIZE * SHELL_GUI_YSIZE];
static struct ctk_label loglabel =
{CTK_LABEL(0, 0, SHELL_GUI_XSIZE, SHELL_GUI_YSIZE, log)};
static char command[SHELL_GUI_XSIZE - 1];
static struct ctk_textentry commandentry =
{CTK_TEXTENTRY_INPUT(0, SHELL_GUI_YSIZE, SHELL_GUI_XSIZE - 2, 1, command,
SHELL_GUI_XSIZE - 2, ctk_textentry_cmdline_input)};
PROCESS(shell_gui_process, "Command shell");
/*-----------------------------------------------------------------------------------*/
void
shell_quit(char *str)
{
ctk_window_close(&window);
process_exit(&shell_gui_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
void
shell_output(char *str1, char *str2)
{
static unsigned char i, len;
for(i = 1; i < SHELL_GUI_YSIZE; ++i) {
memcpy(&log[(i - 1) * SHELL_GUI_XSIZE],
&log[i * SHELL_GUI_XSIZE], SHELL_GUI_XSIZE);
}
memset(&log[(SHELL_GUI_YSIZE - 1) * SHELL_GUI_XSIZE],
0, SHELL_GUI_XSIZE);
len = strlen(str1);
strncpy(&log[(SHELL_GUI_YSIZE - 1) * SHELL_GUI_XSIZE],
str1, SHELL_GUI_XSIZE);
if(len < SHELL_GUI_XSIZE) {
strncpy(&log[(SHELL_GUI_YSIZE - 1) * SHELL_GUI_XSIZE] + len,
str2, SHELL_GUI_XSIZE - len);
}
CTK_WIDGET_REDRAW(&loglabel);
}
/*-----------------------------------------------------------------------------------*/
void
shell_prompt(char *str)
{
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(shell_gui_process, ev, data)
{
PROCESS_BEGIN();
ctk_window_new(&window, SHELL_GUI_XSIZE,
SHELL_GUI_YSIZE + 1, "Command shell");
CTK_WIDGET_ADD(&window, &loglabel);
/* CTK_WIDGET_SET_FLAG(&loglabel, CTK_WIDGET_FLAG_MONOSPACE);*/
CTK_WIDGET_ADD(&window, &commandentry);
/* CTK_WIDGET_SET_FLAG(&commandentry, CTK_WIDGET_FLAG_MONOSPACE);*/
CTK_WIDGET_FOCUS(&window, &commandentry);
memset(log, 0, sizeof(log));
shell_init();
ctk_window_open(&window);
shell_start();
while(1) {
PROCESS_WAIT_EVENT();
if(ev == ctk_signal_widget_activate &&
data == (process_data_t)&commandentry) {
shell_output("> ", command);
shell_input(command);
CTK_TEXTENTRY_CLEAR(&commandentry);
CTK_WIDGET_REDRAW(&commandentry);
} else if(ev == ctk_signal_window_close ||
ev == PROCESS_EVENT_EXIT) {
shell_quit(NULL);
} else {
shell_eventhandler(ev, data);
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/

284
apps/shell/shell.c Normal file
View file

@ -0,0 +1,284 @@
/*
* 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.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include "program-handler.h"
#include "contiki-net.h"
#include "cfs/cfs.h"
#include "shell.h"
#include <string.h>
static char showingdir = 0;
static struct cfs_dir dir;
static unsigned int totsize;
struct ptentry {
char c1;
char c2;
void (* pfunc)(char *str);
};
/*-----------------------------------------------------------------------------------*/
static void
parse(register char *str, struct ptentry *t)
{
register struct ptentry *p;
char *sstr;
sstr = str;
/* 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;
}
/* Skip all spaces.*/
while(*str == ' ') {
++str;
}
/* Call parse table entry function and return. */
p->pfunc(str);
return;
}
}
/* Did not find matching entry in parse table. We just call the
default handler supplied by the caller and return. */
p->pfunc(str);
}
/*-----------------------------------------------------------------------------------*/
static void
inttostr(register char *str, unsigned int i)
{
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)
{
static char idstr[5];
struct process *p;
shell_output("Processes:", "");
/* Step through each possible process ID and see if there is a
matching process. */
for(p = PROCESS_LIST(); p != NULL; p = p->next) {
/* inttostr(idstr, p->id);*/
shell_output(idstr, (char *)p->name);
}
}
/*-----------------------------------------------------------------------------------*/
static char *
nullterminate(char *str)
{
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;
}
/* Return pointer to null char. */
return nt;
}
/*-----------------------------------------------------------------------------------*/
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);
}
/*-----------------------------------------------------------------------------------*/
static void
killproc(char *str)
{
char procnum, j, c;
char procstr[5];
nullterminate(str);
procnum = 0;
for(j = 0; j < 4; ++j) {
c = str[(unsigned int)j];
if(c >= '0' && c <= '9') {
procnum = procnum * 10 + (str[(unsigned int)j] - '0');
} else {
break;
}
}
if(procnum != 0) {
inttostr(procstr, procnum);
shell_output("Killing process ", procstr);
} else {
shell_output("Invalid process number", "");
}
}
/*-----------------------------------------------------------------------------------*/
static void
help(char *str)
{
shell_output("Available commands:", "");
shell_output("run - start program", "");
shell_output("exec - start program & exit shell", "");
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);
}
}
/*-----------------------------------------------------------------------------------*/
static void
none(char *str)
{
}
/*-----------------------------------------------------------------------------------*/
static struct ptentry configparsetab[] =
{{'e', 'E', execfile},
{'r', 'R', runfile},
{'k', 'K', killproc},
{'p', 'P', processes},
{'l', 'L', directory},
{'q', 'Q', shell_quit},
{'h', '?', help},
/* Default action */
{0, 0, none}};
/*-----------------------------------------------------------------------------------*/
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];
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);
}
}
}
}
/*-----------------------------------------------------------------------------------*/

114
apps/shell/shell.h Normal file
View file

@ -0,0 +1,114 @@
/**
* \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.
*/
/*
* 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.
*/
void shell_init(void);
/**
* Start the shell back-end.
*
* Called by the front-end when a new shell is started.
*/
void shell_start(void);
/**
* 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);
/**
* 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);
#endif /* __SHELL_H__ */

View file

@ -0,0 +1,2 @@
APP_SOURCES += simpletelnet.c telnet.c
DSC_SOURCES += telnet-dsc.c

310
apps/telnet/simpletelnet.c Normal file
View file

@ -0,0 +1,310 @@
/*
* Copyright (c) 2002, 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 environment
*
* $Id: simpletelnet.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include <string.h>
#include "contiki-net.h"
#include "lib/petsciiconv.h"
#include "ctk/ctk.h"
#include "telnet.h"
#include "simpletelnet.h"
/* Telnet window */
static struct ctk_window telnetwindow;
static struct ctk_label telnethostlabel =
{CTK_LABEL(1, 0, 4, 1, "Host")};
static char telnethost[25];
static struct ctk_textentry telnethosttextentry =
{CTK_TEXTENTRY(0, 1, 24, 1, telnethost, 24)};
static struct ctk_label telnetportlabel =
{CTK_LABEL(31, 0, 4, 1, "Port")};
static char telnetport[6];
static struct ctk_textentry telnetporttextentry =
{CTK_TEXTENTRY(30, 1, 5, 1, telnetport, 5)};
static struct ctk_button telnetconnectbutton =
{CTK_BUTTON(2, 3, 7, "Connect")};
static struct ctk_button telnetdisconnectbutton =
{CTK_BUTTON(25, 3, 10, "Disconnect")};
static char telnetline[31];
static struct ctk_textentry telnetlinetextentry =
{CTK_TEXTENTRY(0, 5, 30, 1, telnetline, 30)};
static struct ctk_button telnetsendbutton =
{CTK_BUTTON(32, 5, 4, "Send")};
static struct ctk_label telnetstatus =
{CTK_LABEL(0, 19, 38, 1, "")};
static struct ctk_separator telnetsep1 =
{CTK_SEPARATOR(0, 7, 38)};
static struct ctk_separator telnetsep2 =
{CTK_SEPARATOR(0, 18, 38)};
static char telnettext[38*10];
static struct ctk_label telnettextarea =
{CTK_LABEL(0, 8, 38, 10, telnettext)};
static struct telnet_state ts_appstate;
#define ISO_NL 0x0a
#define ISO_CR 0x0d
static char sendline[31+2];
PROCESS(simpletelnet_process, "Telnet client");
/*-----------------------------------------------------------------------------------*/
static void
scrollup(void)
{
unsigned char i;
for(i = 1; i < 10; ++i) {
memcpy(&telnettext[(i - 1) * 38], &telnettext[i * 38], 38);
}
memset(&telnettext[9 * 38], 0, 38);
}
/*-----------------------------------------------------------------------------------*/
static void
add_text(char *text)
{
unsigned char i;
unsigned int len;
len = strlen(text);
i = 0;
while(len > 0) {
if(*text == '\n') {
scrollup();
i = 0;
} else if(*text == '\r') {
i = 0;
} else if(*text >= ' ') {
telnettext[9 * 38 + i] = *text;
++i;
if(i == 38) {
scrollup();
i = 0;
}
}
++text;
--len;
}
/* if(strlen(text) > 37) {
memcpy(&telnettext[9 * 38], text, 37);
} else {
memcpy(&telnettext[9 * 38], text, strlen(text));
}
*/
}
/*-----------------------------------------------------------------------------------*/
static void
show(char *text)
{
add_text(text);
add_text("\n");
ctk_label_set_text(&telnetstatus, text);
ctk_window_redraw(&telnetwindow);
}
/*-----------------------------------------------------------------------------------*/
static void
connect(void)
{
u16_t addr[2], *addrptr;
u16_t port;
char *cptr;
struct uip_conn *conn;
/* Find the first space character in host and put a zero there
to end the string. */
for(cptr = telnethost; *cptr != ' ' && *cptr != 0; ++cptr);
*cptr = 0;
addrptr = &addr[0];
if(uiplib_ipaddrconv(telnethost, (unsigned char *)addr) == 0) {
addrptr = resolv_lookup(telnethost);
if(addrptr == NULL) {
resolv_query(telnethost);
show("Resolving host...");
return;
}
}
port = 0;
for(cptr = telnetport; *cptr != ' ' && *cptr != 0; ++cptr) {
if(*cptr < '0' || *cptr > '9') {
show("Port number error");
return;
}
port = 10 * port + *cptr - '0';
}
conn = tcp_connect(addrptr, htons(port), &ts_appstate);
if(conn == NULL) {
show("Out of memory error");
return;
}
show("Connecting...");
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(simpletelnet_process, ev, data)
{
struct ctk_widget *w;
int sendlen;
PROCESS_BEGIN();
ctk_window_new(&telnetwindow, 38, 20, "Simple telnet");
strcpy(telnetport, "23");
CTK_WIDGET_ADD(&telnetwindow, &telnethostlabel);
CTK_WIDGET_ADD(&telnetwindow, &telnetportlabel);
CTK_WIDGET_ADD(&telnetwindow, &telnethosttextentry);
CTK_WIDGET_ADD(&telnetwindow, &telnetporttextentry);
CTK_WIDGET_ADD(&telnetwindow, &telnetconnectbutton);
CTK_WIDGET_ADD(&telnetwindow, &telnetdisconnectbutton);
CTK_WIDGET_ADD(&telnetwindow, &telnetlinetextentry);
CTK_WIDGET_ADD(&telnetwindow, &telnetsendbutton);
CTK_WIDGET_ADD(&telnetwindow, &telnetsep1);
CTK_WIDGET_ADD(&telnetwindow, &telnettextarea);
CTK_WIDGET_ADD(&telnetwindow, &telnetsep2);
CTK_WIDGET_ADD(&telnetwindow, &telnetstatus);
CTK_WIDGET_FOCUS(&telnetwindow, &telnethosttextentry);
ctk_window_open(&telnetwindow);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == ctk_signal_button_activate) {
w = (struct ctk_widget *)data;
if(w == (struct ctk_widget *)&telnetsendbutton) {
strcpy(sendline, telnetline);
sendlen = strlen(sendline);
petsciiconv_toascii(sendline, sendlen);
sendline[sendlen++] = ISO_CR;
sendline[sendlen++] = ISO_NL;
if(telnet_send(&ts_appstate, sendline, sendlen)) {
/* Could not send. */
ctk_label_set_text(&telnetstatus, "Could not send");
ctk_window_redraw(&telnetwindow);
/* } else {*/
/* Could send */
}
} else if(w == (struct ctk_widget *)&telnetdisconnectbutton) {
telnet_close(&ts_appstate);
show("Closing...");
} else if(w == (struct ctk_widget *)&telnetconnectbutton) {
connect();
ctk_window_redraw(&telnetwindow);
}
} else if(ev == resolv_event_found) {
if(strcmp(data, telnethost) == 0) {
if(resolv_lookup(telnethost) != NULL) {
connect();
} else {
show("Host not found");
}
}
} else if(ev == ctk_signal_window_close ||
ev == PROCESS_EVENT_EXIT) {
process_exit(&simpletelnet_process);
ctk_window_close(&telnetwindow);
LOADER_UNLOAD();
} else if(ev == tcpip_event) {
telnet_app(data);
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/
void
telnet_connected(struct telnet_state *s)
{
show("Connected");
}
/*-----------------------------------------------------------------------------------*/
void
telnet_closed(struct telnet_state *s)
{
show("Connection closed");
}
/*-----------------------------------------------------------------------------------*/
void
telnet_sent(struct telnet_state *s)
{
petsciiconv_topetscii(sendline, sizeof(sendline));
scrollup();
add_text(sendline);
CTK_TEXTENTRY_CLEAR(&telnetlinetextentry);
ctk_window_redraw(&telnetwindow);
}
/*-----------------------------------------------------------------------------------*/
void
telnet_aborted(struct telnet_state *s)
{
show("Connection reset by peer");
}
/*-----------------------------------------------------------------------------------*/
void
telnet_timedout(struct telnet_state *s)
{
show("Connection timed out");
}
/*-----------------------------------------------------------------------------------*/
void
telnet_newdata(struct telnet_state *s, char *data, u16_t len)
{
petsciiconv_topetscii(data, len);
data[len] = 0;
add_text(data);
ctk_window_redraw(&telnetwindow);
}
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2002, 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 environment for the C64.
*
* $Id: simpletelnet.h,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#ifndef __SIMPLETELNET_H__
#define __SIMPLETELNET_H__
void simpletelnet_init(char *arg);
#endif /* __SIMPLETELNET_H__ */

74
apps/telnet/telnet-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: telnet-dsc.c,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon telnet_icon;
/*-----------------------------------------------------------------------------------*/
DSC(telnet_dsc,
"A simple Telnet client",
"telnet.prg",
simpletelnet_process,
&telnet_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char telneticon_bitmap[3*3*8] = {
0x00, 0x7f, 0x43, 0x4c, 0x58, 0x53, 0x60, 0x6f,
0x00, 0xff, 0x00, 0x7e, 0x00, 0xff, 0x00, 0xff,
0x00, 0xfe, 0xc2, 0x32, 0x1a, 0xca, 0x06, 0xf6,
0x40, 0x5f, 0x40, 0x5f, 0x40, 0x5f, 0x40, 0x4f,
0x00, 0xff, 0x00, 0xff, 0x00, 0xfc, 0x01, 0xf3,
0x02, 0xfa, 0x02, 0x82, 0x3e, 0xfe, 0xfe, 0xfe,
0x60, 0x67, 0x50, 0x59, 0x4c, 0x43, 0x7f, 0x00,
0x07, 0xe7, 0x0f, 0xef, 0x0f, 0x0f, 0xff, 0x00,
0x8e, 0x06, 0x06, 0x06, 0x8e, 0xfe, 0xfe, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char telneticon_textmap[9] = {
't', 'e', 'l',
'n', 'e', 't',
'-', '-', '-'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon telnet_icon =
{CTK_ICON("Telnet", telneticon_bitmap, telneticon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/telnet/telnet-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: telnet-dsc.h,v 1.1 2006/06/17 22:41:12 adamdunkels Exp $
*
*/
#ifndef __TELNET_DSC_H__
#define __TELNET_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(telnet_dsc);
#endif /* __TELNET_DSC_H__ */

152
apps/telnet/telnet.c Normal file
View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2002, 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 uIP TCP/IP stack.
*
* $Id: telnet.c,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#include "contiki-net.h"
#include "telnet.h"
#ifndef NULL
#define NULL (void *)0
#endif /* NULL */
#define FLAG_CLOSE 1
#define FLAG_ABORT 2
/*-----------------------------------------------------------------------------------*/
unsigned char
telnet_send(struct telnet_state *s, char *text, u16_t len)
{
if(s->text != NULL) {
return 1;
}
s->text = text;
s->textlen = len;
s->sentlen = 0;
return 0;
}
/*-----------------------------------------------------------------------------------*/
unsigned char
telnet_close(struct telnet_state *s)
{
s->flags = FLAG_CLOSE;
if(s->text != NULL) {
return 1;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
unsigned char
telnet_abort(struct telnet_state *s)
{
s->flags = FLAG_ABORT;
if(s->text != NULL) {
return 1;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
static void
acked(struct telnet_state *s)
{
s->textlen -= s->sentlen;
if(s->textlen == 0) {
s->text = NULL;
telnet_sent(s);
} else {
s->text += s->sentlen;
}
s->sentlen = 0;
}
/*-----------------------------------------------------------------------------------*/
static void
senddata(struct telnet_state *s)
{
if(s->text == NULL) {
uip_send(s->text, 0);
return;
}
if(s->textlen > uip_mss()) {
s->sentlen = uip_mss();
} else {
s->sentlen = s->textlen;
}
uip_send(s->text, s->sentlen);
}
/*-----------------------------------------------------------------------------------*/
void
telnet_app(void *ts)
{
struct telnet_state *s = (struct telnet_state *)ts;
if(uip_connected()) {
s->flags = 0;
telnet_connected(s);
senddata(s);
return;
}
if(uip_closed()) {
telnet_closed(s);
}
if(uip_aborted()) {
telnet_aborted(s);
}
if(uip_timedout()) {
telnet_timedout(s);
}
if(s->flags & FLAG_CLOSE) {
uip_close();
return;
}
if(s->flags & FLAG_ABORT) {
uip_abort();
return;
}
if(uip_acked()) {
acked(s);
}
if(uip_newdata()) {
telnet_newdata(s, (char *)uip_appdata, uip_datalen());
}
if(uip_rexmit() ||
uip_newdata() ||
uip_acked()) {
senddata(s);
} else if(uip_poll()) {
senddata(s);
}
}
/*-----------------------------------------------------------------------------------*/

59
apps/telnet/telnet.h Normal file
View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2002, 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 uIP TCP/IP stack.
*
* $Id: telnet.h,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#ifndef __TELNET_H__
#define __TELNET_H__
#include "contiki-net.h"
struct telnet_state {
unsigned char flags;
char *text;
u16_t textlen;
u16_t sentlen;
};
/*DISPATCHER_UIPCALL(telnet_app, s);*/
void telnet_app(void *s);
unsigned char telnet_send(struct telnet_state *s, char *text, u16_t len);
unsigned char telnet_close(struct telnet_state *s);
unsigned char telnet_abort(struct telnet_state *s);
/* Callbacks, implemented by the caller. */
void telnet_connected(struct telnet_state *s);
void telnet_closed(struct telnet_state *s);
void telnet_sent(struct telnet_state *s);
void telnet_aborted(struct telnet_state *s);
void telnet_timedout(struct telnet_state *s);
void telnet_newdata(struct telnet_state *s, char *data, u16_t len);
#endif /* __TELNET_H__ */

View file

@ -0,0 +1,2 @@
APP_SOURCES += telnetd.c shell.c
DSC_SOURCES += telnetd-dsc.c

View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: telnetd-dsc.c,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon telnetd_icon;
/*-----------------------------------------------------------------------------------*/
DSC(telnetd_dsc,
"Telnet shell server",
"telnetd.prg",
telnetd_process,
&telnetd_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char telnetdicon_bitmap[3*3*8] = {
0x00, 0x7f, 0x43, 0x4c, 0x58, 0x53, 0x60, 0x6f,
0x00, 0xff, 0x00, 0x7e, 0x00, 0xff, 0x00, 0xff,
0x00, 0xfe, 0xc2, 0x32, 0x1a, 0xca, 0x06, 0xf6,
0x40, 0x5f, 0x40, 0x5f, 0x40, 0x5f, 0x40, 0x4f,
0x00, 0xff, 0x00, 0xff, 0x00, 0xfc, 0x01, 0xf3,
0x02, 0xfa, 0x02, 0x82, 0x3e, 0xfe, 0xfe, 0xfe,
0x60, 0x67, 0x50, 0x59, 0x4c, 0x43, 0x7f, 0x00,
0x07, 0xe7, 0x0f, 0xef, 0x0f, 0x0f, 0xff, 0x00,
0x8e, 0x06, 0x06, 0x06, 0x8e, 0xfe, 0xfe, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char telnetdicon_textmap[9] = {
't', 'e', 'l',
'n', 'e', 't',
's', 'r', 'v'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon telnetd_icon =
{CTK_ICON("Telnet server", telnetdicon_bitmap, telnetdicon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: telnetd-dsc.h,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#ifndef __TELNETD_DSC_H__
#define __TELNETD_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(telnetd_dsc);
#endif /* __TELNETD_DSC_H__ */

View file

@ -0,0 +1,98 @@
/*
* 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: telnetd-gui.c,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#include "program-handler.h"
#include "contiki-net.h"
#include "lib/petsciiconv.h"
#include "shell.h"
#include "telnetd.h"
#include <string.h>
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define XSIZE 36
#define YSIZE 12
static struct ctk_window window;
static char log[XSIZE * YSIZE];
static struct ctk_label loglabel =
{CTK_LABEL(0, 0, XSIZE, YSIZE, log)};
/*-----------------------------------------------------------------------------------*/
void
telnetd_gui_output(char *str1, char *str2)
{
static unsigned int len, i;
for(i = 1; i < YSIZE; ++i) {
memcpy(&log[(i - 1) * XSIZE], &log[i * XSIZE], XSIZE);
}
memset(&log[(YSIZE - 1) * XSIZE], 0, XSIZE);
len = strlen(str1);
strncpy(&log[(YSIZE - 1) * XSIZE], str1, XSIZE);
if(len < XSIZE) {
strncpy(&log[(YSIZE - 1) * XSIZE] + len, str2, XSIZE - len);
}
CTK_WIDGET_REDRAW(&loglabel);
}
/*-----------------------------------------------------------------------------------*/
void
telnetd_gui_quit(void)
{
ctk_window_close(&window);
}
/*-----------------------------------------------------------------------------------*/
void
telnetd_gui_init(void)
{
ctk_window_new(&window, XSIZE, YSIZE, "Shell server");
CTK_WIDGET_ADD(&window, &loglabel);
memset(log, 0, sizeof(log));
ctk_window_open(&window);
}
/*-----------------------------------------------------------------------------------*/
void
telnetd_gui_eventhandler(process_event_t ev, process_data_t data)
{
if(ev == ctk_signal_window_close) {
telnetd_quit();
}
}
/*-----------------------------------------------------------------------------------*/

399
apps/telnetd/telnetd.c Normal file
View file

@ -0,0 +1,399 @@
/*
* 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: telnetd.c,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#include "contiki-net.h"
#include "lib/petsciiconv.h"
#include "contiki-lib.h"
#include "shell.h"
#include "telnetd.h"
#include <string.h>
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define XSIZE 36
#define YSIZE 12
PROCESS(telnetd_process, "Shell server");
#ifndef TELNETD_CONF_LINELEN
#define TELNETD_CONF_LINELEN 40
#endif
#ifndef TELNETD_CONF_NUMLINES
#define TELNETD_CONF_NUMLINES 16
#endif
struct telnetd_line {
char line[TELNETD_CONF_LINELEN];
};
MEMB(linemem, struct telnetd_line, TELNETD_CONF_NUMLINES);
struct telnetd_state {
char *lines[TELNETD_CONF_NUMLINES];
char buf[TELNETD_CONF_LINELEN];
char bufptr;
u8_t numsent;
u8_t state;
#define STATE_NORMAL 0
#define STATE_IAC 1
#define STATE_WILL 2
#define STATE_WONT 3
#define STATE_DO 4
#define STATE_DONT 5
#define STATE_CLOSE 6
};
static struct telnetd_state s;
#define TELNET_IAC 255
#define TELNET_WILL 251
#define TELNET_WONT 252
#define TELNET_DO 253
#define TELNET_DONT 254
/*-----------------------------------------------------------------------------------*/
static char *
alloc_line(void)
{
return memb_alloc(&linemem);
}
/*-----------------------------------------------------------------------------------*/
static void
dealloc_line(char *line)
{
memb_free(&linemem, line);
}
/*-----------------------------------------------------------------------------------*/
void
shell_quit(char *str)
{
s.state = STATE_CLOSE;
}
/*-----------------------------------------------------------------------------------*/
void
telnetd_quit(void)
{
#if TELNETD_CONF_GUI
telnetd_gui_quit();
#endif /* TELNETD_CONF_GUI */
process_exit(&telnetd_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
static void
sendline(char *line)
{
static unsigned int i;
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
if(s.lines[i] == NULL) {
s.lines[i] = line;
break;
}
}
if(i == TELNETD_CONF_NUMLINES) {
dealloc_line(line);
}
}
/*-----------------------------------------------------------------------------------*/
void
shell_prompt(char *str)
{
char *line;
line = alloc_line();
if(line != NULL) {
strncpy(line, str, TELNETD_CONF_LINELEN);
petsciiconv_toascii(line, TELNETD_CONF_LINELEN);
sendline(line);
}
}
/*-----------------------------------------------------------------------------------*/
void
shell_output(char *str1, char *str2)
{
static unsigned len;
char *line;
line = alloc_line();
if(line != NULL) {
len = strlen(str1);
strncpy(line, str1, TELNETD_CONF_LINELEN);
if(len < TELNETD_CONF_LINELEN) {
strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
}
len = strlen(line);
if(len < TELNETD_CONF_LINELEN - 2) {
line[len] = ISO_cr;
line[len+1] = ISO_nl;
line[len+2] = 0;
}
petsciiconv_toascii(line, TELNETD_CONF_LINELEN);
sendline(line);
}
}
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(telnetd_process, ev, data)
{
PROCESS_BEGIN();
tcp_listen(HTONS(23));
memb_init(&linemem);
shell_init();
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
telnetd_appcall(data);
} else if(ev == PROCESS_EVENT_EXIT) {
telnetd_quit();
} else {
#if TELNETD_CONF_GUI
telnetd_gui_eventhandler(ev, data);
#endif /* TELNETD_CONF_GUI */
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/
static void
acked(void)
{
static unsigned int i;
while(s.numsent > 0) {
dealloc_line(s.lines[0]);
for(i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
s.lines[i - 1] = s.lines[i];
}
s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
--s.numsent;
}
}
/*-----------------------------------------------------------------------------------*/
static void
senddata(void)
{
static char *bufptr, *lineptr;
static int buflen, linelen;
bufptr = uip_appdata;
buflen = 0;
for(s.numsent = 0; s.numsent < TELNETD_CONF_NUMLINES &&
s.lines[s.numsent] != NULL ; ++s.numsent) {
lineptr = s.lines[s.numsent];
linelen = strlen(lineptr);
if(linelen > TELNETD_CONF_LINELEN) {
linelen = TELNETD_CONF_LINELEN;
}
if(buflen + linelen < uip_mss()) {
memcpy(bufptr, lineptr, linelen);
bufptr += linelen;
buflen += linelen;
} else {
break;
}
}
uip_send(uip_appdata, buflen);
}
/*-----------------------------------------------------------------------------------*/
static void
closed(void)
{
static unsigned int i;
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
if(s.lines[i] != NULL) {
dealloc_line(s.lines[i]);
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
get_char(u8_t c)
{
if(c == ISO_cr) {
return;
}
s.buf[(int)s.bufptr] = c;
if(s.buf[(int)s.bufptr] == ISO_nl ||
s.bufptr == sizeof(s.buf) - 1) {
if(s.bufptr > 0) {
s.buf[(int)s.bufptr] = 0;
petsciiconv_topetscii(s.buf, TELNETD_CONF_LINELEN);
}
shell_input(s.buf);
s.bufptr = 0;
} else {
++s.bufptr;
}
}
/*-----------------------------------------------------------------------------------*/
static void
sendopt(u8_t option, u8_t value)
{
char *line;
line = alloc_line();
if(line != NULL) {
line[0] = TELNET_IAC;
line[1] = option;
line[2] = value;
line[3] = 0;
sendline(line);
}
}
/*-----------------------------------------------------------------------------------*/
static void
newdata(void)
{
u16_t len;
u8_t c;
len = uip_datalen();
while(len > 0 && s.bufptr < sizeof(s.buf)) {
c = *(char *)uip_appdata;
++((char *)uip_appdata);
--len;
switch(s.state) {
case STATE_IAC:
if(c == TELNET_IAC) {
get_char(c);
s.state = STATE_NORMAL;
} else {
switch(c) {
case TELNET_WILL:
s.state = STATE_WILL;
break;
case TELNET_WONT:
s.state = STATE_WONT;
break;
case TELNET_DO:
s.state = STATE_DO;
break;
case TELNET_DONT:
s.state = STATE_DONT;
break;
default:
s.state = STATE_NORMAL;
break;
}
}
break;
case STATE_WILL:
/* Reply with a DONT */
sendopt(TELNET_DONT, c);
s.state = STATE_NORMAL;
break;
case STATE_WONT:
/* Reply with a DONT */
sendopt(TELNET_DONT, c);
s.state = STATE_NORMAL;
break;
case STATE_DO:
/* Reply with a WONT */
sendopt(TELNET_WONT, c);
s.state = STATE_NORMAL;
break;
case STATE_DONT:
/* Reply with a WONT */
sendopt(TELNET_WONT, c);
s.state = STATE_NORMAL;
break;
case STATE_NORMAL:
if(c == TELNET_IAC) {
s.state = STATE_IAC;
} else {
get_char(c);
}
break;
}
}
}
/*-----------------------------------------------------------------------------------*/
void
telnetd_appcall(void *ts)
{
static unsigned int i;
if(uip_connected()) {
tcp_markconn(uip_conn, &s);
for(i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
s.lines[i] = NULL;
}
s.bufptr = 0;
s.state = STATE_NORMAL;
shell_start();
}
if(s.state == STATE_CLOSE) {
s.state = STATE_NORMAL;
uip_close();
return;
}
if(uip_closed() ||
uip_aborted() ||
uip_timedout()) {
closed();
}
if(uip_acked()) {
acked();
}
if(uip_newdata()) {
newdata();
}
if(uip_rexmit() ||
uip_newdata() ||
uip_acked() ||
uip_connected() ||
uip_poll()) {
senddata();
}
}
/*-----------------------------------------------------------------------------------*/
void
program_handler_load(char *name, char *arg)
{}

49
apps/telnetd/telnetd.h Normal file
View file

@ -0,0 +1,49 @@
/*
* 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 environment
*
* $Id: telnetd.h,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#ifndef __TELNETD_H__
#define __TELNETD_H__
#include "contiki.h"
PROCESS_NAME(telnetd_process);
void telnetd_gui_eventhandler(process_event_t ev, process_data_t data);
void telnetd_appcall(void *data);
void telnetd_gui_output(char *str1, char *str2);
void telnetd_gui_quit(void);
void telnetd_quit(void);
#endif /* __TELNETD_H__ */

View file

@ -0,0 +1,3 @@
APP_SOURCES += www.c webclient.c http-strings.c http-user-agent-string.c \
htmlparser.c html-strings.c
DSC_SOURCES += www-dsc.c

View file

@ -0,0 +1,36 @@
html_slasha "/a\0"
html_slashcenter "/center\0"
html_slashform "/form\0"
html_slashh "/h\0"
html_slashscript "/script\0"
html_slashselect "/select\0"
html_slashstyle "/style\0"
html_a "a\0"
html_body "body\0"
html_br "br\0"
html_center "center\0"
html_form "form\0"
html_frame "frame\0"
html_h1 "h1\0"
html_h2 "h2\0"
html_h3 "h3\0"
html_h4 "h4\0"
html_img "img\0"
html_input "input\0"
html_li "li\0"
html_p "p\0"
html_script "script\0"
html_select "select\0"
html_style "style\0"
html_tr "tr\0"
html_href "href\0"
html_alt "alt\0"
html_src "src\0"
html_type "type\0"
html_submit "submit\0"
html_value "value\0"
html_action "action\0"
html_name "name\0"
html_text "text\0"
html_size "size\0"
html_image "image\0"

View file

@ -0,0 +1,108 @@
const char html_slasha[4] =
/* "/a\0" */
{0x2f, 0x61, 00, };
const char html_slashcenter[9] =
/* "/center\0" */
{0x2f, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 00, };
const char html_slashform[7] =
/* "/form\0" */
{0x2f, 0x66, 0x6f, 0x72, 0x6d, 00, };
const char html_slashh[4] =
/* "/h\0" */
{0x2f, 0x68, 00, };
const char html_slashscript[9] =
/* "/script\0" */
{0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 00, };
const char html_slashselect[9] =
/* "/select\0" */
{0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 00, };
const char html_slashstyle[8] =
/* "/style\0" */
{0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 00, };
const char html_a[3] =
/* "a\0" */
{0x61, 00, };
const char html_body[6] =
/* "body\0" */
{0x62, 0x6f, 0x64, 0x79, 00, };
const char html_br[4] =
/* "br\0" */
{0x62, 0x72, 00, };
const char html_center[8] =
/* "center\0" */
{0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 00, };
const char html_form[6] =
/* "form\0" */
{0x66, 0x6f, 0x72, 0x6d, 00, };
const char html_frame[7] =
/* "frame\0" */
{0x66, 0x72, 0x61, 0x6d, 0x65, 00, };
const char html_h1[4] =
/* "h1\0" */
{0x68, 0x31, 00, };
const char html_h2[4] =
/* "h2\0" */
{0x68, 0x32, 00, };
const char html_h3[4] =
/* "h3\0" */
{0x68, 0x33, 00, };
const char html_h4[4] =
/* "h4\0" */
{0x68, 0x34, 00, };
const char html_img[5] =
/* "img\0" */
{0x69, 0x6d, 0x67, 00, };
const char html_input[7] =
/* "input\0" */
{0x69, 0x6e, 0x70, 0x75, 0x74, 00, };
const char html_li[4] =
/* "li\0" */
{0x6c, 0x69, 00, };
const char html_p[3] =
/* "p\0" */
{0x70, 00, };
const char html_script[8] =
/* "script\0" */
{0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 00, };
const char html_select[8] =
/* "select\0" */
{0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 00, };
const char html_style[7] =
/* "style\0" */
{0x73, 0x74, 0x79, 0x6c, 0x65, 00, };
const char html_tr[4] =
/* "tr\0" */
{0x74, 0x72, 00, };
const char html_href[6] =
/* "href\0" */
{0x68, 0x72, 0x65, 0x66, 00, };
const char html_alt[5] =
/* "alt\0" */
{0x61, 0x6c, 0x74, 00, };
const char html_src[5] =
/* "src\0" */
{0x73, 0x72, 0x63, 00, };
const char html_type[6] =
/* "type\0" */
{0x74, 0x79, 0x70, 0x65, 00, };
const char html_submit[8] =
/* "submit\0" */
{0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 00, };
const char html_value[7] =
/* "value\0" */
{0x76, 0x61, 0x6c, 0x75, 0x65, 00, };
const char html_action[8] =
/* "action\0" */
{0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 00, };
const char html_name[6] =
/* "name\0" */
{0x6e, 0x61, 0x6d, 0x65, 00, };
const char html_text[6] =
/* "text\0" */
{0x74, 0x65, 0x78, 0x74, 00, };
const char html_size[6] =
/* "size\0" */
{0x73, 0x69, 0x7a, 0x65, 00, };
const char html_image[7] =
/* "image\0" */
{0x69, 0x6d, 0x61, 0x67, 0x65, 00, };

View file

@ -0,0 +1,36 @@
extern const char html_slasha[4];
extern const char html_slashcenter[9];
extern const char html_slashform[7];
extern const char html_slashh[4];
extern const char html_slashscript[9];
extern const char html_slashselect[9];
extern const char html_slashstyle[8];
extern const char html_a[3];
extern const char html_body[6];
extern const char html_br[4];
extern const char html_center[8];
extern const char html_form[6];
extern const char html_frame[7];
extern const char html_h1[4];
extern const char html_h2[4];
extern const char html_h3[4];
extern const char html_h4[4];
extern const char html_img[5];
extern const char html_input[7];
extern const char html_li[4];
extern const char html_p[3];
extern const char html_script[8];
extern const char html_select[8];
extern const char html_style[7];
extern const char html_tr[4];
extern const char html_href[6];
extern const char html_alt[5];
extern const char html_src[5];
extern const char html_type[6];
extern const char html_submit[8];
extern const char html_value[7];
extern const char html_action[8];
extern const char html_name[6];
extern const char html_text[6];
extern const char html_size[6];
extern const char html_image[7];

View file

@ -0,0 +1,852 @@
/*
* Copyright (c) 2002, 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 environment
*
* $Id: htmlparser.c,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
/* htmlparser.c:
*
* Implements a very simplistic HTML parser. It recognizes HTML links
* (<a href>-tags), HTML img alt tags, a few text flow break tags
G * (<br>, <p>, <h>), the <li> tag (but does not even try to
* distinguish between <ol> or <ul>) as well as HTML comment tags
* (<!-- -->).
*
* To save memory, the HTML parser is state machine driver, which
* means that it will shave off one character from the HTML page,
* process that character, and return to the next. Another way of
* doing it would be to buffer a number of characters and process them
* together.
*
* The main function in this file is the htmlparser_parse() function
* which takes a htmlparser_state structur and a part of an HTML file
* as an argument. The htmlparser_parse() function will call the
* helper functions parse_char() and parse_tag(). Those functions will
* in turn call the two callback functions htmlparser_char() and
* htmlparser_tag(). Those functions must be implemented by the using
* module (e.g., a web browser program).
*
* htmlparser_char() will be called for every non-tag character.
*
* htmlparser_tag() will be called whenever a full tag has been found.
*
*/
#include "htmlparser.h"
#include "html-strings.h"
#include "contiki.h"
#include <string.h>
#if 1
#define PRINTF(x)
#else
#include <stdio.h>
#define PRINTF(x) printf x
#endif
/*-----------------------------------------------------------------------------------*/
#define ISO_A 0x41
#define ISO_B 0x42
#define ISO_E 0x45
#define ISO_F 0x46
#define ISO_G 0x47
#define ISO_H 0x48
#define ISO_I 0x49
#define ISO_L 0x4c
#define ISO_M 0x4d
#define ISO_P 0x50
#define ISO_R 0x52
#define ISO_T 0x54
#define ISO_a (ISO_A | 0x20)
#define ISO_b (ISO_B | 0x20)
#define ISO_e (ISO_E | 0x20)
#define ISO_f (ISO_F | 0x20)
#define ISO_g (ISO_G | 0x20)
#define ISO_h (ISO_H | 0x20)
#define ISO_i (ISO_I | 0x20)
#define ISO_l (ISO_L | 0x20)
#define ISO_m (ISO_M | 0x20)
#define ISO_p (ISO_P | 0x20)
#define ISO_r (ISO_R | 0x20)
#define ISO_t (ISO_T | 0x20)
#define ISO_ht 0x09
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define ISO_space 0x20
#define ISO_bang 0x21
#define ISO_citation 0x22
#define ISO_ampersand 0x26
#define ISO_citation2 0x27
#define ISO_asterisk 0x2a
#define ISO_dash 0x2d
#define ISO_slash 0x2f
#define ISO_semicolon 0x3b
#define ISO_lt 0x3c
#define ISO_eq 0x3d
#define ISO_gt 0x3e
#define ISO_rbrack 0x5b
#define ISO_lbrack 0x5d
#define MINORSTATE_NONE 0
#define MINORSTATE_TEXT 1 /* Parse normal text */
#define MINORSTATE_EXTCHAR 2 /* Check for semi-colon */
#define MINORSTATE_TAG 3 /* Check for name of tag. */
#define MINORSTATE_TAGEND 4 /* Scan for end of tag. */
#define MINORSTATE_TAGATTR 5 /* Parse tag attr. */
#define MINORSTATE_TAGATTRSPACE 6 /* Parse optional space after tag
attr. */
#define MINORSTATE_TAGATTRPARAM 7 /* Parse tag attr parameter. */
#define MINORSTATE_TAGATTRPARAMNQ 8 /* Parse tag attr parameter without
quotation marks. */
#define MINORSTATE_HTMLCOMMENT 9 /* Scan for HTML comment end */
#define MAJORSTATE_NONE 0
#define MAJORSTATE_BODY 1
#define MAJORSTATE_LINK 2
#define MAJORSTATE_FORM 3
#define MAJORSTATE_DISCARD 4
struct htmlparser_state {
unsigned char minorstate;
char tag[20];
unsigned char tagptr;
char tagattr[20];
unsigned char tagattrptr;
char tagattrparam[WWW_CONF_MAX_URLLEN];
unsigned char tagattrparamptr;
unsigned char lastchar, quotechar;
unsigned char majorstate, lastmajorstate;
char linkurl[WWW_CONF_MAX_URLLEN];
#define MAX_WORDLEN 40
char word[MAX_WORDLEN];
unsigned char wordlen;
#if WWW_CONF_FORMS
char formaction[WWW_CONF_MAX_FORMACTIONLEN];
char formname[WWW_CONF_MAX_FORMNAMELEN];
unsigned char inputtype;
char inputname[WWW_CONF_MAX_INPUTNAMELEN];
char inputvalue[WWW_CONF_MAX_INPUTVALUELEN];
unsigned char inputvaluesize;
#endif /* WWW_CONF_FORMS */
};
static struct htmlparser_state s;
/*-----------------------------------------------------------------------------------*/
static char last[1] = {0xff};
static const char *tags[] = {
#define TAG_FIRST 0
#define TAG_SLASHA 0
html_slasha,
#define TAG_SLASHCENTER 1
html_slashcenter,
#define TAG_SLASHFORM 2
html_slashform,
#define TAG_SLASHH 3
html_slashh,
#define TAG_SLASHSCRIPT 4
html_slashscript,
#define TAG_SLASHSELECT 5
html_slashselect,
#define TAG_SLASHSTYLE 6
html_slashstyle,
#define TAG_A 7
html_a,
#define TAG_BODY 8
html_body,
#define TAG_BR 9
html_br,
#define TAG_CENTER 10
html_center,
#define TAG_FORM 11
html_form,
#define TAG_FRAME 12
html_frame,
#define TAG_H1 13
html_h1,
#define TAG_H2 14
html_h2,
#define TAG_H3 15
html_h3,
#define TAG_H4 16
html_h4,
#define TAG_IMG 17
html_img,
#define TAG_INPUT 18
html_input,
#define TAG_LI 19
html_li,
#define TAG_P 20
html_p,
#define TAG_SCRIPT 21
html_script,
#define TAG_SELECT 22
html_select,
#define TAG_STYLE 23
html_style,
#define TAG_TR 24
html_tr,
#define TAG_LAST 25
last,
};
/*-----------------------------------------------------------------------------------*/
static unsigned char CC_FASTCALL
iswhitespace(char c)
{
return (c == ISO_space ||
c == ISO_nl ||
c == ISO_cr ||
c == ISO_ht);
}
/*-----------------------------------------------------------------------------------*/
void
htmlparser_init(void)
{
s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD;
s.minorstate = MINORSTATE_TEXT;
s.lastchar = 0;
}
/*-----------------------------------------------------------------------------------*/
static char CC_FASTCALL
lowercase(char c)
{
/* XXX: This is a *brute force* approach to lower-case
converting and should *not* be used anywhere else! It
works for our purposes, however (i.e., HTML tags). */
if(c > 0x40) {
return (c & 0x1f) | 0x60;
} else {
return c;
}
}
/*-----------------------------------------------------------------------------------*/
static void
endtagfound(void)
{
s.tag[s.tagptr] = 0;
s.tagattr[s.tagattrptr] = 0;
s.tagattrparam[s.tagattrparamptr] = 0;
}
/*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL
switch_majorstate(unsigned char newstate)
{
if(s.majorstate != newstate) {
PRINTF(("Switching state from %d to %d (%d)\n", s.majorstate, newstate, s.lastmajorstate));
s.lastmajorstate = s.majorstate;
s.majorstate = newstate;
}
}
/*-----------------------------------------------------------------------------------*/
static void CC_FASTCALL
add_char(unsigned char c)
{
if(s.wordlen < MAX_WORDLEN &&
c < 0x80) {
s.word[s.wordlen] = c;
++s.wordlen;
if(s.wordlen == MAX_WORDLEN) {
s.wordlen = MAX_WORDLEN - 1;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
do_word(void)
{
if(s.wordlen > 0) {
if(s.majorstate == MAJORSTATE_LINK) {
if(s.word[s.wordlen] != ISO_space) {
add_char(ISO_space);
}
} else if(s.majorstate == MAJORSTATE_DISCARD) {
s.wordlen = 0;
} else {
s.word[s.wordlen] = '\0';
htmlparser_word(s.word, s.wordlen);
s.wordlen = 0;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
newline(void)
{
do_word();
htmlparser_newline();
}
/*-----------------------------------------------------------------------------------*/
static unsigned char CC_FASTCALL
find_tag(char *tag)
{
static unsigned char first, last, i, tabi;
static char tagc;
first = TAG_FIRST;
last = TAG_LAST;
i = 0;
do {
tagc = tag[i];
if(tagc == 0 &&
tags[first][i] == 0) {
return first;
}
tabi = first;
/* First, find first matching tag from table. */
while(tagc > (tags[tabi])[i] &&
tabi < last) {
++tabi;
}
first = tabi;
/* Second, find last matching tag from table. */
while(tagc == (tags[tabi])[i] &&
tabi < last) {
++tabi;
}
last = tabi;
/* If first and last matching tags are equal, we have a non-match
and return. Else we continue with the next character. */
++i;
} while(last != first);
return TAG_LAST;
}
/*-----------------------------------------------------------------------------------*/
static void
parse_tag(void)
{
static char *tagattrparam;
static unsigned char size, i;
static char dummy;
PRINTF(("Parsing tag '%s' '%s' '%s'\n",
s.tag, s.tagattr, s.tagattrparam));
switch(find_tag(s.tag)) {
case TAG_P:
case TAG_H1:
case TAG_H2:
case TAG_H3:
case TAG_H4:
/* parse_char(ISO_nl);*/
newline();
/* FALLTHROUGH */
case TAG_BR:
case TAG_TR:
case TAG_SLASHH:
/* parse_char(ISO_nl);*/
dummy = 0;
newline();
break;
case TAG_LI:
newline();
add_char(ISO_asterisk);
add_char(ISO_space);
break;
case TAG_SCRIPT:
case TAG_STYLE:
case TAG_SELECT:
switch_majorstate(MAJORSTATE_DISCARD);
break;
case TAG_SLASHSCRIPT:
case TAG_SLASHSTYLE:
case TAG_SLASHSELECT:
switch_majorstate(s.lastmajorstate);
break;
case TAG_BODY:
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
break;
case TAG_FRAME:
if(strncmp(s.tagattr, html_src, sizeof(html_src)) == 0 &&
s.tagattrparam[0] != 0) {
switch_majorstate(MAJORSTATE_BODY);
newline();
add_char(ISO_rbrack);
do_word();
htmlparser_link((char *)html_frame, strlen(html_frame), s.tagattrparam);
PRINTF(("Frame [%s]\n", s.tagattrparam));
add_char(ISO_lbrack);
newline();
}
break;
case TAG_IMG:
if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 &&
s.tagattrparam[0] != 0) {
/* parse_char(ISO_lt);*/
add_char(ISO_lt);
tagattrparam = &s.tagattrparam[0];
while(*tagattrparam) {
/* parse_char(*tagattrparam);*/
add_char(*tagattrparam);
++tagattrparam;
}
/* parse_char(ISO_gt);*/
add_char(ISO_gt);
do_word();
}
break;
case TAG_A:
PRINTF(("A %s %s\n", s.tagattr, s.tagattrparam));
if(strncmp(s.tagattr, html_href, sizeof(html_href)) == 0 &&
s.tagattrparam[0] != 0) {
strcpy(s.linkurl, s.tagattrparam);
do_word();
switch_majorstate(MAJORSTATE_LINK);
}
break;
case TAG_SLASHA:
if(s.majorstate == MAJORSTATE_LINK) {
switch_majorstate(s.lastmajorstate);
s.word[s.wordlen] = 0;
htmlparser_link(s.word, s.wordlen, s.linkurl);
s.wordlen = 0;
}
break;
#if WWW_CONF_FORMS
case TAG_FORM:
PRINTF(("Form tag\n"));
switch_majorstate(MAJORSTATE_FORM);
if(strncmp(s.tagattr, html_action, sizeof(html_action)) == 0) {
PRINTF(("Form action '%s'\n", s.tagattrparam));
strncpy(s.formaction, s.tagattrparam, WWW_CONF_MAX_FORMACTIONLEN - 1);
} else if(strncmp(s.tagattr, html_name, sizeof(html_name)) == 0) {
PRINTF(("Form name '%s'\n", s.tagattrparam));
strncpy(s.formname, s.tagattrparam, WWW_CONF_MAX_FORMNAMELEN - 1);
}
s.inputname[0] = s.inputvalue[0] = 0;
break;
case TAG_SLASHFORM:
switch_majorstate(MAJORSTATE_BODY);
s.formaction[0] = s.formname[0] = 0;
break;
case TAG_INPUT:
if(s.majorstate == MAJORSTATE_FORM) {
/* First check if we are called at the end of an input tag. If
so, we should render the input widget. */
if(s.tagattr[0] == 0 &&
s.inputname[0] != 0) {
PRINTF(("Render input type %d\n", s.inputtype));
switch(s.inputtype) {
case HTMLPARSER_INPUTTYPE_NONE:
case HTMLPARSER_INPUTTYPE_TEXT:
for(i = 0; i < s.inputvaluesize; ++i) {
if(s.inputvalue[i] == 0) {
memset(&s.inputvalue[i], ISO_space, s.inputvaluesize - i);
s.inputvalue[s.inputvaluesize] = 0;
break;
}
}
htmlparser_inputfield(s.inputvalue, s.inputname,
s.formname, s.formaction);
break;
case HTMLPARSER_INPUTTYPE_SUBMIT:
case HTMLPARSER_INPUTTYPE_IMAGE:
htmlparser_submitbutton(s.inputvalue, s.inputname,
s.formname, s.formaction);
break;
}
s.inputtype = HTMLPARSER_INPUTTYPE_NONE;
} else {
PRINTF(("Input '%s' '%s'\n", s.tagattr, s.tagattrparam));
if(strncmp(s.tagattr, html_type, sizeof(html_type)) == 0) {
if(strncmp(s.tagattrparam, html_submit,
sizeof(html_submit)) == 0) {
s.inputtype = HTMLPARSER_INPUTTYPE_SUBMIT;
} else if(strncmp(s.tagattrparam, html_image,
sizeof(html_image)) == 0) {
s.inputtype = HTMLPARSER_INPUTTYPE_IMAGE;
} else if(strncmp(s.tagattrparam, html_text,
sizeof(html_text)) == 0) {
s.inputtype = HTMLPARSER_INPUTTYPE_TEXT;
} else {
s.inputtype = HTMLPARSER_INPUTTYPE_OTHER;
}
} else if(strncmp(s.tagattr, html_name,
sizeof(html_name)) == 0) {
strncpy(s.inputname, s.tagattrparam,
WWW_CONF_MAX_INPUTNAMELEN);
} else if(strncmp(s.tagattr, html_alt,
sizeof(html_alt)) == 0 &&
s.inputtype == HTMLPARSER_INPUTTYPE_IMAGE) {
strncpy(s.inputvalue, s.tagattrparam,
WWW_CONF_MAX_INPUTVALUELEN);
} else if(strncmp(s.tagattr, html_value,
sizeof(html_value)) == 0) {
strncpy(s.inputvalue, s.tagattrparam,
WWW_CONF_MAX_INPUTVALUELEN);
} else if(strncmp(s.tagattr, html_size,
sizeof(html_size)) == 0) {
size = 0;
if(s.tagattrparam[0] >= '0' &&
s.tagattrparam[0] <= '9') {
size = s.tagattrparam[0] - '0';
if(s.tagattrparam[1] >= '0' &&
s.tagattrparam[1] <= '9') {
size = size * 10 + (s.tagattrparam[1] - '0');
}
}
if(size >= WWW_CONF_MAX_INPUTVALUELEN) {
size = WWW_CONF_MAX_INPUTVALUELEN - 1;
}
s.inputvaluesize = size;
/* strncpy(s.inputvalue, s.tagattrparam,
WWW_CONF_MAX_INPUTVALUELEN);*/
}
}
}
break;
#endif /* WWW_CONF_FORMS */
#if WWW_CONF_RENDERSTATE
case TAG_CENTER:
/* parse_char(ISO_nl); */
newline();
htmlparser_renderstate(HTMLPARSER_RENDERSTATE_BEGIN |
HTMLPARSER_RENDERSTATE_CENTER);
break;
case TAG_SLASHCENTER:
/* parse_char(ISO_nl);*/
newline();
htmlparser_renderstate(HTMLPARSER_RENDERSTATE_END |
HTMLPARSER_RENDERSTATE_CENTER);
break;
#endif /* WWW_CONF_RENDERSTATE */
}
}
/*-----------------------------------------------------------------------------------*/
static u16_t
parse_word(char *data, u8_t dlen)
{
static u8_t i;
static u8_t len;
unsigned char c;
len = dlen;
switch(s.minorstate) {
case MINORSTATE_TEXT:
for(i = 0; i < len; ++i) {
c = data[i];
if(iswhitespace(c)) {
do_word();
} else if(c == ISO_lt) {
s.minorstate = MINORSTATE_TAG;
s.tagptr = 0;
/* do_word();*/
break;
} else if(c == ISO_ampersand) {
s.minorstate = MINORSTATE_EXTCHAR;
break;
} else {
add_char(c);
}
}
break;
case MINORSTATE_EXTCHAR:
for(i = 0; i < len; ++i) {
c = data[i];
if(c == ISO_semicolon) {
s.minorstate = MINORSTATE_TEXT;
add_char(' ');
break;
} else if(iswhitespace(c)) {
s.minorstate = MINORSTATE_TEXT;
add_char('&');
add_char(' ');
break;
}
}
break;
case MINORSTATE_TAG:
/* We are currently parsing within the name of a tag. We check
for the end of a tag (the '>' character) or whitespace (which
indicates that we should parse a tag attr argument
instead). */
for(i = 0; i < len; ++i) {
c = data[i];
if(c == ISO_gt) {
/* Full tag found. We continue parsing regular text. */
s.minorstate = MINORSTATE_TEXT;
s.tagattrptr = s.tagattrparamptr = 0;
endtagfound();
parse_tag();
break;
} else if(iswhitespace(c)) {
/* The name of the tag found. We continue parsing the tag
attr.*/
s.minorstate = MINORSTATE_TAGATTR;
s.tagattrptr = 0;
endtagfound();
break;
} else {
/* Keep track of the name of the tag, but convert it to
lower case. */
s.tag[s.tagptr] = lowercase(c);
++s.tagptr;
/* Check if the ->tag field is full. If so, we just eat up
any data left in the tag. */
if(s.tagptr == sizeof(s.tag)) {
s.minorstate = MINORSTATE_TAGEND;
break;
}
}
/* Check for HTML comment, indicated by <!-- */
if(s.tagptr == 3 &&
s.tag[0] == ISO_bang &&
s.tag[1] == ISO_dash &&
s.tag[2] == ISO_dash) {
PRINTF(("Starting comment...\n"));
s.minorstate = MINORSTATE_HTMLCOMMENT;
s.tagptr = 0;
endtagfound();
break;
}
}
break;
case MINORSTATE_TAGATTR:
/* We parse the "tag attr", i.e., the "href" in <a
href="...">. */
for(i = 0; i < len; ++i) {
c = data[i];
if(c == ISO_gt) {
/* Full tag found. */
s.minorstate = MINORSTATE_TEXT;
s.tagattrparamptr = 0;
s.tagattrptr = 0;
endtagfound();
parse_tag();
s.tagptr = 0;
endtagfound();
break;
} else if(iswhitespace(c)) {
if(s.tagattrptr == 0) {
/* Discard leading spaces. */
} else {
/* A non-leading space is the end of the attribute. */
s.tagattrparamptr = 0;
endtagfound();
parse_tag();
s.minorstate = MINORSTATE_TAGATTRSPACE;
break;
/* s.tagattrptr = 0;
endtagfound();*/
}
} else if(c == ISO_eq) {
s.minorstate = MINORSTATE_TAGATTRPARAMNQ;
s.tagattrparamptr = 0;
endtagfound();
break;
} else {
s.tagattr[s.tagattrptr] = lowercase(c);
++s.tagattrptr;
/* Check if the "tagattr" field is full. If so, we just eat
up any data left in the tag. */
if(s.tagattrptr == sizeof(s.tagattr)) {
s.minorstate = MINORSTATE_TAGEND;
break;
}
}
}
break;
case MINORSTATE_TAGATTRSPACE:
for(i = 0; i < len; ++i) {
c = data[i];
if(iswhitespace(c)) {
/* Discard spaces. */
} else if(c == ISO_eq) {
s.minorstate = MINORSTATE_TAGATTRPARAMNQ;
s.tagattrparamptr = 0;
endtagfound();
parse_tag();
break;
} else {
s.tagattr[0] = lowercase(c);
s.tagattrptr = 1;
s.minorstate = MINORSTATE_TAGATTR;
break;
}
}
break;
case MINORSTATE_TAGATTRPARAMNQ:
/* We are parsing the "tag attr parameter", i.e., the link part
in <a href="link">. */
for(i = 0; i < len; ++i) {
c = data[i];
if(c == ISO_gt) {
/* Full tag found. */
endtagfound();
parse_tag();
s.minorstate = MINORSTATE_TEXT;
s.tagattrptr = 0;
endtagfound();
parse_tag();
s.tagptr = 0;
endtagfound();
break;
} else if(iswhitespace(c) &&
s.tagattrparamptr == 0) {
/* Discard leading spaces. */
} else if((c == ISO_citation ||
c == ISO_citation2) &&
s.tagattrparamptr == 0) {
s.minorstate = MINORSTATE_TAGATTRPARAM;
s.quotechar = c;
PRINTF(("tag attr param q found\n"));
break;
} else if(iswhitespace(c)) {
PRINTF(("Non-leading space found at %d\n",
s.tagattrparamptr));
/* Stop parsing if a non-leading space was found */
endtagfound();
parse_tag();
s.minorstate = MINORSTATE_TAGATTR;
s.tagattrptr = 0;
endtagfound();
break;
} else {
s.tagattrparam[s.tagattrparamptr] = c;
++s.tagattrparamptr;
/* Check if the "tagattr" field is full. If so, we just eat
up any data left in the tag. */
if(s.tagattrparamptr >= sizeof(s.tagattrparam) - 1) {
s.minorstate = MINORSTATE_TAGEND;
break;
}
}
}
break;
case MINORSTATE_TAGATTRPARAM:
/* We are parsing the "tag attr parameter", i.e., the link
part in <a href="link">. */
for(i = 0; i < len; ++i) {
c = data[i];
if(c == s.quotechar) {
/* Found end of tag attr parameter. */
endtagfound();
parse_tag();
s.minorstate = MINORSTATE_TAGATTR;
s.tagattrptr = 0;
endtagfound();
break;
} else {
if(iswhitespace(c)) {
s.tagattrparam[s.tagattrparamptr] = ISO_space;
} else {
s.tagattrparam[s.tagattrparamptr] = c;
}
++s.tagattrparamptr;
/* Check if the "tagattr" field is full. If so, we just eat
up any data left in the tag. */
if(s.tagattrparamptr >= sizeof(s.tagattrparam) - 1) {
s.minorstate = MINORSTATE_TAGEND;
break;
}
}
}
break;
case MINORSTATE_HTMLCOMMENT:
for(i = 0; i < len; ++i) {
c = data[i];
if(c == ISO_dash) {
++s.tagptr;
} else if(c == ISO_gt && s.tagptr > 0) {
PRINTF(("Comment done.\n"));
s.minorstate = MINORSTATE_TEXT;
break;
} else {
s.tagptr = 0;
}
}
break;
case MINORSTATE_TAGEND:
/* Discard characters until a '>' is seen. */
for(i = 0; i < len; ++i) {
if(data[i] == ISO_gt) {
s.minorstate = MINORSTATE_TEXT;
s.tagattrptr = 0;
endtagfound();
parse_tag();
break;
}
}
break;
default:
i = 0;
break;
}
if(i >= len) {
return len;
}
return i + 1;
}
/*-----------------------------------------------------------------------------------*/
void
htmlparser_parse(char *data, u16_t datalen)
{
u16_t plen;
while(datalen > 0) {
if(datalen > 255) {
plen = parse_word(data, 255);
} else {
plen = parse_word(data, datalen);
}
datalen -= plen;
data += plen;
}
}
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2002, 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 environment
*
* $Id: htmlparser.h,v 1.1 2006/06/17 22:41:13 adamdunkels Exp $
*
*/
#ifndef __HTMLPARSER_H__
#define __HTMLPARSER_H__
#include "contiki-net.h"
/* Callbacks. */
void htmlparser_link(char *text, unsigned char textlen, char *url);
void htmlparser_submitbutton(char *value,
char *name,
char *formname,
char *formaction);
void htmlparser_inputfield(char *value,
char *name,
char *formname,
char *formaction);
void htmlparser_newline(void);
void htmlparser_word(char *word, unsigned char wordlen);
void htmlparser_renderstate(unsigned char state);
#define HTMLPARSER_RENDERSTATE_STATUSMASK 0x80
#define HTMLPARSER_RENDERSTATE_BEGIN 0x00
#define HTMLPARSER_RENDERSTATE_END 0x80
#define HTMLPARSER_RENDERSTATE_NONE 0x00
#define HTMLPARSER_RENDERSTATE_CENTER 0x01
#define HTMLPARSER_RENDERSTATE_TABLE 0x02
#define HTMLPARSER_RENDERSTATE_TR 0x04
#define HTMLPARSER_RENDERSTATE_TD 0x08
#define HTMLPARSER_INPUTTYPE_NONE 0
#define HTMLPARSER_INPUTTYPE_TEXT 1
#define HTMLPARSER_INPUTTYPE_PASSWORD 2
#define HTMLPARSER_INPUTTYPE_SUBMIT 3
#define HTMLPARSER_INPUTTYPE_IMAGE 4
#define HTMLPARSER_INPUTTYPE_OTHER 5
/* Functions. */
void htmlparser_init(void);
void htmlparser_parse(char *data, u16_t len);
#endif /* __HTMLPARSER_H__ */

View file

@ -0,0 +1,32 @@
http_http "http://"
http_200 "200 "
http_301 "301 "
http_302 "302 "
http_get "GET "
http_10 "HTTP/1.0"
http_11 "HTTP/1.1"
http_content_type "content-type: "
http_texthtml "text/html"
http_location "location: "
http_host "host: "
http_crnl "\r\n"
http_index_html "/index.html"
http_404_html "/404.html"
http_header_200 "HTTP/1.0 200 OK\r\nServer: Contiki/1.2-pre0 http://dunkels.com/adam/contiki/\r\nConnection: close\r\n"
http_header_404 "HTTP/1.0 404 Not found\r\nServer: Contiki/1.2-pre0 http://dunkels.com/adam/contiki/\r\nConnection: close\r\n"
http_content_type_html "Content-type: text/html\r\n\r\n"
http_content_type_css "Content-type: text/css\r\n\r\n"
http_content_type_text "Content-type: text/text\r\n\r\n"
http_content_type_png "Content-type: image/png\r\n\r\n"
http_content_type_gif "Content-type: image/gif\r\n\r\n"
http_content_type_jpg "Content-type: image/jpeg\r\n\r\n"
http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"
http_html ".html"
http_htm ".htm"
http_css ".css"
http_png ".png"
http_gif ".gif"
http_jpg ".jpg"
http_text ".text"
http_txt ".txt"

View file

@ -0,0 +1,102 @@
const char http_http[8] =
/* "http://" */
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
const char http_200[5] =
/* "200 " */
{0x32, 0x30, 0x30, 0x20, };
const char http_301[5] =
/* "301 " */
{0x33, 0x30, 0x31, 0x20, };
const char http_302[5] =
/* "302 " */
{0x33, 0x30, 0x32, 0x20, };
const char http_get[5] =
/* "GET " */
{0x47, 0x45, 0x54, 0x20, };
const char http_10[9] =
/* "HTTP/1.0" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };
const char http_11[9] =
/* "HTTP/1.1" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };
const char http_content_type[15] =
/* "content-type: " */
{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, };
const char http_texthtml[10] =
/* "text/html" */
{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };
const char http_location[11] =
/* "location: " */
{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };
const char http_host[7] =
/* "host: " */
{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };
const char http_crnl[3] =
/* "\r\n" */
{0xd, 0xa, };
const char http_index_html[12] =
/* "/index.html" */
{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_404_html[10] =
/* "/404.html" */
{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_referer[9] =
/* "Referer:" */
{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };
const char http_header_200[92] =
/* "HTTP/1.0 200 OK\r\nServer: Contiki/1.2 http://www.sics.se/~adam/contiki/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x31, 0x2e, 0x32, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_header_404[99] =
/* "HTTP/1.0 404 Not found\r\nServer: Contiki/1.2 http://www.sics.se/~adam/contiki/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x31, 0x2e, 0x32, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_content_type_plain[29] =
/* "Content-type: text/plain\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_html[28] =
/* "Content-type: text/html\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_css [27] =
/* "Content-type: text/css\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_text[28] =
/* "Content-type: text/text\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_png [28] =
/* "Content-type: image/png\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_gif [28] =
/* "Content-type: image/gif\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_jpg [29] =
/* "Content-type: image/jpeg\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_binary[43] =
/* "Content-type: application/octet-stream\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, };
const char http_html[6] =
/* ".html" */
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_shtml[7] =
/* ".shtml" */
{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };
const char http_htm[5] =
/* ".htm" */
{0x2e, 0x68, 0x74, 0x6d, };
const char http_css[5] =
/* ".css" */
{0x2e, 0x63, 0x73, 0x73, };
const char http_png[5] =
/* ".png" */
{0x2e, 0x70, 0x6e, 0x67, };
const char http_gif[5] =
/* ".gif" */
{0x2e, 0x67, 0x69, 0x66, };
const char http_jpg[5] =
/* ".jpg" */
{0x2e, 0x6a, 0x70, 0x67, };
const char http_text[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };
const char http_txt[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };

View file

@ -0,0 +1,34 @@
extern const char http_http[8];
extern const char http_200[5];
extern const char http_301[5];
extern const char http_302[5];
extern const char http_get[5];
extern const char http_10[9];
extern const char http_11[9];
extern const char http_content_type[15];
extern const char http_texthtml[10];
extern const char http_location[11];
extern const char http_host[7];
extern const char http_crnl[3];
extern const char http_index_html[12];
extern const char http_404_html[10];
extern const char http_referer[9];
extern const char http_header_200[92];
extern const char http_header_404[99];
extern const char http_content_type_plain[29];
extern const char http_content_type_html[28];
extern const char http_content_type_css [27];
extern const char http_content_type_text[28];
extern const char http_content_type_png [28];
extern const char http_content_type_gif [28];
extern const char http_content_type_jpg [29];
extern const char http_content_type_binary[43];
extern const char http_html[6];
extern const char http_shtml[7];
extern const char http_htm[5];
extern const char http_css[5];
extern const char http_png[5];
extern const char http_gif[5];
extern const char http_jpg[5];
extern const char http_text[5];
extern const char http_txt[5];

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: http-user-agent-string.c,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*/
const char http_user_agent_fields[84] =
/* "Connection: close\r\nUser-Agent: Contiki/1.1 (; http://dunkels.com/adam/contiki/)\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, 0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x31, 0x2e, 0x31, 0x20, 0x28, 0x3b, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x75, 0x6e, 0x6b, 0x65, 0x6c, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x29, 0xd, 0xa, 0xd, 0xa, };

View file

@ -0,0 +1,35 @@
/*
* Copyright (c) 2004, 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. 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.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: http-user-agent-string.h,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*/
extern const char http_user_agent_fields[84];

441
apps/webbrowser/webclient.c Normal file
View file

@ -0,0 +1,441 @@
/*
* Copyright (c) 2002, 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" web browser.
*
* $Id: webclient.c,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*
*/
#include "contiki-net.h"
#include "webclient.h"
#include <string.h>
#define WEBCLIENT_TIMEOUT 100
#define WEBCLIENT_STATE_STATUSLINE 0
#define WEBCLIENT_STATE_HEADERS 1
#define WEBCLIENT_STATE_DATA 2
#define WEBCLIENT_STATE_CLOSE 3
#define HTTPFLAG_NONE 0
#define HTTPFLAG_OK 1
#define HTTPFLAG_MOVED 2
#define HTTPFLAG_ERROR 3
#define ISO_nl 0x0a
#define ISO_cr 0x0d
#define ISO_space 0x20
struct webclient_state {
u8_t timer;
u8_t state;
u8_t httpflag;
u16_t port;
char host[40];
char file[WWW_CONF_MAX_URLLEN];
u16_t getrequestptr;
u16_t getrequestleft;
char httpheaderline[200];
u16_t httpheaderlineptr;
char mimetype[32];
};
static struct webclient_state s;
/*-----------------------------------------------------------------------------------*/
char *
webclient_mimetype(void)
{
return s.mimetype;
}
/*-----------------------------------------------------------------------------------*/
char *
webclient_filename(void)
{
return s.file;
}
/*-----------------------------------------------------------------------------------*/
char *
webclient_hostname(void)
{
return s.host;
}
/*-----------------------------------------------------------------------------------*/
unsigned short
webclient_port(void)
{
return s.port;
}
/*-----------------------------------------------------------------------------------*/
void
webclient_init(void)
{
}
/*-----------------------------------------------------------------------------------*/
static void
init_connection(void)
{
s.state = WEBCLIENT_STATE_STATUSLINE;
s.getrequestleft = sizeof(http_get) - 1 + 1 +
sizeof(http_10) - 1 +
sizeof(http_crnl) - 1 +
sizeof(http_host) - 1 +
sizeof(http_crnl) - 1 +
strlen(http_user_agent_fields) +
strlen(s.file) + strlen(s.host);
s.getrequestptr = 0;
s.httpheaderlineptr = 0;
}
/*-----------------------------------------------------------------------------------*/
void
webclient_close(void)
{
s.state = WEBCLIENT_STATE_CLOSE;
}
/*-----------------------------------------------------------------------------------*/
unsigned char
webclient_get(char *host, u16_t port, char *file)
{
struct uip_conn *conn;
u16_t *ipaddr;
static u16_t addr[2];
/* First check if the host is an IP address. */
ipaddr = &addr[0];
if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) {
ipaddr = resolv_lookup(host);
if(ipaddr == NULL) {
return 0;
}
}
conn = tcp_connect(ipaddr, htons(port), NULL);
if(conn == NULL) {
return 0;
}
s.port = port;
strncpy(s.file, file, sizeof(s.file));
strncpy(s.host, host, sizeof(s.host));
init_connection();
return 1;
}
/*-----------------------------------------------------------------------------------*/
static unsigned char * CC_FASTCALL
copy_string(unsigned char *dest,
const unsigned char *src, unsigned char len)
{
return strcpy(dest, src) + len;
}
/*-----------------------------------------------------------------------------------*/
static void
senddata(void)
{
u16_t len;
char *getrequest;
char *cptr;
if(s.getrequestleft > 0) {
cptr = getrequest = (char *)uip_appdata;
cptr = copy_string(cptr, http_get, sizeof(http_get) - 1);
cptr = copy_string(cptr, s.file, strlen(s.file));
*cptr++ = ISO_space;
cptr = copy_string(cptr, http_10, sizeof(http_10) - 1);
cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
cptr = copy_string(cptr, http_host, sizeof(http_host) - 1);
cptr = copy_string(cptr, s.host, strlen(s.host));
cptr = copy_string(cptr, http_crnl, sizeof(http_crnl) - 1);
cptr = copy_string(cptr, http_user_agent_fields,
strlen(http_user_agent_fields));
len = s.getrequestleft > uip_mss()?
uip_mss():
s.getrequestleft;
uip_send(&(getrequest[s.getrequestptr]), len);
}
}
/*-----------------------------------------------------------------------------------*/
static void
acked(void)
{
u16_t len;
if(s.getrequestleft > 0) {
len = s.getrequestleft > uip_mss()?
uip_mss():
s.getrequestleft;
s.getrequestleft -= len;
s.getrequestptr += len;
}
}
/*-----------------------------------------------------------------------------------*/
static u16_t
parse_statusline(u16_t len)
{
char *cptr;
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
++((char *)uip_appdata);
--len;
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
if((strncmp(s.httpheaderline, http_10,
sizeof(http_10) - 1) == 0) ||
(strncmp(s.httpheaderline, http_11,
sizeof(http_11) - 1) == 0)) {
cptr = &(s.httpheaderline[9]);
s.httpflag = HTTPFLAG_NONE;
if(strncmp(cptr, http_200, sizeof(http_200) - 1) == 0) {
/* 200 OK */
s.httpflag = HTTPFLAG_OK;
} else if(strncmp(cptr, http_301, sizeof(http_301) - 1) == 0 ||
strncmp(cptr, http_302, sizeof(http_302) - 1) == 0) {
/* 301 Moved permanently or 302 Found. Location: header line
will contain thw new location. */
s.httpflag = HTTPFLAG_MOVED;
} else {
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
}
} else {
uip_abort();
webclient_aborted();
return 0;
}
/* We're done parsing the status line, so we reset the pointer
and start parsing the HTTP headers.*/
s.httpheaderlineptr = 0;
s.state = WEBCLIENT_STATE_HEADERS;
break;
} else {
++s.httpheaderlineptr;
}
}
return len;
}
/*-----------------------------------------------------------------------------------*/
static char
casecmp(char *str1, const char *str2, char len)
{
static char c;
while(len > 0) {
c = *str1;
/* Force lower-case characters. */
if(c & 0x40) {
c |= 0x20;
}
if(*str2 != c) {
return 1;
}
++str1;
++str2;
--len;
}
return 0;
}
/*-----------------------------------------------------------------------------------*/
static u16_t
parse_headers(u16_t len)
{
char *cptr;
static unsigned char i;
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
++((char *)uip_appdata);
--len;
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
/* We have an entire HTTP header line in s.httpheaderline, so
we parse it. */
if(s.httpheaderline[0] == ISO_cr) {
/* This was the last header line (i.e., and empty "\r\n"), so
we are done with the headers and proceed with the actual
data. */
s.state = WEBCLIENT_STATE_DATA;
return len;
}
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
/* Check for specific HTTP header fields. */
if(casecmp(s.httpheaderline, http_content_type,
sizeof(http_content_type) - 1) == 0) {
/* Found Content-type field. */
cptr = strchr(s.httpheaderline, ';');
if(cptr != NULL) {
*cptr = 0;
}
strncpy(s.mimetype, s.httpheaderline +
sizeof(http_content_type) - 1, sizeof(s.mimetype));
} else if(casecmp(s.httpheaderline, http_location,
sizeof(http_location) - 1) == 0) {
cptr = s.httpheaderline +
sizeof(http_location) - 1;
if(strncmp(cptr, http_http, 7) == 0) {
cptr += 7;
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
if(*cptr == 0 ||
*cptr == '/' ||
*cptr == ' ' ||
*cptr == ':') {
s.host[i] = 0;
break;
}
s.host[i] = *cptr;
++cptr;
}
}
strncpy(s.file, cptr, sizeof(s.file));
/* s.file[s.httpheaderlineptr - i] = 0;*/
}
/* We're done parsing, so we reset the pointer and start the
next line. */
s.httpheaderlineptr = 0;
} else {
++s.httpheaderlineptr;
}
}
return len;
}
/*-----------------------------------------------------------------------------------*/
static void
newdata(void)
{
u16_t len;
len = uip_datalen();
if(s.state == WEBCLIENT_STATE_STATUSLINE) {
len = parse_statusline(len);
}
if(s.state == WEBCLIENT_STATE_HEADERS && len > 0) {
len = parse_headers(len);
}
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
s.httpflag != HTTPFLAG_MOVED) {
webclient_datahandler((char *)uip_appdata, len);
}
}
/*-----------------------------------------------------------------------------------*/
void
webclient_appcall(void *state)
{
if(uip_connected()) {
s.timer = 0;
s.state = WEBCLIENT_STATE_STATUSLINE;
senddata();
webclient_connected();
tcp_markconn(uip_conn, &s);
return;
}
if(uip_timedout()) {
webclient_timedout();
}
if(state == NULL) {
uip_abort();
return;
}
if(s.state == WEBCLIENT_STATE_CLOSE) {
webclient_closed();
uip_abort();
return;
}
if(uip_aborted()) {
webclient_aborted();
}
if(uip_acked()) {
s.timer = 0;
acked();
}
if(uip_newdata()) {
s.timer = 0;
newdata();
}
if(uip_rexmit() ||
uip_newdata() ||
uip_acked()) {
senddata();
} else if(uip_poll()) {
++s.timer;
if(s.timer == WEBCLIENT_TIMEOUT) {
webclient_timedout();
uip_abort();
return;
}
/* senddata();*/
}
if(uip_closed()) {
tcp_markconn(uip_conn, NULL);
if(s.httpflag != HTTPFLAG_MOVED) {
/* Send NULL data to signal EOF. */
webclient_datahandler(NULL, 0);
} else {
/* conn = uip_connect(uip_conn->ripaddr, s.port);
if(conn != NULL) {
dispatcher_markconn(conn, NULL);
init_connection();
}*/
if(resolv_lookup(s.host) == NULL) {
resolv_query(s.host);
}
webclient_get(s.host, s.port, s.file);
}
}
}
/*-----------------------------------------------------------------------------------*/

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2002, 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" web browser.
*
* $Id: webclient.h,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*
*/
#ifndef __WEBCLIENT_H__
#define __WEBCLIENT_H__
#include "contiki-net.h"
#include "http-strings.h"
#include "http-user-agent-string.h"
/* Callback functions that have to be implemented by the application
program. */
struct webclient_state;
void webclient_datahandler(char *data, u16_t len);
void webclient_connected(void);
void webclient_timedout(void);
void webclient_aborted(void);
void webclient_closed(void);
/* Functions. */
void webclient_init(void);
unsigned char webclient_get(char *host, u16_t port, char *file);
void webclient_close(void);
void webclient_appcall(void *state);
/*DISPATCHER_UIPCALL(webclient_appcall, state);*/
char *webclient_mimetype(void);
char *webclient_filename(void);
char *webclient_hostname(void);
unsigned short webclient_port(void);
#endif /* __WEBCLIENT_H__ */

74
apps/webbrowser/www-dsc.c Normal file
View file

@ -0,0 +1,74 @@
/*
* 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 environment
*
* $Id: www-dsc.c,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*
*/
#include "sys/dsc.h"
extern struct ctk_icon www_icon;
/*-----------------------------------------------------------------------------------*/
DSC(www_dsc,
"The Contiki web browser",
"www.prg",
www_process,
&www_icon);
/*-----------------------------------------------------------------------------------*/
#if CTK_CONF_ICON_BITMAPS
static unsigned char wwwicon_bitmap[3*3*8] = {
0x00, 0x7e, 0x40, 0x73, 0x46, 0x4c, 0x18, 0x13,
0x00, 0x00, 0xff, 0x81, 0x34, 0xc9, 0x00, 0xb6,
0x00, 0x7e, 0x02, 0xce, 0x72, 0x32, 0x18, 0x48,
0x30, 0x27, 0x24, 0x20, 0x37, 0x24, 0x20, 0x33,
0x00, 0x7b, 0x42, 0x00, 0x7b, 0x42, 0x00, 0x3b,
0x0c, 0x24, 0x24, 0x04, 0xa4, 0x24, 0x04, 0x4c,
0x12, 0x19, 0x4c, 0x46, 0x63, 0x40, 0x7c, 0x00,
0x22, 0x91, 0x00, 0xc4, 0x81, 0xff, 0x00, 0x00,
0x08, 0x18, 0x32, 0x62, 0xc6, 0x02, 0x3e, 0x00
};
#endif /* CTK_CONF_ICON_BITMAPS */
#if CTK_CONF_ICON_TEXTMAPS
static char wwwicon_textmap[9] = {
'w', 'w', 'w',
'(', ')', ' ',
' ', '(', ')'
};
#endif /* CTK_CONF_ICON_TEXTMAPS */
#if CTK_CONF_ICONS
static struct ctk_icon www_icon =
{CTK_ICON("Web browser", wwwicon_bitmap, wwwicon_textmap)};
#endif /* CTK_CONF_ICONS */
/*-----------------------------------------------------------------------------------*/

42
apps/webbrowser/www-dsc.h Normal file
View file

@ -0,0 +1,42 @@
/*
* 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 environment
*
* $Id: www-dsc.h,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*
*/
#ifndef __WWW_DSC_H__
#define __WWW_DSC_H__
#include "sys/dsc.h"
DSC_HEADER(www_dsc);
#endif /* __WWW_DSC_H__ */

950
apps/webbrowser/www.c Normal file
View file

@ -0,0 +1,950 @@
/*
* Copyright (c) 2002, 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 environment
*
* $Id: www.c,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*
*/
#include <string.h>
#include "ctk/ctk.h"
#include "contiki-net.h"
#include "webclient.h"
#include "htmlparser.h"
#include "http-strings.h"
#include "lib/petsciiconv.h"
#include "program-handler.h"
#if 1
#define PRINTF(x)
#else
#include <stdio.h>
#define PRINTF(x) printf x
#endif
/* The array that holds the current URL. */
static char url[WWW_CONF_MAX_URLLEN + 1];
static char tmpurl[WWW_CONF_MAX_URLLEN + 1];
/* The array that holds the web page text. */
static char webpage[WWW_CONF_WEBPAGE_WIDTH *
WWW_CONF_WEBPAGE_HEIGHT + 1];
/* The CTK widgets for the main window. */
static struct ctk_window mainwindow;
static struct ctk_button backbutton =
{CTK_BUTTON(0, 0, 4, "Back")};
static struct ctk_button downbutton =
{CTK_BUTTON(10, 0, 4, "Down")};
static struct ctk_button stopbutton =
{CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 16, 0, 4, "Stop")};
static struct ctk_button gobutton =
{CTK_BUTTON(WWW_CONF_WEBPAGE_WIDTH - 4, 0, 2, "Go")};
static struct ctk_separator sep1 =
{CTK_SEPARATOR(0, 2, WWW_CONF_WEBPAGE_WIDTH)};
static char editurl[WWW_CONF_MAX_URLLEN + 1];
static struct ctk_textentry urlentry =
{CTK_TEXTENTRY(0, 1, WWW_CONF_WEBPAGE_WIDTH - 2,
1, editurl, WWW_CONF_MAX_URLLEN)};
static struct ctk_label webpagelabel =
{CTK_LABEL(0, 3, WWW_CONF_WEBPAGE_WIDTH,
WWW_CONF_WEBPAGE_HEIGHT, webpage)};
static char statustexturl[WWW_CONF_WEBPAGE_WIDTH];
static struct ctk_label statustext =
{CTK_LABEL(0, WWW_CONF_WEBPAGE_HEIGHT + 4,
WWW_CONF_WEBPAGE_WIDTH, 1, "")};
static struct ctk_separator sep2 =
{CTK_SEPARATOR(0, WWW_CONF_WEBPAGE_HEIGHT + 3,
WWW_CONF_WEBPAGE_WIDTH)};
static struct ctk_window wgetdialog;
static struct ctk_label wgetlabel1 =
{CTK_LABEL(1, 1, 34, 1, "This web page cannot be displayed.")};
static struct ctk_label wgetlabel2 =
{CTK_LABEL(1, 3, 35, 1, "Would you like to download instead?")};
static struct ctk_button wgetnobutton =
{CTK_BUTTON(1, 5, 6, "Cancel")};
static struct ctk_button wgetyesbutton =
{CTK_BUTTON(11, 5, 24, "Close browser & download")};
/* The char arrays that hold the history of visited URLs. */
static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];
static char history_last;
/* The CTK widget definitions for the hyperlinks and the char arrays
that hold the link URLs. */
struct formattribs {
char formaction[WWW_CONF_MAX_FORMACTIONLEN];
char formname[WWW_CONF_MAX_FORMNAMELEN];
#define FORMINPUTTYPE_SUBMITBUTTON 1
#define FORMINPUTTYPE_INPUTFIELD 2
unsigned char inputtype;
char inputname[WWW_CONF_MAX_INPUTNAMELEN];
char *inputvalue;
};
union pagewidgetattrib {
char url[WWW_CONF_MAX_URLLEN];
#if WWW_CONF_FORMS
struct formattribs form;
#endif /* WWW_CONF_FORMS */
};
static struct ctk_widget pagewidgets[WWW_CONF_MAX_NUMPAGEWIDGETS];
static union pagewidgetattrib pagewidgetattribs[WWW_CONF_MAX_NUMPAGEWIDGETS];
static unsigned char pagewidgetptr;
#if WWW_CONF_RENDERSTATE
static unsigned char renderstate;
#endif /* WWW_CONF_RENDERSTATE */
#define ISO_nl 0x0a
#define ISO_space 0x20
#define ISO_ampersand 0x26
#define ISO_plus 0x2b
#define ISO_slash 0x2f
#define ISO_eq 0x3d
#define ISO_questionmark 0x3f
/* The state of the rendering code. */
static char *webpageptr;
static unsigned char x, y;
static unsigned char loading;
static unsigned short firsty, pagey;
static unsigned char count;
static char receivingmsgs[4][23] = {
"Receiving web page ...",
"Receiving web page. ..",
"Receiving web page.. .",
"Receiving web page... "
};
PROCESS(www_process, "Web browser");
static void formsubmit(struct formattribs *attribs);
/*-----------------------------------------------------------------------------------*/
/* make_window()
*
* Creates the web browser's window.
*/
static void
make_window(void)
{
CTK_WIDGET_ADD(&mainwindow, &backbutton);
CTK_WIDGET_ADD(&mainwindow, &downbutton);
CTK_WIDGET_ADD(&mainwindow, &stopbutton);
CTK_WIDGET_ADD(&mainwindow, &gobutton);
CTK_WIDGET_ADD(&mainwindow, &urlentry);
CTK_WIDGET_ADD(&mainwindow, &sep1);
CTK_WIDGET_ADD(&mainwindow, &webpagelabel);
CTK_WIDGET_SET_FLAG(&webpagelabel, CTK_WIDGET_FLAG_MONOSPACE);
CTK_WIDGET_ADD(&mainwindow, &sep2);
CTK_WIDGET_ADD(&mainwindow, &statustext);
pagewidgetptr = 0;
}
/*-----------------------------------------------------------------------------------*/
/* redraw_window():
*
* Convenience function that calls upon CTK to redraw the browser
* window. */
static void
redraw_window(void)
{
ctk_window_redraw(&mainwindow);
}
/*-----------------------------------------------------------------------------------*/
static void
clear_page(void)
{
ctk_window_clear(&mainwindow);
make_window();
redraw_window();
memset(webpage, 0, WWW_CONF_WEBPAGE_WIDTH * WWW_CONF_WEBPAGE_HEIGHT);
}
/*-----------------------------------------------------------------------------------*/
static void
show_url(void)
{
memcpy(editurl, url, WWW_CONF_MAX_URLLEN);
strncpy(editurl, "http://", 7);
petsciiconv_topetscii(editurl + 7, WWW_CONF_MAX_URLLEN - 7);
CTK_WIDGET_REDRAW(&urlentry);
}
static void
start_loading(void)
{
loading = 1;
x = y = 0;
pagey = 0;
webpageptr = webpage;
clear_page();
}
/*-----------------------------------------------------------------------------------*/
static void
show_statustext(char *text)
{
ctk_label_set_text(&statustext, text);
CTK_WIDGET_REDRAW(&statustext);
}
/*-----------------------------------------------------------------------------------*/
/* open_url():
*
* Called when the URL present in the global "url" variable should be
* opened. It will call the hostname resolver as well as the HTTP
* client requester.
*/
static void
open_url(void)
{
unsigned char i;
static char host[32];
char *file;
register char *urlptr;
static u16_t addr[2];
/* Trim off any spaces in the end of the url. */
urlptr = url + strlen(url) - 1;
while(*urlptr == ' ' && urlptr > url) {
*urlptr = 0;
--urlptr;
}
/* Don't even try to go further if the URL is empty. */
if(urlptr == url) {
return;
}
/* See if the URL starts with http://, otherwise prepend it. */
if(strncmp(url, http_http, 7) != 0) {
while(urlptr >= url) {
*(urlptr + 7) = *urlptr;
--urlptr;
}
strncpy(url, http_http, 7);
}
/* Find host part of the URL. */
urlptr = &url[7];
for(i = 0; i < sizeof(host); ++i) {
if(*urlptr == 0 ||
*urlptr == '/' ||
*urlptr == ' ' ||
*urlptr == ':') {
host[i] = 0;
break;
}
host[i] = *urlptr;
++urlptr;
}
/* XXX: Here we should find the port part of the URL, but this isn't
currently done because of laziness from the programmer's side
:-) */
/* Find file part of the URL. */
while(*urlptr != '/' && *urlptr != 0) {
++urlptr;
}
if(*urlptr == '/') {
file = urlptr;
} else {
file = "/";
}
/* Try to lookup the hostname. If it fails, we initiate a hostname
lookup and print out an informative message on the statusbar. */
if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) {
if(resolv_lookup(host) == NULL) {
resolv_query(host);
show_statustext("Resolving host...");
return;
}
}
/* The hostname we present in the hostname table, so we send out the
initial GET request. */
if(webclient_get(host, 80, file) == 0) {
show_statustext("Out of memory error.");
} else {
show_statustext("Connecting...");
}
redraw_window();
}
/*-----------------------------------------------------------------------------------*/
/* open_link(link):
*
* Will format a link from the current web pages so that it suits the
* open_url() function and finally call it to open the requested URL.
*/
static void
open_link(char *link)
{
char *urlptr;
if(strncmp(link, http_http, 7) == 0) {
/* The link starts with http://. We just copy the contents of the
link into the url string and jump away. */
strncpy(url, link, WWW_CONF_MAX_URLLEN);
} else if(*link == ISO_slash &&
*(link + 1) == ISO_slash) {
/* The link starts with //, so we'll copy it into the url
variable, starting after the http (which already is present in
the url variable since we were able to open the web page on
which this link was found in the first place). */
strncpy(&url[5], link, WWW_CONF_MAX_URLLEN);
} else if(*link == ISO_slash) {
/* The link starts with a slash, so it is a non-relative link
within the same web site. We find the start of the filename of
the current URL and paste the contents of this link there, and
head off to the new URL. */
for(urlptr = &url[7];
*urlptr != 0 && *urlptr != ISO_slash;
++urlptr);
strncpy(urlptr, link, WWW_CONF_MAX_URLLEN - (urlptr - url));
} else {
/* A fully relative link is found. We find the last slash in the
current URL and paste the link there. */
/* XXX: we should really parse any ../ in the link as well. */
for(urlptr = url + strlen(url);
urlptr != url && *urlptr != ISO_slash;
--urlptr);
++urlptr;
strncpy(urlptr, link, WWW_CONF_MAX_URLLEN - (urlptr - url));
}
/* Open the URL. */
show_url();
open_url();
start_loading();
}
/*-----------------------------------------------------------------------------------*/
/* log_back():
*
* Copies the current URL from the url variable and into the log for
* the back button.
*/
static void
log_back(void)
{
if(strncmp(url, history[(int)history_last], WWW_CONF_MAX_URLLEN) != 0) {
memcpy(history[(int)history_last], url, WWW_CONF_MAX_URLLEN);
++history_last;
if(history_last >= WWW_CONF_HISTORY_SIZE) {
history_last = 0;
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
quit(void)
{
ctk_window_close(&mainwindow);
process_exit(&www_process);
LOADER_UNLOAD();
}
/*-----------------------------------------------------------------------------------*/
/* www_dispatcher():
*
* The program's signal dispatcher function. Is called by the ek
* dispatcher whenever a signal arrives.
*/
PROCESS_THREAD(www_process, ev, data)
{
static struct ctk_widget *w;
static unsigned char i;
static char *argptr;
w = (struct ctk_widget *)data;
PROCESS_BEGIN();
/* Create the main window. */
memset(webpage, 0, sizeof(webpage));
ctk_window_new(&mainwindow, WWW_CONF_WEBPAGE_WIDTH,
WWW_CONF_WEBPAGE_HEIGHT+5, "Web browser");
make_window();
#ifdef WWW_CONF_HOMEPAGE
strncpy(editurl, WWW_CONF_HOMEPAGE, sizeof(editurl));
#endif /* WWW_CONF_HOMEPAGE */
CTK_WIDGET_FOCUS(&mainwindow, &urlentry);
/* Create download dialog.*/
ctk_dialog_new(&wgetdialog, 38, 7);
CTK_WIDGET_ADD(&wgetdialog, &wgetlabel1);
CTK_WIDGET_ADD(&wgetdialog, &wgetlabel2);
CTK_WIDGET_ADD(&wgetdialog, &wgetnobutton);
CTK_WIDGET_ADD(&wgetdialog, &wgetyesbutton);
ctk_window_open(&mainwindow);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
webclient_appcall(data);
} else if(ev == ctk_signal_widget_activate) {
if(w == (struct ctk_widget *)&backbutton) {
firsty = 0;
start_loading();
--history_last;
if(history_last > WWW_CONF_HISTORY_SIZE) {
history_last = WWW_CONF_HISTORY_SIZE - 1;
}
memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN);
open_url();
CTK_WIDGET_FOCUS(&mainwindow, &backbutton);
} else if(w == (struct ctk_widget *)&downbutton) {
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4;
start_loading();
open_url();
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
} else if(w == (struct ctk_widget *)&gobutton ||
w == (struct ctk_widget *)&urlentry) {
start_loading();
firsty = 0;
log_back();
memcpy(url, editurl, WWW_CONF_MAX_URLLEN);
petsciiconv_toascii(url, WWW_CONF_MAX_URLLEN);
open_url();
CTK_WIDGET_FOCUS(&mainwindow, &gobutton);
} else if(w == (struct ctk_widget *)&stopbutton) {
loading = 0;
webclient_close();
} else if(w == (struct ctk_widget *)&wgetnobutton) {
ctk_dialog_close();
} else if(w == (struct ctk_widget *)&wgetyesbutton) {
ctk_dialog_close();
quit();
argptr = arg_alloc(WWW_CONF_MAX_URLLEN);
if(argptr != NULL) {
strncpy(argptr, url, WWW_CONF_MAX_URLLEN);
}
program_handler_load("wget.prg", argptr);
#if WWW_CONF_FORMS
} else {
/* Check form buttons */
for(i = 0; i < pagewidgetptr; ++i) {
if(&pagewidgets[i] == w) {
formsubmit(&pagewidgetattribs[i].form);
/* show_statustext(pagewidgetattribs[i].form.formaction);*/
/* PRINTF(("Formaction %s formname %s inputname %s\n",
pagewidgetattribs[i].form.formaction,
pagewidgetattribs[i].form.formname,
pagewidgetattribs[i].form.inputname));*/
break;
}
}
#endif /* WWW_CONF_FORMS */
}
} else if(ev == ctk_signal_hyperlink_activate) {
firsty = 0;
log_back();
open_link(w->widget.hyperlink.url);
CTK_WIDGET_FOCUS(&mainwindow, &stopbutton);
/* ctk_window_open(&mainwindow);*/
} else if(ev == ctk_signal_hyperlink_hover) {
if(CTK_WIDGET_TYPE((struct ctk_widget *)data) ==
CTK_WIDGET_HYPERLINK) {
strncpy(statustexturl, w->widget.hyperlink.url,
sizeof(statustexturl));
petsciiconv_topetscii(statustexturl, sizeof(statustexturl));
show_statustext(statustexturl);
}
} else if(ev == resolv_event_found) {
/* Either found a hostname, or not. */
if((char *)data != NULL &&
resolv_lookup((char *)data) != NULL) {
open_url();
} else {
show_statustext("Host not found.");
}
} else if(ev == ctk_signal_window_close ||
ev == PROCESS_EVENT_EXIT) {
quit();
}
}
PROCESS_END();
}
/*-----------------------------------------------------------------------------------*/
/* set_url():
*
* Constructs an URL from the arguments and puts it into the global
* "url" variable and the visible "editurl" (which is shown in the URL
* text entry widget in the browser window).
*/
static void
set_url(char *host, u16_t port, char *file)
{
char *urlptr;
memset(url, 0, WWW_CONF_MAX_URLLEN);
if(strncmp(file, http_http, 7) == 0) {
strncpy(url, file, sizeof(url));
} else {
strncpy(url, http_http, 7);
urlptr = url + 7;
strcpy(urlptr, host);
urlptr += strlen(host);
strcpy(urlptr, file);
}
show_url();
}
/*-----------------------------------------------------------------------------------*/
/* webclient_aborted():
*
* Callback function. Called from the webclient when the HTTP
* connection was abruptly aborted.
*/
void
webclient_aborted(void)
{
show_statustext("Connection reset by peer");
}
/*-----------------------------------------------------------------------------------*/
/* webclient_timedout():
*
* Callback function. Called from the webclient when the HTTP
* connection timed out.
*/
void
webclient_timedout(void)
{
show_statustext("Connection timed out");
}
/*-----------------------------------------------------------------------------------*/
/* webclient_closed():
*
* Callback function. Called from the webclient when the HTTP
* connection was closed after a request from the "webclient_close()"
* function. .
*/
void
webclient_closed(void)
{
show_statustext("Stopped.");
petsciiconv_topetscii(&webpage[(WWW_CONF_WEBPAGE_HEIGHT - 1) *
WWW_CONF_WEBPAGE_WIDTH], WWW_CONF_WEBPAGE_WIDTH);
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
redraw_window();
}
/*-----------------------------------------------------------------------------------*/
/* webclient_closed():
*
* Callback function. Called from the webclient when the HTTP
* connection is connected.
*/
void
webclient_connected(void)
{
start_loading();
clear_page();
show_statustext("Request sent...");
set_url(webclient_hostname(), webclient_port(), webclient_filename());
#if WWW_CONF_RENDERSTATE
renderstate = HTMLPARSER_RENDERSTATE_NONE;
#endif /* WWW_CONF_RENDERSTATE */
htmlparser_init();
}
/*-----------------------------------------------------------------------------------*/
/* webclient_datahandler():
*
* Callback function. Called from the webclient module when HTTP data
* has arrived.
*/
void
webclient_datahandler(char *data, u16_t len)
{
if(len > 0) {
if(strcmp(webclient_mimetype(), http_texthtml) == 0) {
count = (count + 1) & 3;
show_statustext(receivingmsgs[count]);
htmlparser_parse(data, len);
redraw_window();
} else {
uip_abort();
ctk_dialog_open(&wgetdialog);
}
} else {
/* Clear remaining parts of page. */
loading = 0;
}
if(data == NULL) {
loading = 0;
show_statustext("Done.");
petsciiconv_topetscii(&webpage[(WWW_CONF_WEBPAGE_HEIGHT - 1) *
WWW_CONF_WEBPAGE_WIDTH], WWW_CONF_WEBPAGE_WIDTH);
CTK_WIDGET_FOCUS(&mainwindow, &urlentry);
redraw_window();
}
}
/*-----------------------------------------------------------------------------------*/
static void *
add_pagewidget(char *text, unsigned char len, unsigned char type,
unsigned char border)
{
register struct ctk_widget *lptr;
register unsigned char *wptr;
static unsigned char maxwidth;
static void *dataptr;
if(!loading) {
return NULL;
}
if(len + border == 0) {
return NULL;
}
maxwidth = WWW_CONF_WEBPAGE_WIDTH - (1 + 2 * border);
/* If the text of the link is too long so that it does not fit into
the width of the current window, counting from the current x
coordinate, we first try to jump to the next line. */
if(len + x > maxwidth) {
htmlparser_newline();
if(!loading) {
return NULL;
}
}
/* If the text of the link still is too long, we just chop it off!
XXX: this is not really the right thing to do, we should probably
either make a link into a multiline link, or add multiple
buttons. But this will do for now. */
if(len > maxwidth) {
text[maxwidth] = 0;
len = maxwidth;
}
dataptr = NULL;
if(firsty == pagey) {
wptr = webpageptr;
/* To save memory, we'll copy the widget text to the web page
drawing area and reference it from there. */
wptr[0] = 0;
wptr += border;
memcpy(wptr, text, len);
wptr[len] = 0;
wptr[len + border] = ' ';
if(pagewidgetptr < WWW_CONF_MAX_NUMPAGEWIDGETS) {
dataptr = &pagewidgetattribs[pagewidgetptr];
lptr = &pagewidgets[pagewidgetptr];
switch(type) {
case CTK_WIDGET_HYPERLINK:
CTK_HYPERLINK_NEW((struct ctk_hyperlink *)lptr, x,
y + 3, len,
wptr, dataptr);
break;
case CTK_WIDGET_BUTTON:
CTK_BUTTON_NEW((struct ctk_button *)lptr, x,
y + 3, len,
wptr);
((struct formattribs *)dataptr)->inputvalue = wptr;
break;
case CTK_WIDGET_TEXTENTRY:
CTK_TEXTENTRY_NEW((struct ctk_textentry *)lptr, x,
y + 3, len, 1,
wptr, len);
((struct formattribs *)dataptr)->inputvalue = wptr;
break;
}
CTK_WIDGET_SET_FLAG(lptr, CTK_WIDGET_FLAG_MONOSPACE);
CTK_WIDGET_ADD(&mainwindow, lptr);
++pagewidgetptr;
}
}
/* Increase the x coordinate with the length of the link text plus
the extra space behind it and the CTK button markers. */
len = len + 1 + 2 * border;
x += len;
if(firsty == pagey) {
webpageptr += len;
}
if(x == WWW_CONF_WEBPAGE_WIDTH) {
htmlparser_newline();
}
return dataptr;
}
/*-----------------------------------------------------------------------------------*/
#if WWW_CONF_RENDERSTATE
static void
centerline(char *wptr)
{
unsigned char spaces, i;
char *cptr;
register struct ctk_widget *linksptr;
cptr = wptr + WWW_CONF_WEBPAGE_WIDTH;
for(spaces = 0; spaces < WWW_CONF_WEBPAGE_WIDTH; ++spaces) {
if(*--cptr != 0) {
break;
}
}
spaces /= 2;
while(cptr >= wptr) {
*(cptr + spaces) = *cptr;
--cptr;
}
memset(wptr, ' ', spaces);
linksptr = pagewidgets;
for(i = 0; i < pagewidgetptr; ++i) {
if(CTK_WIDGET_YPOS(linksptr) == y + 2) {
linksptr->x += spaces;
linksptr->widget.hyperlink.text += spaces;
}
++linksptr;
}
}
#endif /* WWW_CONF_RENDERSTATE */
/*-----------------------------------------------------------------------------------*/
void
htmlparser_newline(void)
{
char *wptr;
if(pagey < firsty) {
++pagey;
x = 0;
return;
}
if(!loading) {
return;
}
webpageptr += (WWW_CONF_WEBPAGE_WIDTH - x);
++y;
x = 0;
wptr = webpageptr - WWW_CONF_WEBPAGE_WIDTH;
petsciiconv_topetscii(wptr,
WWW_CONF_WEBPAGE_WIDTH);
#if WWW_CONF_RENDERSTATE
if(renderstate & HTMLPARSER_RENDERSTATE_CENTER) {
centerline(wptr);
}
#endif /* WWW_CONF_RENDERSTATE */
if(y == WWW_CONF_WEBPAGE_HEIGHT) {
loading = 0;
webclient_close();
}
}
/*-----------------------------------------------------------------------------------*/
void
htmlparser_word(char *word, unsigned char wordlen)
{
if(loading) {
if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
htmlparser_newline();
}
if(loading) {
if(pagey == firsty) {
memcpy(webpageptr, word, wordlen);
webpageptr += wordlen;
*webpageptr = ' ';
++webpageptr;
}
x += wordlen + 1;
if(x == WWW_CONF_WEBPAGE_WIDTH) {
htmlparser_newline();
}
}
}
}
/*-----------------------------------------------------------------------------------*/
void
htmlparser_link(char *text, unsigned char textlen, char *url)
{
static unsigned char *linkurlptr;
linkurlptr = add_pagewidget(text, textlen, CTK_WIDGET_HYPERLINK, 0);
if(linkurlptr != NULL &&
strlen(url) < WWW_CONF_MAX_URLLEN) {
strcpy(linkurlptr, url);
}
}
/*-----------------------------------------------------------------------------------*/
#if WWW_CONF_RENDERSTATE
void
htmlparser_renderstate(unsigned char s)
{
if((s & HTMLPARSER_RENDERSTATE_STATUSMASK) ==
HTMLPARSER_RENDERSTATE_BEGIN) {
renderstate |= s & ~HTMLPARSER_RENDERSTATE_STATUSMASK;
} else {
renderstate &= ~(s & ~HTMLPARSER_RENDERSTATE_STATUSMASK);
}
}
#endif /* WWW_CONF_RENDERSTATE */
#if WWW_CONF_FORMS
/*-----------------------------------------------------------------------------------*/
void
htmlparser_submitbutton(char *text, char *name,
char *formname, char *formaction)
{
register struct formattribs *form;
form = add_pagewidget(text, strlen(text), CTK_WIDGET_BUTTON, 1);
if(form != NULL) {
strncpy(form->formaction, formaction, WWW_CONF_MAX_FORMACTIONLEN);
strncpy(form->formname, formname, WWW_CONF_MAX_FORMNAMELEN);
strncpy(form->inputname, name, WWW_CONF_MAX_INPUTNAMELEN);
form->inputtype = FORMINPUTTYPE_SUBMITBUTTON;
}
}
/*-----------------------------------------------------------------------------------*/
void
htmlparser_inputfield(char *text, char *name,
char *formname, char *formaction)
{
register struct formattribs *form;
form = add_pagewidget(text, strlen(text), CTK_WIDGET_TEXTENTRY, 1);
if(form != NULL) {
strncpy(form->formaction, formaction, WWW_CONF_MAX_FORMACTIONLEN);
strncpy(form->formname, formname, WWW_CONF_MAX_FORMNAMELEN);
strncpy(form->inputname, name, WWW_CONF_MAX_INPUTNAMELEN);
form->inputtype = FORMINPUTTYPE_INPUTFIELD;
}
}
/*-----------------------------------------------------------------------------------*/
static void
formsubmit(struct formattribs *attribs)
{
unsigned char i, j;
register char *urlptr, *valueptr;
register struct formattribs *faptr;
urlptr = &tmpurl[0];
strncpy(urlptr, attribs->formaction, WWW_CONF_MAX_URLLEN);
tmpurl[WWW_CONF_MAX_URLLEN] = 0;
urlptr += strlen(urlptr);
*urlptr = ISO_questionmark;
++urlptr;
/* Construct an URL by finding all input field forms with the same
formname as the current submit button, and add the submit button
URL stuff as well. */
for(i = 0; i < pagewidgetptr; ++i) {
if(urlptr - &tmpurl[0] >= WWW_CONF_MAX_URLLEN) {
break;
}
faptr = &pagewidgetattribs[i].form;
if(strcmp(attribs->formaction, faptr->formaction) == 0 &&
strcmp(attribs->formname, faptr->formname) == 0 &&
(faptr->inputtype == FORMINPUTTYPE_INPUTFIELD ||
faptr == attribs)) {
/* Copy the name of the input field into the URL and append a
questionmark. */
strncpy(urlptr, faptr->inputname, WWW_CONF_MAX_URLLEN - strlen(tmpurl));
tmpurl[WWW_CONF_MAX_URLLEN] = 0;
urlptr += strlen(urlptr);
*urlptr = ISO_eq;
++urlptr;
/* Convert and copy the contents of the input field to the URL
and append an ampersand. */
valueptr = pagewidgets[i].widget.textentry.text;
petsciiconv_toascii(valueptr, WWW_CONF_MAX_INPUTVALUELEN);
for(j = 0; j < WWW_CONF_MAX_INPUTVALUELEN; ++j) {
if(urlptr - &tmpurl[0] >= WWW_CONF_MAX_URLLEN) {
break;
}
*urlptr = *valueptr;
if(*urlptr == ISO_space) {
*urlptr = ISO_plus;
}
if(*urlptr == 0) {
break;
}
++urlptr;
++valueptr;
}
*urlptr = ISO_ampersand;
++urlptr;
}
}
--urlptr;
*urlptr = 0;
log_back();
open_link(tmpurl);
}
/*-----------------------------------------------------------------------------------*/
#endif /* WWW_CONF_FORMS */

40
apps/webbrowser/www.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2002, 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 environment for the C64.
*
* $Id: www.h,v 1.1 2006/06/17 22:41:14 adamdunkels Exp $
*
*/
#ifndef __WWW_H__
#define __WWW_H__
void www_init(void);
#endif /* __WWW_H__ */

View file

@ -0,0 +1,3 @@
APP_SOURCES += webserver.c webserver-nogui.c httpd.c http-strings.c psock.c uipbuf.c \
memb.c httpd-fs.c httpd-cgi.c
DSC_SOURCES += webserver-dsc.c

View file

@ -0,0 +1,102 @@
const char http_http[8] =
/* "http://" */
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
const char http_200[5] =
/* "200 " */
{0x32, 0x30, 0x30, 0x20, };
const char http_301[5] =
/* "301 " */
{0x33, 0x30, 0x31, 0x20, };
const char http_302[5] =
/* "302 " */
{0x33, 0x30, 0x32, 0x20, };
const char http_get[5] =
/* "GET " */
{0x47, 0x45, 0x54, 0x20, };
const char http_10[9] =
/* "HTTP/1.0" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };
const char http_11[9] =
/* "HTTP/1.1" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };
const char http_content_type[15] =
/* "content-type: " */
{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, };
const char http_texthtml[10] =
/* "text/html" */
{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };
const char http_location[11] =
/* "location: " */
{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };
const char http_host[7] =
/* "host: " */
{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };
const char http_crnl[3] =
/* "\r\n" */
{0xd, 0xa, };
const char http_index_html[12] =
/* "/index.html" */
{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_404_html[10] =
/* "/404.html" */
{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_referer[9] =
/* "Referer:" */
{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };
const char http_header_200[92] =
/* "HTTP/1.0 200 OK\r\nServer: Contiki/1.2 http://www.sics.se/~adam/contiki/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x31, 0x2e, 0x32, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_header_404[99] =
/* "HTTP/1.0 404 Not found\r\nServer: Contiki/1.2 http://www.sics.se/~adam/contiki/\r\nConnection: close\r\n" */
{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0x31, 0x2e, 0x32, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x69, 0x63, 0x73, 0x2e, 0x73, 0x65, 0x2f, 0x7e, 0x61, 0x64, 0x61, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6b, 0x69, 0x2f, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
const char http_content_type_plain[29] =
/* "Content-type: text/plain\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_html[28] =
/* "Content-type: text/html\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_css [27] =
/* "Content-type: text/css\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_text[28] =
/* "Content-type: text/text\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_png [28] =
/* "Content-type: image/png\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_gif [28] =
/* "Content-type: image/gif\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_jpg [29] =
/* "Content-type: image/jpeg\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, };
const char http_content_type_binary[43] =
/* "Content-type: application/octet-stream\r\n\r\n" */
{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, };
const char http_html[6] =
/* ".html" */
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
const char http_shtml[7] =
/* ".shtml" */
{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };
const char http_htm[5] =
/* ".htm" */
{0x2e, 0x68, 0x74, 0x6d, };
const char http_css[5] =
/* ".css" */
{0x2e, 0x63, 0x73, 0x73, };
const char http_png[5] =
/* ".png" */
{0x2e, 0x70, 0x6e, 0x67, };
const char http_gif[5] =
/* ".gif" */
{0x2e, 0x67, 0x69, 0x66, };
const char http_jpg[5] =
/* ".jpg" */
{0x2e, 0x6a, 0x70, 0x67, };
const char http_text[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };
const char http_txt[5] =
/* ".txt" */
{0x2e, 0x74, 0x78, 0x74, };

View file

@ -0,0 +1,34 @@
extern const char http_http[8];
extern const char http_200[5];
extern const char http_301[5];
extern const char http_302[5];
extern const char http_get[5];
extern const char http_10[9];
extern const char http_11[9];
extern const char http_content_type[15];
extern const char http_texthtml[10];
extern const char http_location[11];
extern const char http_host[7];
extern const char http_crnl[3];
extern const char http_index_html[12];
extern const char http_404_html[10];
extern const char http_referer[9];
extern const char http_header_200[92];
extern const char http_header_404[99];
extern const char http_content_type_plain[29];
extern const char http_content_type_html[28];
extern const char http_content_type_css [27];
extern const char http_content_type_text[28];
extern const char http_content_type_png [28];
extern const char http_content_type_gif [28];
extern const char http_content_type_jpg [29];
extern const char http_content_type_binary[43];
extern const char http_html[6];
extern const char http_shtml[7];
extern const char http_htm[5];
extern const char http_css[5];
extern const char http_png[5];
extern const char http_gif[5];
extern const char http_jpg[5];
extern const char http_text[5];
extern const char http_txt[5];

Some files were not shown because too many files have changed in this diff Show more