commit c9e808d6385306f37972a4d1475bbebea51d6dd4 Author: adamdunkels Date: Sat Jun 17 22:41:10 2006 +0000 Import of the contiki-2.x development code from the SICS internal CVS server diff --git a/Makefile.include b/Makefile.include new file mode 100644 index 000000000..1d4896043 --- /dev/null +++ b/Makefile.include @@ -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) + @ diff --git a/apps/about/Makefile.about b/apps/about/Makefile.about new file mode 100644 index 000000000..dc13c3834 --- /dev/null +++ b/apps/about/Makefile.about @@ -0,0 +1,2 @@ +APP_SOURCES += about.c +DSC_SOURCES += about-dsc.c \ No newline at end of file diff --git a/apps/about/about-dsc.c b/apps/about/about-dsc.c new file mode 100644 index 000000000..132a28e37 --- /dev/null +++ b/apps/about/about-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/about/about-dsc.h b/apps/about/about-dsc.h new file mode 100644 index 000000000..f592a69d2 --- /dev/null +++ b/apps/about/about-dsc.h @@ -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__ */ diff --git a/apps/about/about.c b/apps/about/about.c new file mode 100644 index 000000000..d23da30f8 --- /dev/null +++ b/apps/about/about.c @@ -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 + +#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(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/calc/Makefile.calc b/apps/calc/Makefile.calc new file mode 100644 index 000000000..a0f343611 --- /dev/null +++ b/apps/calc/Makefile.calc @@ -0,0 +1,2 @@ +APP_SOURCES += calc.c +DSC_SOURCES += calc-dsc.c \ No newline at end of file diff --git a/apps/calc/calc-dsc.c b/apps/calc/calc-dsc.c new file mode 100644 index 000000000..c233a066c --- /dev/null +++ b/apps/calc/calc-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/calc/calc-dsc.h b/apps/calc/calc-dsc.h new file mode 100644 index 000000000..98f414737 --- /dev/null +++ b/apps/calc/calc-dsc.h @@ -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__ */ diff --git a/apps/calc/calc.c b/apps/calc/calc.c new file mode 100644 index 000000000..8f8fa50f1 --- /dev/null +++ b/apps/calc/calc.c @@ -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(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/cmdd/Makefile.cmdd b/apps/cmdd/Makefile.cmdd new file mode 100644 index 000000000..8b36f8e65 --- /dev/null +++ b/apps/cmdd/Makefile.cmdd @@ -0,0 +1,2 @@ +APP_SOURCES += cmdd.c +DSC_SOURCES += \ No newline at end of file diff --git a/apps/cmdd/cmdd.c b/apps/cmdd/cmdd.c new file mode 100644 index 000000000..8c0fb9c40 --- /dev/null +++ b/apps/cmdd/cmdd.c @@ -0,0 +1,168 @@ +#include "contiki.h" +#include "psock.h" +#include "memb.h" + +#include + +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(); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/cmdd/cmdd.h b/apps/cmdd/cmdd.h new file mode 100644 index 000000000..7543c9140 --- /dev/null +++ b/apps/cmdd/cmdd.h @@ -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__ */ diff --git a/apps/dhcp/Makefile.dhcp b/apps/dhcp/Makefile.dhcp new file mode 100644 index 000000000..b205fb160 --- /dev/null +++ b/apps/dhcp/Makefile.dhcp @@ -0,0 +1,2 @@ +APP_SOURCES += dhcp.c dhcpc.c +DSC_SOURCES += dhcp-dsc.c \ No newline at end of file diff --git a/apps/dhcp/dhcp-dsc.c b/apps/dhcp/dhcp-dsc.c new file mode 100644 index 000000000..9c18bb5fa --- /dev/null +++ b/apps/dhcp/dhcp-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/dhcp/dhcp-dsc.h b/apps/dhcp/dhcp-dsc.h new file mode 100644 index 000000000..e52d30758 --- /dev/null +++ b/apps/dhcp/dhcp-dsc.h @@ -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__ */ diff --git a/apps/dhcp/dhcp.c b/apps/dhcp/dhcp.c new file mode 100644 index 000000000..c026a5760 --- /dev/null +++ b/apps/dhcp/dhcp.c @@ -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); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/dhcp/dhcp.h b/apps/dhcp/dhcp.h new file mode 100644 index 000000000..e69de29bb diff --git a/apps/directory/Makefile.directory b/apps/directory/Makefile.directory new file mode 100644 index 000000000..e74993f3f --- /dev/null +++ b/apps/directory/Makefile.directory @@ -0,0 +1,2 @@ +APP_SOURCES += directory.c +DSC_SOURCES += directory-dsc.c \ No newline at end of file diff --git a/apps/directory/directory-dsc.c b/apps/directory/directory-dsc.c new file mode 100644 index 000000000..ccc8da794 --- /dev/null +++ b/apps/directory/directory-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/directory/directory-dsc.h b/apps/directory/directory-dsc.h new file mode 100644 index 000000000..60110d618 --- /dev/null +++ b/apps/directory/directory-dsc.h @@ -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__ */ diff --git a/apps/directory/directory.c b/apps/directory/directory.c new file mode 100644 index 000000000..be1ce86b5 --- /dev/null +++ b/apps/directory/directory.c @@ -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 +#include + +#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(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/editor/Makefile.editor b/apps/editor/Makefile.editor new file mode 100644 index 000000000..9a514acc4 --- /dev/null +++ b/apps/editor/Makefile.editor @@ -0,0 +1,2 @@ +APP_SOURCES += editor.c memb.c ctk-filedialog.c +DSC_SOURCES += editor-dsc.c \ No newline at end of file diff --git a/apps/editor/editor-dsc.c b/apps/editor/editor-dsc.c new file mode 100644 index 000000000..057ada02a --- /dev/null +++ b/apps/editor/editor-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/editor/editor-dsc.h b/apps/editor/editor-dsc.h new file mode 100644 index 000000000..6716128e0 --- /dev/null +++ b/apps/editor/editor-dsc.h @@ -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__ */ diff --git a/apps/editor/editor.c b/apps/editor/editor.c new file mode 100644 index 000000000..645b84d08 --- /dev/null +++ b/apps/editor/editor.c @@ -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 + * + * $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); +}*/ +/*---------------------------------------------------------------------------*/ diff --git a/apps/email/Makefile.email b/apps/email/Makefile.email new file mode 100644 index 000000000..4a0917e62 --- /dev/null +++ b/apps/email/Makefile.email @@ -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 \ No newline at end of file diff --git a/apps/email/email-dsc.c b/apps/email/email-dsc.c new file mode 100644 index 000000000..f7832519b --- /dev/null +++ b/apps/email/email-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/email/email-dsc.h b/apps/email/email-dsc.h new file mode 100644 index 000000000..65de9ff57 --- /dev/null +++ b/apps/email/email-dsc.h @@ -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__ */ diff --git a/apps/email/email.c b/apps/email/email.c new file mode 100644 index 000000000..6563a7e0a --- /dev/null +++ b/apps/email/email.c @@ -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 + +#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); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/email/email.h b/apps/email/email.h new file mode 100644 index 000000000..3bdf78252 --- /dev/null +++ b/apps/email/email.h @@ -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__ */ diff --git a/apps/email/smtp-socket.c b/apps/email/smtp-socket.c new file mode 100644 index 000000000..20c7e4aa0 --- /dev/null +++ b/apps/email/smtp-socket.c @@ -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 + * + * $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 + +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; +} +/*---------------------------------------------------------------------------*/ + diff --git a/apps/email/smtp-strings b/apps/email/smtp-strings new file mode 100644 index 000000000..27f639c2e --- /dev/null +++ b/apps/email/smtp-strings @@ -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" \ No newline at end of file diff --git a/apps/email/smtp-strings.c b/apps/email/smtp-strings.c new file mode 100644 index 000000000..67295392e --- /dev/null +++ b/apps/email/smtp-strings.c @@ -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 + * + * $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, }; diff --git a/apps/email/smtp-strings.h b/apps/email/smtp-strings.h new file mode 100644 index 000000000..74cb5da46 --- /dev/null +++ b/apps/email/smtp-strings.h @@ -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 + * + * $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]; diff --git a/apps/email/smtp.h b/apps/email/smtp.h new file mode 100644 index 000000000..11c3b6890 --- /dev/null +++ b/apps/email/smtp.h @@ -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__ */ diff --git a/apps/ftp/Makefile.ftp b/apps/ftp/Makefile.ftp new file mode 100644 index 000000000..df796d7e7 --- /dev/null +++ b/apps/ftp/Makefile.ftp @@ -0,0 +1,2 @@ +APP_SOURCES += ftp.c ftpc.c memb.c +DSC_SOURCES += ftp-dsc.c \ No newline at end of file diff --git a/apps/ftp/ftp-dsc.c b/apps/ftp/ftp-dsc.c new file mode 100644 index 000000000..80fb6b0e3 --- /dev/null +++ b/apps/ftp/ftp-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/ftp/ftp-dsc.h b/apps/ftp/ftp-dsc.h new file mode 100644 index 000000000..52418c360 --- /dev/null +++ b/apps/ftp/ftp-dsc.h @@ -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__ */ diff --git a/apps/ftp/ftp.c b/apps/ftp/ftp.c new file mode 100644 index 000000000..f8a55114b --- /dev/null +++ b/apps/ftp/ftp.c @@ -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 + * + * $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 + +#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); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/ftp/ftpc.c b/apps/ftp/ftpc.c new file mode 100644 index 000000000..237e580c0 --- /dev/null +++ b/apps/ftp/ftpc.c @@ -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 + * + * $Id: ftpc.c,v 1.1 2006/06/17 22:41:11 adamdunkels Exp $ + */ +#include "contiki.h" +#include "ftpc.h" + +#include +#include + +#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; +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/ftp/ftpc.h b/apps/ftp/ftpc.h new file mode 100644 index 000000000..3d5434b51 --- /dev/null +++ b/apps/ftp/ftpc.h @@ -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 + * + * $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__ */ diff --git a/apps/irc/Makefile.irc b/apps/irc/Makefile.irc new file mode 100644 index 000000000..de23e03a8 --- /dev/null +++ b/apps/irc/Makefile.irc @@ -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 \ No newline at end of file diff --git a/apps/irc/irc-dsc.c b/apps/irc/irc-dsc.c new file mode 100644 index 000000000..935dad456 --- /dev/null +++ b/apps/irc/irc-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/irc/irc-dsc.h b/apps/irc/irc-dsc.h new file mode 100644 index 000000000..5efa4dd4c --- /dev/null +++ b/apps/irc/irc-dsc.h @@ -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__ */ diff --git a/apps/irc/irc.c b/apps/irc/irc.c new file mode 100644 index 000000000..b549fd638 --- /dev/null +++ b/apps/irc/irc.c @@ -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 + * + * $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 + +#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"); +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/irc/ircc-strings b/apps/irc/ircc-strings new file mode 100644 index 000000000..1d53244df --- /dev/null +++ b/apps/irc/ircc-strings @@ -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 " \ No newline at end of file diff --git a/apps/irc/ircc-strings.c b/apps/irc/ircc-strings.c new file mode 100644 index 000000000..f23c9b632 --- /dev/null +++ b/apps/irc/ircc-strings.c @@ -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, }; diff --git a/apps/irc/ircc-strings.h b/apps/irc/ircc-strings.h new file mode 100644 index 000000000..72748292a --- /dev/null +++ b/apps/irc/ircc-strings.h @@ -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]; diff --git a/apps/irc/ircc.c b/apps/irc/ircc.c new file mode 100644 index 000000000..62a74966e --- /dev/null +++ b/apps/irc/ircc.c @@ -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 + * + * $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 + +#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; +} +/*---------------------------------------------------------------------------*/ diff --git a/apps/irc/ircc.h b/apps/irc/ircc.h new file mode 100644 index 000000000..92eef0845 --- /dev/null +++ b/apps/irc/ircc.h @@ -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 + * + * $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__ */ diff --git a/apps/netconf/Makefile.netconf b/apps/netconf/Makefile.netconf new file mode 100644 index 000000000..20e53a918 --- /dev/null +++ b/apps/netconf/Makefile.netconf @@ -0,0 +1,2 @@ +APP_SOURCES += netconf.c +DSC_SOURCES += netconf-dsc.c \ No newline at end of file diff --git a/apps/netconf/netconf-dsc.c b/apps/netconf/netconf-dsc.c new file mode 100644 index 000000000..4828cde6c --- /dev/null +++ b/apps/netconf/netconf-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/netconf/netconf-dsc.h b/apps/netconf/netconf-dsc.h new file mode 100644 index 000000000..485a3bd09 --- /dev/null +++ b/apps/netconf/netconf-dsc.h @@ -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__ */ diff --git a/apps/netconf/netconf.c b/apps/netconf/netconf.c new file mode 100644 index 000000000..7a36f97d9 --- /dev/null +++ b/apps/netconf/netconf.c @@ -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(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/process-list/Makefile.process-list b/apps/process-list/Makefile.process-list new file mode 100644 index 000000000..6a84ea57b --- /dev/null +++ b/apps/process-list/Makefile.process-list @@ -0,0 +1,2 @@ +APP_SOURCES += process-list.c +DSC_SOURCES += process-list-dsc.c \ No newline at end of file diff --git a/apps/process-list/process-list-dsc.c b/apps/process-list/process-list-dsc.c new file mode 100644 index 000000000..5f33797b9 --- /dev/null +++ b/apps/process-list/process-list-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/process-list/process-list-dsc.h b/apps/process-list/process-list-dsc.h new file mode 100644 index 000000000..e13469df9 --- /dev/null +++ b/apps/process-list/process-list-dsc.h @@ -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__ */ diff --git a/apps/process-list/process-list.c b/apps/process-list/process-list.c new file mode 100644 index 000000000..b42b5d471 --- /dev/null +++ b/apps/process-list/process-list.c @@ -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 + +#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(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/program-handler/Makefile.program-handler b/apps/program-handler/Makefile.program-handler new file mode 100644 index 000000000..2aa939769 --- /dev/null +++ b/apps/program-handler/Makefile.program-handler @@ -0,0 +1,2 @@ +APP_SOURCES += program-handler.c +DSC_SOURCES += \ No newline at end of file diff --git a/apps/program-handler/program-handler.c b/apps/program-handler/program-handler.c new file mode 100644 index 000000000..aadb1ff70 --- /dev/null +++ b/apps/program-handler/program-handler.c @@ -0,0 +1,385 @@ +/** + * \file + * The program handler, used for loading programs and starting the + * screensaver. + * \author Adam Dunkels + * + * 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 + +#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(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/program-handler/program-handler.h b/apps/program-handler/program-handler.h new file mode 100644 index 000000000..ff240ecc4 --- /dev/null +++ b/apps/program-handler/program-handler.h @@ -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__ */ diff --git a/apps/shell/Makefile.shell b/apps/shell/Makefile.shell new file mode 100644 index 000000000..bbbe64890 --- /dev/null +++ b/apps/shell/Makefile.shell @@ -0,0 +1,2 @@ +APP_SOURCES += shell-gui.c shell.c ctk-textentry-cmdline.c +DSC_SOURCES += shell-dsc.c \ No newline at end of file diff --git a/apps/shell/shell-dsc.c b/apps/shell/shell-dsc.c new file mode 100644 index 000000000..44e001c16 --- /dev/null +++ b/apps/shell/shell-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/shell/shell-dsc.h b/apps/shell/shell-dsc.h new file mode 100644 index 000000000..b89c8772f --- /dev/null +++ b/apps/shell/shell-dsc.h @@ -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__ */ diff --git a/apps/shell/shell-gui.c b/apps/shell/shell-gui.c new file mode 100644 index 000000000..02c0c5f59 --- /dev/null +++ b/apps/shell/shell-gui.c @@ -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 + +#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(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/shell/shell.c b/apps/shell/shell.c new file mode 100644 index 000000000..3f08feb1c --- /dev/null +++ b/apps/shell/shell.c @@ -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 + +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); + } + } + } +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/shell/shell.h b/apps/shell/shell.h new file mode 100644 index 000000000..7fbe4c4e5 --- /dev/null +++ b/apps/shell/shell.h @@ -0,0 +1,114 @@ +/** + * \file + * Interface for the Contiki shell. + * \author Adam Dunkels + * + * 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__ */ + + + diff --git a/apps/telnet/Makefile.telnet b/apps/telnet/Makefile.telnet new file mode 100644 index 000000000..92ffd3a60 --- /dev/null +++ b/apps/telnet/Makefile.telnet @@ -0,0 +1,2 @@ +APP_SOURCES += simpletelnet.c telnet.c +DSC_SOURCES += telnet-dsc.c \ No newline at end of file diff --git a/apps/telnet/simpletelnet.c b/apps/telnet/simpletelnet.c new file mode 100644 index 000000000..b2726deee --- /dev/null +++ b/apps/telnet/simpletelnet.c @@ -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 + +#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); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/telnet/simpletelnet.h b/apps/telnet/simpletelnet.h new file mode 100644 index 000000000..3c2794397 --- /dev/null +++ b/apps/telnet/simpletelnet.h @@ -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__ */ diff --git a/apps/telnet/telnet-dsc.c b/apps/telnet/telnet-dsc.c new file mode 100644 index 000000000..472325c6a --- /dev/null +++ b/apps/telnet/telnet-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/telnet/telnet-dsc.h b/apps/telnet/telnet-dsc.h new file mode 100644 index 000000000..14ee95fba --- /dev/null +++ b/apps/telnet/telnet-dsc.h @@ -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__ */ diff --git a/apps/telnet/telnet.c b/apps/telnet/telnet.c new file mode 100644 index 000000000..72f8bb5d2 --- /dev/null +++ b/apps/telnet/telnet.c @@ -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); + } +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/telnet/telnet.h b/apps/telnet/telnet.h new file mode 100644 index 000000000..baaae1bc8 --- /dev/null +++ b/apps/telnet/telnet.h @@ -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__ */ diff --git a/apps/telnetd/Makefile.telnetd b/apps/telnetd/Makefile.telnetd new file mode 100644 index 000000000..fcfd002af --- /dev/null +++ b/apps/telnetd/Makefile.telnetd @@ -0,0 +1,2 @@ +APP_SOURCES += telnetd.c shell.c +DSC_SOURCES += telnetd-dsc.c diff --git a/apps/telnetd/telnetd-dsc.c b/apps/telnetd/telnetd-dsc.c new file mode 100644 index 000000000..01a5cc175 --- /dev/null +++ b/apps/telnetd/telnetd-dsc.c @@ -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 */ +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/telnetd/telnetd-dsc.h b/apps/telnetd/telnetd-dsc.h new file mode 100644 index 000000000..1501f6fbd --- /dev/null +++ b/apps/telnetd/telnetd-dsc.h @@ -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__ */ diff --git a/apps/telnetd/telnetd-gui.c b/apps/telnetd/telnetd-gui.c new file mode 100644 index 000000000..f09f12097 --- /dev/null +++ b/apps/telnetd/telnetd-gui.c @@ -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 + +#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(); + } +} +/*-----------------------------------------------------------------------------------*/ diff --git a/apps/telnetd/telnetd.c b/apps/telnetd/telnetd.c new file mode 100644 index 000000000..34ed57c88 --- /dev/null +++ b/apps/telnetd/telnetd.c @@ -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 + +#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) +{} diff --git a/apps/telnetd/telnetd.h b/apps/telnetd/telnetd.h new file mode 100644 index 000000000..c347a2d85 --- /dev/null +++ b/apps/telnetd/telnetd.h @@ -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__ */ diff --git a/apps/webbrowser/Makefile.webbrowser b/apps/webbrowser/Makefile.webbrowser new file mode 100644 index 000000000..fede31c05 --- /dev/null +++ b/apps/webbrowser/Makefile.webbrowser @@ -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 \ No newline at end of file diff --git a/apps/webbrowser/html-strings b/apps/webbrowser/html-strings new file mode 100644 index 000000000..e3c43c93b --- /dev/null +++ b/apps/webbrowser/html-strings @@ -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" \ No newline at end of file diff --git a/apps/webbrowser/html-strings.c b/apps/webbrowser/html-strings.c new file mode 100644 index 000000000..6292280e6 --- /dev/null +++ b/apps/webbrowser/html-strings.c @@ -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, }; diff --git a/apps/webbrowser/html-strings.h b/apps/webbrowser/html-strings.h new file mode 100644 index 000000000..21c6c129d --- /dev/null +++ b/apps/webbrowser/html-strings.h @@ -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]; diff --git a/apps/webbrowser/htmlparser.c b/apps/webbrowser/htmlparser.c new file mode 100644 index 000000000..0d0c5a7f2 --- /dev/null +++ b/apps/webbrowser/htmlparser.c @@ -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 + * (-tags), HTML img alt tags, a few text flow break tags +G * (
,

, ), the

  • tag (but does not even try to + * distinguish between
      or
        ) 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 + +#if 1 +#define PRINTF(x) +#else +#include +#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 [0, 255]:6 valid bits */ +#define RSSI_OFFSET -38 +#define RSSI_2_ED(rssi) ((rssi) < RSSI_OFFSET ? 0 : ((rssi) - RSSI_OFFSET)) +#define ED_2_LQI(ed) (((ed) > 63 ? 255 : ((ed) << 2))) + +/* Page 48. [48, 112] --> [0, 255]:6 valid bits */ +#define CORR_OFFSET 48 +#define CORR_2_X(corr) ((corr) < CORR_OFFSET ? 0 : ((corr) - CORR_OFFSET)) +#define X_2_LQI(x) (((x) > 63) ? 255 : ((x) << 2)) + +#endif /* CC2420_CONST_H */ diff --git a/core/dev/cc2420_send_ip.c b/core/dev/cc2420_send_ip.c new file mode 100644 index 000000000..7ebb2d931 --- /dev/null +++ b/core/dev/cc2420_send_ip.c @@ -0,0 +1,58 @@ +#include + +#include "contiki.h" + +#include "net/uip.h" +#include "net/uip-fw.h" +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#include "dev/leds.h" + +#include "dev/cc2420.h" + +#define in_my_network(a) \ + (((a[0] ^ cc2420if.ipaddr[0]) & cc2420if.netmask[0]) == 0 && \ + ((a[1] ^ cc2420if.ipaddr[1]) & cc2420if.netmask[1]) == 0) + +u8_t +cc2420_send_ip(void) +{ + struct hdr_802_15 h; + + u8_t color = (cc2420_ack_received) ? LEDS_BLUE : LEDS_RED; + leds_toggle(color); + + h.len = MAC_HDR_LEN + uip_len + 2; /* Including footer[2]. */ + h.fc0 = FC0_TYPE_DATA | FC0_REQ_ACK | FC0_INTRA_PAN; + h.fc1 = FC1_DST_16 | FC1_SRC_16; + + h.src = uip_hostaddr[1]; + if (BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) + h.dst = 0xffff; + else { + uip_ipaddr_t *next_gw; + + if (in_my_network(BUF->destipaddr)) + next_gw = &BUF->destipaddr; + else + next_gw = &uip_draddr; /* Default router. */ + + if (cc2420_check_remote((*next_gw)[1]) == 1) + h.dst = 0xffff; /* remote, use bcast */ + else + h.dst = (*next_gw)[1]; /* local or unknown, use ucast */ + } + + /* Don't request MAC level ACKs for broadcast packets. */ + if (h.dst == 0xffff) + h.fc0 &= ~FC0_REQ_ACK; + + if (cc2420_send(&h, 10, &uip_buf[UIP_LLH_LEN], uip_len) < 0) { + printf("cc2420_send_ip too big uip_len=%d\n", uip_len); + return UIP_FW_TOOLARGE; + } + + leds_toggle(color); + + return UIP_FW_OK; +} diff --git a/core/dev/cc2420_send_uaodv.c b/core/dev/cc2420_send_uaodv.c new file mode 100644 index 000000000..5afcd7d3c --- /dev/null +++ b/core/dev/cc2420_send_uaodv.c @@ -0,0 +1,80 @@ +#include + +#include "contiki.h" + +#include "net/uip.h" +#include "net/uip-fw.h" +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#include "dev/leds.h" + +#include "dev/cc2420.h" + +#include "net/uaodv.h" +#include "net/uaodv-rt.h" + +#define in_my_network(a) \ + (((a[0] ^ cc2420if.ipaddr[0]) & cc2420if.netmask[0]) == 0 && \ + ((a[1] ^ cc2420if.ipaddr[1]) & cc2420if.netmask[1]) == 0) + +u8_t +cc2420_send_uaodv(void) +{ + struct hdr_802_15 h; + + u8_t color = (cc2420_ack_received) ? LEDS_BLUE : LEDS_RED; + leds_toggle(color); + + h.len = MAC_HDR_LEN + uip_len + 2; /* Including footer[2]. */ + h.fc0 = FC0_TYPE_DATA | FC0_REQ_ACK | FC0_INTRA_PAN; + h.fc1 = FC1_DST_16 | FC1_SRC_16; + + h.src = uip_hostaddr[1]; + if (BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) + h.dst = 0xffff; + else { + uip_ipaddr_t *next_gw; + + if (in_my_network(BUF->destipaddr)) + next_gw = &BUF->destipaddr; + else + next_gw = &uip_draddr; /* Default router. */ + + if (cc2420_check_remote((*next_gw)[1]) == 0) + h.dst = (*next_gw)[1]; /* local, use ucast */ + else { /* remote or unknown */ + struct uaodv_rt_entry *route = uaodv_request_route_to(next_gw); + + if (route == NULL) { + h.dst = (*next_gw)[1]; /* try local while waiting for route */ + } else { + if (cc2420_check_remote(route->nexthop[1]) == 1) { + printf("LOST 0x%04x\n", route->nexthop[1]); + /* Send bad route notification? */ +#ifdef UAODV_BAD_ROUTE + uaodv_bad_route(route); +#endif + uaodv_rt_remove(route); + h.dst = 0xffff; /* revert to bcast */ + } else /* unknown */ { + /* This will implicitly update neigbour table. */ + h.dst = route->nexthop[1]; + } + } + } + } + + /* Don't request MAC level ACKs for broadcast packets. */ + if (h.dst == 0xffff) + h.fc0 &= ~FC0_REQ_ACK; + + if (cc2420_send(&h, 10, &uip_buf[UIP_LLH_LEN], uip_len) < 0) { + printf("cc2420_send_uaodv too big uip_len=%d\n", uip_len); + leds_toggle(color); + return UIP_FW_TOOLARGE; + } + + leds_toggle(color); + + return UIP_FW_OK; +} diff --git a/core/dev/cs8900a.c b/core/dev/cs8900a.c new file mode 100644 index 000000000..ba54501c7 --- /dev/null +++ b/core/dev/cs8900a.c @@ -0,0 +1,314 @@ +/* UNFINISHED CODE: the code works, but has yet to be converted into + proper C code. It is mostly 6502 assembler for now. */ + +/* + * Copyright (c) 2001, 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 C64 RealAudio server demo project. + * + * $Id: cs8900a.c,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ + * + */ + +/* cs8900a.c: device driver for the CS8900a chip in 8-bit mode. Mostly + written in 6502 assembler for speed. */ + +#include "cs8900a.h" +#include "uip.h" +#include "uip_arp.h" + +#define UIP_ETHADDR0 0x00 +#define UIP_ETHADDR1 0x00 +#define UIP_ETHADDR2 0x00 +#define UIP_ETHADDR3 0x64 +#define UIP_ETHADDR4 0x64 +#define UIP_ETHADDR5 0x64 + +extern u8_t *cs8900a_rxtxreg, + *cs8900a_txcmd, + *cs8900a_txlen, + *cs8900a_packetpp, + *cs8900a_ppdata; + +static u16_t len; +static u8_t r; + +#define WRITE(P, D) do { PACKETPP = (P); \ + PPDATA = (D); } while(0) + + +/*-----------------------------------------------------------------------------------*/ +void +cs8900a_init(void) +{ + /* Turn on transmission and reception of frames. */ + WRITE(0x0112, 0x00c0); + + /* Accept valid unicast+broadcast frames. */ + WRITE(0x0104, 0x0d05); + + /* Set MAC address. */ + WRITE(0x0158, (ETHADDR1 << 8) | (ETHADDR0)); + WRITE(0x015a, (ETHADDR3 << 8) | (ETHADDR2)); + WRITE(0x015c, (ETHADDR5 << 8) | (ETHADDR4)); + +} +/*-----------------------------------------------------------------------------------*/ +void +cs8900a_send(void) +{ + if(uip_len > UIP_BUFSIZE) { + return; + } + + /* Transmit command. */ + /* *cs8900a_txcmd = 0x00c0 */ + asm("lda #$c0"); + asm("sta %v", cs8900a_txcmd); + asm("lda #$00"); + asm("sta %v+1", cs8900a_txcmd); + + /* *cs8900a_txlen = uip_len */ + + asm("lda _uip_len"); + asm("sta %v", cs8900a_txlen); +#if UIP_BUFSIZE > 255 + asm("lda _uip_len+1"); +#else + asm("lda #0"); +#endif + asm("sta %v+1", cs8900a_txlen); + + asm("ldx #8"); + asm("tryagain:"); + /* Check for avaliable buffer space. */ + asm("lda #$38"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v+1", cs8900a_ppdata); + asm("and #1"); + asm("bne send"); + + /* No space avaliable, skip a received frame and try again. */ + asm("lda #$02"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v", cs8900a_ppdata); + asm("ora #$40"); + asm("sta %v", cs8900a_ppdata); + + asm("dex"); + asm("bne tryagain"); + + asm("bailout:"); + return; + + /* Send the frame. */ + asm("send:"); + + + /* First, send 40+14=54 bytes of header. */ + + asm("ldx #54"); + asm("ldy #0"); + asm("sendloop1:"); + asm("lda _uip_buf,y"); + asm("sta %v", cs8900a_rxtxreg); + asm("lda _uip_buf+1,y"); + asm("sta %v+1", cs8900a_rxtxreg); + asm("iny"); + asm("iny"); + asm("dex"); + asm("dex"); + asm("bne sendloop1"); + + if(uip_len <= 54) { + return; + } + + /* Next, send rest of the packet. */ + + uip_len -= 54; + + + asm("lda ptr1"); + asm("pha"); + asm("lda ptr1+1"); + asm("pha"); + + asm("lda _uip_appdata"); + asm("sta ptr1"); + asm("lda _uip_appdata+1"); + asm("sta ptr1+1"); + + asm("sendloop2:"); + asm("lda _uip_len"); + asm("tax"); + asm("and #1"); + asm("beq noinc"); + asm("inx"); + asm("noinc:"); +#if UIP_BUFSIZE > 255 + asm("lda _uip_len+1"); +#else + asm("lda #0"); +#endif + asm("beq nozero"); + asm("ldx #0"); + asm("nozero:"); + asm("ldy #0"); + asm("sendloop:"); + asm("lda (ptr1),y"); + asm("sta %v", cs8900a_rxtxreg); + asm("iny"); + asm("lda (ptr1),y"); + asm("sta %v+1", cs8900a_rxtxreg); + asm("iny"); + asm("dex"); + asm("dex"); + asm("bne sendloop"); + asm("inc ptr1+1"); +#if UIP_BUFSIZE > 255 + asm("dec _uip_len+1"); + asm("bpl sendloop2"); +#endif + + asm("pla"); + asm("sta ptr1+1"); + asm("pla"); + asm("sta ptr1"); +} +/*-----------------------------------------------------------------------------------*/ +static void +skip_frame(void) +{ + WRITE(0x0102, PPDATA | 0x0040); +} +/*-----------------------------------------------------------------------------------*/ +u8_t +cs8900a_poll(void) +{ + /* Check receiver event register to see if there are any valid + unicast frames avaliable. */ + /* PACKETPP = 0x0124; + if(PPDATA & 0x000d == 0x0000) { + return 0; + } + */ + asm("lda #$24"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v+1", cs8900a_ppdata); + asm("and #$0d"); + asm("cmp #$00"); + asm("bne noreturn"); + /* No frame ready. */ + return 0; + + asm("noreturn:"); + /* Process the incoming frame. */ + + /* Read receiver event and discard it. */ + /* dummy = RXTXREG; */ + + asm("lda %v+1", cs8900a_rxtxreg); + asm("sta _len+1"); + asm("lda %v", cs8900a_rxtxreg); + asm("sta _len"); + + /* Read frame length. */ + /* len = uip_len = RXTXREG; */ + asm("lda %v+1", cs8900a_rxtxreg); + asm("sta _len+1"); + asm("sta _uip_len+1"); + asm("lda %v", cs8900a_rxtxreg); + asm("sta _len"); + asm("sta _uip_len"); + + + if(len > UIP_BUFSIZE) { + skip_frame(); + return 0; + } + + /* Read bytes into uip_buf. */ + asm("lda ptr1"); + asm("pha"); + asm("lda ptr1+1"); + asm("pha"); + + asm("lda #<_uip_buf"); + asm("sta ptr1"); + asm("lda #>_uip_buf"); + asm("sta ptr1+1"); + + asm("lda _len+1"); + asm("beq read256"); + + /* Read first 256*n bytes. */ + asm("ldy #0"); + asm("read256loop:"); + asm("lda %v", cs8900a_rxtxreg); + asm("sta (ptr1),y"); + asm("iny"); + asm("lda %v+1", cs8900a_rxtxreg); + asm("sta (ptr1),y"); + asm("iny"); + asm("bne read256loop"); + asm("inc ptr1+1"); + + asm("dec _len+1"); + asm("bne read256loop"); + + /* Read last 255 or less bytes. */ + asm("read256:"); + asm("lda _len"); + asm("lsr"); + asm("bcc noinc"); + asm("inc _len"); + asm("noinc:"); + asm("ldy #$0"); + asm("readloop:"); + asm("lda %v", cs8900a_rxtxreg); + asm("sta (ptr1),y"); + asm("iny"); + asm("lda %v+1", cs8900a_rxtxreg); + asm("sta (ptr1),y"); + asm("iny"); + asm("cpy _len"); + asm("bne readloop"); + + asm("pla"); + asm("sta ptr1+1"); + asm("pla"); + asm("sta ptr1"); + return len; +} diff --git a/core/dev/cs8900a.h b/core/dev/cs8900a.h new file mode 100644 index 000000000..e0525e0ef --- /dev/null +++ b/core/dev/cs8900a.h @@ -0,0 +1,44 @@ +/* + * 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 + * + * $Id: cs8900a.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ + */ +#ifndef __CS8900A_H__ +#define __CS8900A_H__ + +#include "uip_arch.h" + +void cs8900a_init(void); +void cs8900a_send(void); +u8_t cs8900a_poll(void); + +#endif /* __CS8900A_H__ */ diff --git a/core/dev/ds2411.c b/core/dev/ds2411.c new file mode 100644 index 000000000..ae6ed5430 --- /dev/null +++ b/core/dev/ds2411.c @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: ds2411.c,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ + */ +/* + * Device driver for the Dallas Semiconductor DS2411 chip. Heavily + * based on the application note 126 "1-Wire Communications Through + * Software". + * + * http://www.maxim-ic.com/appnotes.cfm/appnote_number/126 + */ + +/* + * For now we stuff in Moteiv Corporation's unique OUI. + * From http://www.ethereal.com/distribution/manuf.txt: + * 00:12:75 Moteiv # Moteiv Corporation + * + * The EUI-64 is a concatenation of the 24-bit OUI value assigned by + * the IEEE Registration Authority and a 40-bit extension identifier + * assigned by the organization with that OUI assignment. + */ + +#include + +#include +#include + +#include "contiki.h" + +#include "ds2411.h" + +unsigned char ds2411_id[8]; + +#ifdef TMOTE_SKY +/* 1-wire is at p2.4 */ +#define PIN BV(4) + +#define PIN_INIT() {\ + P2DIR &= ~PIN; /* p2.4 in, resistor pull high */\ + P2OUT &= ~PIN; /* p2.4 == 0 but still input */\ +} + +/* Set 1-Wire low or high. */ +#define OUTP_0() (P2DIR |= PIN) /* output and p2.4 == 0 from above */ +#define OUTP_1() (P2DIR &= ~PIN) /* p2.4 in, external resistor pull high */ + +/* Read one bit. */ +#define INP() (P2IN & PIN) + +/* + * Delay for u microseconds on a MSP430 at 2.4756MHz. + * + * The loop in clock_delay consists of one add and one jnz, i.e 3 + * cycles. + * + * 3 cycles at 2.4756MHz ==> 1.2us = 6/5us. + * + * Call overhead is roughly 7 cycles and the loop 3 cycles, to + * compensate for call overheads we make 7/3=14/6 fewer laps in the + * loop. + * + * This macro will loose badly if not passed a constant argument, it + * relies on the compiler doing the arithmetic during compile time!! + */ +#define udelay(u) clock_delay((u*5 - 14)/6) + +/* + * Where call overhead dominates, use a macro! + */ +#define udelay_6() { _NOP(); _NOP(); _NOP(); _NOP(); _NOP(); } + +#endif /* TMOTE_SKY */ + +/* + * Recommended delay times in us. + */ +#define udelay_tA() udelay_6() +/* tA 6 max 15 */ +#define tB 64 +#define tC 60 /* max 120 */ +#define tD 10 +#define tE 9 /* max 12 */ +#define tF 55 +#define tG 0 +#define tH 480 +#define tI 70 +#define tJ 410 + +static int +owreset(void) +{ + int result; + OUTP_0(); + udelay(tH); + OUTP_1(); /* Releases the bus */ + udelay(tI); + result = INP(); + udelay(tJ); + return result; +} + +static void +owwriteb(unsigned byte) +{ + int i = 7; + do { + if (byte & 0x01) { + OUTP_0(); + udelay_tA(); + OUTP_1(); /* Releases the bus */ + udelay(tB); + } else { + OUTP_0(); + udelay(tC); + OUTP_1(); /* Releases the bus */ + udelay(tD); + } + if (i == 0) + return; + i--; + byte >>= 1; + } while (1); +} + +static unsigned +owreadb(void) +{ + unsigned result = 0; + int i = 7; + do { + OUTP_0(); + udelay_tA(); + OUTP_1(); /* Releases the bus */ + udelay(tE); + if (INP()) + result |= 0x80; /* LSbit first */ + udelay(tF); + if (i == 0) + return result; + i--; + result >>= 1; + } while (1); +} + +/* Polynomial ^8 + ^5 + ^4 + 1 */ +static unsigned +crc8_add(unsigned acc, unsigned byte) +{ + int i; + acc ^= byte; + for (i = 0; i < 8; i++) + if (acc & 1) + acc = (acc >> 1) ^ 0x8c; + else + acc >>= 1; + + return acc; +} + +int +ds2411_init() +{ + int i; + unsigned family, crc, acc; + + PIN_INIT(); + + if (owreset() == 0) { /* Something pulled down 1-wire. */ + /* + * Read MAC id with interrupts disabled. + */ + int s = splhigh(); + owwriteb(0x33); /* Read ROM command. */ + family = owreadb(); + /* We receive 6 bytes in the reverse order, LSbyte first. */ + for (i = 7; i >= 2; i--) + ds2411_id[i] = owreadb(); + crc = owreadb(); + splx(s); + + /* Verify family and that CRC match. */ + if (family != 0x01) + goto fail; + acc = crc8_add(0x0, family); + for (i = 7; i >= 2; i--) + acc = crc8_add(acc, ds2411_id[i]); + if (acc == crc) { +#ifdef TMOTE_SKY + /* 00:12:75 Moteiv # Moteiv Corporation */ + ds2411_id[0] = 0x00; + ds2411_id[1] = 0x12; + ds2411_id[2] = 0x75; +#endif /* TMOTE_SKY */ + return 1; /* Success! */ + } + } + + fail: + memset(ds2411_id, 0x0, sizeof(ds2411_id)); + return 0; /* Fail! */ +} diff --git a/core/dev/ds2411.h b/core/dev/ds2411.h new file mode 100644 index 000000000..1fd32350e --- /dev/null +++ b/core/dev/ds2411.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: ds2411.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ + */ +/* -*- C -*- */ +/* @(#)$Id: ds2411.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ */ + +#ifndef DS2411_H +#define DS2411_H + +extern unsigned char ds2411_id[8]; +extern int ds2411_init(); + +#endif /* DS2411_H */ diff --git a/core/dev/eeprom.h b/core/dev/eeprom.h new file mode 100644 index 000000000..e3f810c8c --- /dev/null +++ b/core/dev/eeprom.h @@ -0,0 +1,105 @@ +/** + * \addtogroup dev + * @{ + */ + +/** + * \defgroup eeprom EEPROM API + * + * The EEPROM API defines a common interface for EEPROM access on + * Contiki platforms. + * + * A platform with EEPROM support must implement this API. + * + * @{ + */ + +/** + * \file + * EEPROM functions. + * \author Adam Dunkels + */ + +/* Copyright (c) 2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * $Id: eeprom.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ + * + * Author: Adam Dunkels + * + */ + + +#ifndef __EEPROM_H__ +#define __EEPROM_H__ + +typedef unsigned short eeprom_addr_t; +#define EEPROM_NULL 0 + +/** + * Write a buffer into EEPROM. + * + * This function writes a buffer of the specified size into EEPROM. + * + * \param addr The address in EEPROM to which the buffer should be written. + * + * \param buf A pointer to the buffer from which data is to be read. + * + * \param size The number of bytes to write into EEPROM. + * + * + */ +void eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size); + +/** + * Read data from the EEPROM. + * + * This function reads a number of bytes from the specified address in + * EEPROM and into a buffer in memory. + * + * \param addr The address in EEPROM from which the data should be read. + * + * \param buf A pointer to the buffer to which the data should be stored. + * + * \param size The number of bytes to read. + * + * + */ +void eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size); + +/** + * Initialize the EEPROM module + * + * This function initializes the EEPROM module and is called from the + * bootup code. + * + */ + +void eeprom_init(void); + +#endif /* __EEPROM_H__ */ + +/** @} */ +/** @} */ diff --git a/core/dev/leds.c b/core/dev/leds.c new file mode 100644 index 000000000..0f3621b2b --- /dev/null +++ b/core/dev/leds.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: leds.c,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ + */ + +#include "dev/leds.h" +#include "sys/clock.h" + +static struct { + char green:4, yellow:4, red:4; +} leds; + +static struct { + char green:2, yellow:2, red:2; /* These bit fields should really be + only one bit wide, but that + crashed gcc... */ +} invert; + +/*---------------------------------------------------------------------------*/ +static void +show_leds(void) +{ + leds_arch_set((((leds.green > 0) ^ invert.green) ? LEDS_GREEN : 0) | + (((leds.yellow > 0) ^ invert.yellow) ? LEDS_YELLOW : 0) | + (((leds.red > 0) ^ invert.red) ? LEDS_RED : 0)); +} +/*---------------------------------------------------------------------------*/ +void +leds_init(void) +{ + leds.green = leds.red = leds.yellow = 0; + invert.green = invert.red = invert.yellow = 0; + leds_arch_init(); + + show_leds(); +} +/*---------------------------------------------------------------------------*/ +void +leds_blink(void) +{ + /* Blink all leds. */ + leds_arch_set(LEDS_ALL); + + clock_delay(400); + + show_leds(); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_get(void) { + return leds_arch_get(); +} +/*---------------------------------------------------------------------------*/ +void +leds_on(unsigned char l) +{ + if((l & LEDS_GREEN) && leds.green < 15) { + ++leds.green; + } + if((l & LEDS_YELLOW) && leds.yellow < 15) { + ++leds.yellow; + } + if((l & LEDS_RED) && leds.red < 15) { + ++leds.red; + } + show_leds(); +} +/*---------------------------------------------------------------------------*/ +void +leds_off(unsigned char l) +{ + if((l & LEDS_GREEN) && leds.green > 0) { + --leds.green; + } + if((l & LEDS_YELLOW) && leds.yellow > 0) { + --leds.yellow; + } + if((l & LEDS_RED) && leds.red > 0) { + --leds.red; + } + show_leds(); +} +/*---------------------------------------------------------------------------*/ +void +leds_toggle(unsigned char leds) +{ + leds_invert(leds); +} + +/* invert the ínvert register using the leds parameter */ +void leds_invert(unsigned char l) { + if(l & LEDS_GREEN) { + invert.green = 1 - invert.green; + } + if(l & LEDS_YELLOW) { + invert.yellow = 1 - invert.yellow; + } + if(l & LEDS_RED) { + invert.red = 1 - invert.red; + } + show_leds(); +} + +/*---------------------------------------------------------------------------*/ +void leds_green(int o) { o?leds_on(LEDS_GREEN):leds_off(LEDS_GREEN); } +void leds_yellow(int o) { o?leds_on(LEDS_YELLOW):leds_off(LEDS_YELLOW); } +void leds_red(int o) { o?leds_on(LEDS_RED):leds_off(LEDS_RED); } diff --git a/core/dev/leds.h b/core/dev/leds.h new file mode 100644 index 000000000..6561d76f7 --- /dev/null +++ b/core/dev/leds.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: leds.h,v 1.1 2006/06/17 22:41:16 adamdunkels Exp $ + */ +/** + * \addtogroup dev + * @{ + */ + +/** + * \defgroup leds LEDs API + * + * The LEDs API defines a set of functions for accessing LEDs for + * Contiki plaforms with LEDs. + * + * A platform with LED support must implement this API. + * @{ + */ + +#ifndef __LEDS_H__ +#define __LEDS_H__ + +void leds_init(void); + +/** + * Blink all LEDs. + */ +void leds_blink(void); + +#define LEDS_GREEN 1 +#define LEDS_YELLOW 2 +#define LEDS_RED 4 +#define LEDS_BLUE LEDS_YELLOW /* Tmote Sky is colorblind? */ +#define leds_blue leds_yellow + +#define LEDS_ALL 7 + +/** + * Returns the current status of all leds (respects invert) + */ +unsigned char leds_get(void); +void leds_on(unsigned char leds); +void leds_off(unsigned char leds); +void leds_toggle(unsigned char leds); +void leds_invert(unsigned char leds); + + + + +void leds_green(int onoroff); +void leds_red(int onoroff); +void leds_yellow(int onoroff); +#define LEDS_ON 1 +#define LEDS_OFF 0 + + + + +/** + * Leds implementation + */ +void leds_arch_init(void); +unsigned char leds_arch_get(void); +void leds_arch_set(unsigned char leds); + +#endif /* __LEDS_H__ */ diff --git a/core/dev/radio.h b/core/dev/radio.h new file mode 100644 index 000000000..4bd828266 --- /dev/null +++ b/core/dev/radio.h @@ -0,0 +1,76 @@ +/** + * \addtogroup dev + * @{ + */ + +/** + * \defgroup radio Radio API + * + * The radio API module defines a set of functions that a radio device + * driver must implement. + * + * @{ + */ + +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: radio.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +/** + * \file + * Header file for the radio API + * \author + * Adam Dunkels + */ + +#ifndef __RADIO_H__ +#define __RADIO_H__ + + +/** + * \brief Turn radio on. + * + * This function turns the radio hardware on. + */ +void radio_on(void); + +/** + * \brief Turn radio off. + * + * This function turns the radio hardware off. + */ +void radio_off(void); + +#endif /* __RADIO_H__ */ + +/** @} */ +/** @} */ diff --git a/core/dev/rom.h b/core/dev/rom.h new file mode 100644 index 000000000..db1d59eaf --- /dev/null +++ b/core/dev/rom.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: rom.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +#ifndef ROM_H +#define ROM_H + +int rom_pread(void *buf, int nbytes, off_t offset); + +int rom_pwrite(const void *buf, int nbytes, off_t offset); + +int rom_erase(long nbytes, off_t offset); + +#endif /* ROM_H */ diff --git a/core/dev/serial.c b/core/dev/serial.c new file mode 100644 index 000000000..9a3b96d40 --- /dev/null +++ b/core/dev/serial.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: serial.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ +#include "serial.h" +#include /* for memcpy() */ + + +#ifdef SERIAL_CONF_BUFSIZE +#define BUFSIZE SERIAL_CONF_BUFSIZE +#else /* SERIAL_CONF_BUFSIZE */ +#define BUFSIZE 40 +#endif /* SERIAL_CONF_BUFSIZE */ + +#define IGNORE_CHAR(c) (c == 0x0d) +#define END 0x0a + +static char buffer[BUFSIZE], appbuffer[BUFSIZE]; +static unsigned char bufwptr; +static char buffer_full = 0; + +PROCESS(serial_process, "Serial driver"); + +process_event_t serial_event_message; + +/*---------------------------------------------------------------------------*/ +int +serial_input_byte(unsigned char c) +{ + if(!buffer_full && !IGNORE_CHAR(c)) { + buffer[bufwptr] = c; + if(bufwptr < BUFSIZE) { + ++bufwptr; + } + + if(c == END) { + buffer_full++; + process_poll(&serial_process); + return 1; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(serial_process, ev, data) +{ + PROCESS_BEGIN(); + + bufwptr = 0; + buffer_full = 0; + + serial_event_message = process_alloc_event(); + + while(1) { + PROCESS_YIELD(); + + if(buffer_full) { + memcpy(appbuffer, buffer, bufwptr); + process_post(PROCESS_BROADCAST, serial_event_message, appbuffer); + buffer_full = 0; + bufwptr = 0; + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +serial_init(void) +{ + process_start(&serial_process, NULL); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/dev/serial.h b/core/dev/serial.h new file mode 100644 index 000000000..1398b0355 --- /dev/null +++ b/core/dev/serial.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: serial.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ +/** + * \file + * Generic serial I/O process header filer + * \author + * Adam Dunkels + * + */ +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + +#include "contiki.h" + +/** + * Event posted when a line of input has been received. + * + * This event is posted when an entire line of input has been received + * from the serial port. A data pointer to the incoming line of input + * is sent together with the event. + */ +extern process_event_t serial_event_message; + +/** + * Get one byte of input from the serial driver. + * + * This function is to be called from the actual RS232 driver to get + * one byte of serial data input. + * + * For systems using low-power CPU modes, the return value of the + * function can be used to determine if the CPU should be woken up or + * not. If the function returns non-zero, the CPU should be powered + * up. If the function returns zero, the CPU can continue to be + * powered down. + * + * \param c The data that is received. + * + * \return Non-zero if the CPU should be powered up, zero otherwise. + */ + +int serial_input_byte(unsigned char c); + +void serial_init(void); + +PROCESS_NAME(serial_process); + +#endif /* __SERIAL_H__ */ diff --git a/core/dev/slip.c b/core/dev/slip.c new file mode 100644 index 000000000..ef8c75c8f --- /dev/null +++ b/core/dev/slip.c @@ -0,0 +1,291 @@ +/* -*- C -*- */ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: slip.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + + +#include +#include + +#include "contiki.h" + +#include "net/uip.h" +#include "net/uip-fw.h" +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#include "dev/slip.h" + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +PROCESS(slip_process, "SLIP driver"); + +#if 1 +#define SLIP_STATISTICS(statement) +#else +u16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop; +#define SLIP_STATISTICS(statement) statement +#endif + +/* Must be at least one byte larger than UIP_BUFSIZE! */ +#define RX_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN + 16) + +enum { + STATE_TWOPACKETS = 0, /* We have 2 packets and drop incoming data. */ + STATE_OK = 1, + STATE_ESC = 2, + STATE_RUBBISH = 3, +}; + +/* + * Variables begin and end manage the buffer space in a cyclic + * fashion. The first used byte is at begin and end is one byte past + * the last. I.e. [begin, end) is the actively used space. + * + * If begin != pkt_end we have a packet at [begin, pkt_end), + * furthermore, if state == STATE_TWOPACKETS we have one more packet at + * [pkt_end, end). If more bytes arrive in state STATE_TWOPACKETS + * they are discarded. + */ + +static u8_t state = STATE_TWOPACKETS; +static u16_t begin, end; +static u8_t rxbuf[RX_BUFSIZE]; +static u16_t pkt_end; /* SLIP_END tracker. */ + + +/*---------------------------------------------------------------------------*/ +u8_t +slip_send(void) +{ + u16_t i; + u8_t *ptr; + u8_t c; + + slip_arch_writeb(SLIP_END); + + ptr = &uip_buf[UIP_LLH_LEN]; + for(i = 0; i < uip_len; ++i) { + if(i == UIP_TCPIP_HLEN) { + ptr = (u8_t *)uip_appdata; + } + c = *ptr++; + if(c == SLIP_END) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_END; + } else if(c == SLIP_ESC) { + slip_arch_writeb(SLIP_ESC); + c = SLIP_ESC_ESC; + } + slip_arch_writeb(c); + } + slip_arch_writeb(SLIP_END); + + return UIP_FW_OK; +} +/*---------------------------------------------------------------------------*/ +static void +rxbuf_init(void) +{ + begin = end = pkt_end = 0; + state = STATE_OK; +} +/*---------------------------------------------------------------------------*/ +/* Upper half does the polling. */ +static u16_t +slip_poll_handler(u8_t *outbuf, u16_t blen) +{ + /* This is a hack and won't work across buffer edge! */ + if(rxbuf[begin] == 'C') { + int i; + if(begin < end && (end - begin) >= 6 + && memcmp(&rxbuf[begin], "CLIENT", 6) == 0) { + state = STATE_TWOPACKETS; /* Interrupts do nothing. */ + memset(&rxbuf[begin], 0x0, 6); + + rxbuf_init(); + + for(i = 0; i < 13; i++) { + slip_arch_writeb("CLIENTSERVER\300"[i]); + } + return 0; + } + } + + /* + * Interrupt can not change begin but may change pkt_end. + * If pkt_end != begin it will not change again. + */ + if(begin != pkt_end) { + u16_t len; + + if(begin < pkt_end) { + len = pkt_end - begin; + if(len > blen) { + len = 0; + } else { + memcpy(outbuf, &rxbuf[begin], len); + } + } else { + len = (RX_BUFSIZE - begin) + (pkt_end - 0); + if(len > blen) { + len = 0; + } else { + unsigned i; + for(i = begin; i < RX_BUFSIZE; i++) + *outbuf++ = rxbuf[i]; + for(i = 0; i < pkt_end; i++) + *outbuf++ = rxbuf[i]; + } + } + + /* Remove data from buffer together with the copied packet. */ + begin = pkt_end; + if(state == STATE_TWOPACKETS) { + pkt_end = end; + state = STATE_OK; /* Assume no bytes where lost! */ + + /* One more packet is buffered, need to be polled again! */ + process_poll(&slip_process); + } + return len; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(slip_process, ev, data) +{ + PROCESS_BEGIN(); + + rxbuf_init(); + + while(1) { + PROCESS_YIELD(); + + /* Move packet from rxbuf to buffer provided by uIP. */ + uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN], + UIP_BUFSIZE - UIP_LLH_LEN); + + if(uip_len > 0 + && uip_len == (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) + && uip_ipchksum() == 0xffff) { + tcpip_input(); + } else { + uip_len = 0; + SLIP_STATISTICS(slip_ip_drop++); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +int +slip_input_byte(unsigned char c) +{ + switch(state) { + case STATE_RUBBISH: + if(c == SLIP_END) { + state = STATE_OK; + } + return 0; + + case STATE_TWOPACKETS: /* Two packets are already buffered! */ + return 0; + + case STATE_ESC: + if(c == SLIP_ESC_END) { + c = SLIP_END; + } else if(c == SLIP_ESC_ESC) { + c = SLIP_ESC; + } else { + state = STATE_RUBBISH; + SLIP_STATISTICS(slip_rubbish++); + end = pkt_end; /* remove rubbish */ + return 0; + } + state = STATE_OK; + break; + + case STATE_OK: + if(c == SLIP_ESC) { + state = STATE_ESC; + return 0; + } else if(c == SLIP_END) { + /* + * We have a new packet, possibly of zero length. + * + * There may already be one packet buffered. + */ + if(end != pkt_end) { /* Non zero length. */ + if(begin == pkt_end) { /* None buffered. */ + pkt_end = end; + } else { + state = STATE_TWOPACKETS; + SLIP_STATISTICS(slip_twopackets++); + } + process_poll(&slip_process); + return 1; + } + return 0; + } + break; + } + + /* add_char: */ + { + unsigned next; + next = end + 1; + if(next == RX_BUFSIZE) { + next = 0; + } + if(next == begin) { /* rxbuf is full */ + state = STATE_RUBBISH; + SLIP_STATISTICS(slip_overflow++); + end = pkt_end; /* remove rubbish */ + return 0; + } + rxbuf[end] = c; + end = next; + } + + /* There could be a separate poll routine for this. */ + if(c == 'T' && rxbuf[begin] == 'C') { + process_poll(&slip_process); + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/dev/slip.h b/core/dev/slip.h new file mode 100644 index 000000000..1f25506b0 --- /dev/null +++ b/core/dev/slip.h @@ -0,0 +1,76 @@ +/* -*- C -*- */ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: slip.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +#ifndef __SLIP_H__ +#define __SLIP_H__ + +#include "contiki.h" + +PROCESS_NAME(slip_process); + +/** + * Send an IP packet from the uIP buffer with SLIP. + */ +u8_t slip_send(void); + +/** + * Input a SLIP byte. + * + * This function is called by the RS232/SIO device driver to pass + * incoming bytes to the SLIP driver. The function can be called from + * an interrupt context. + * + * For systems using low-power CPU modes, the return value of the + * function can be used to determine if the CPU should be woken up or + * not. If the function returns non-zero, the CPU should be powered + * up. If the function returns zero, the CPU can continue to be + * powered down. + * + * \param c The data that is to be passed to the SLIP driver + * + * \return Non-zero if the CPU should be powered up, zero otherwise. + */ +int slip_input_byte(unsigned char c); + +/* Statistics. */ +extern u16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop; + +/* + * These machine dependent functions and an interrupt service routine + * must be provided externally (slip_arch.c). + */ +void slip_arch_init(void); +void slip_arch_writeb(unsigned char c); + +#endif /* __SLIP_H__ */ diff --git a/core/dev/spi.h b/core/dev/spi.h new file mode 100644 index 000000000..dd3ce65f2 --- /dev/null +++ b/core/dev/spi.h @@ -0,0 +1,213 @@ +/* -*- C -*- */ +/* @(#)$Id: spi.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ */ + +#ifndef SPI_H +#define SPI_H + +extern unsigned char spi_busy; + +void spi_init(void); + +/****************************************************************************************************** +* TEXAS INSTRUMENTS INC., * +* MSP430 APPLICATIONS. * +* Copyright Texas Instruments Inc, 2004 * + *****************************************************************************************************/ + +/*********************************************************** + FAST SPI: Low level functions +***********************************************************/ + +#define FASTSPI_TX(x)\ + do {\ + SPI_TXBUF = x;\ + SPI_WAITFOREOTx();\ + } while(0) + +#define FASTSPI_RX(x)\ + do {\ + SPI_TXBUF = 0;\ + SPI_WAITFOREORx();\ + x = SPI_RXBUF;\ + } while(0) + +#define FASTSPI_CLEAR_RX(x) do{ SPI_RXBUF; }while(0) + +#define FASTSPI_RX_GARBAGE()\ + do {\ + SPI_TXBUF = 0;\ + SPI_WAITFOREORx();\ + SPI_RXBUF;\ + } while(0) + +#define FASTSPI_TX_MANY(p,c)\ + do {\ + for (u8_t spiCnt = 0; spiCnt < (c); spiCnt++) {\ + FASTSPI_TX(((u8_t*)(p))[spiCnt]);\ + }\ + } while(0) + + +#define FASTSPI_RX_WORD(x)\ + do {\ + SPI_TXBUF = 0;\ + SPI_WAITFOREORx();\ + x = SPI_RXBUF << 8;\ + SPI_TXBUF = 0;\ + SPI_WAITFOREORx();\ + x |= SPI_RXBUF;\ + } while (0) + +#define FASTSPI_TX_ADDR(a)\ + do {\ + SPI_TXBUF = a;\ + SPI_WAITFOREOTx();\ + } while (0) + +#define FASTSPI_RX_ADDR(a)\ + do {\ + SPI_TXBUF = (a) | 0x40;\ + SPI_WAITFOREOTx();\ + } while (0) + + + +/*********************************************************** + FAST SPI: Register access +***********************************************************/ +// s = command strobe +// a = register address +// v = register value + +#define FASTSPI_STROBE(s) \ + do {\ + SPI_ENABLE();\ + FASTSPI_TX_ADDR(s);\ + SPI_DISABLE();\ + } while (0) + +#define FASTSPI_SETREG(a,v)\ + do {\ + SPI_ENABLE();\ + FASTSPI_TX_ADDR(a);\ + FASTSPI_TX((u8_t) ((v) >> 8));\ + FASTSPI_TX((u8_t) (v));\ + SPI_DISABLE();\ + } while (0) + + +#define FASTSPI_GETREG(a,v)\ + do {\ + SPI_ENABLE();\ + FASTSPI_RX_ADDR(a);\ + v= (u8_t)SPI_RXBUF;\ + FASTSPI_RX_WORD(v);\ + clock_delay(1);\ + SPI_DISABLE();\ + } while (0) + +// Updates the SPI status byte + +#define FASTSPI_UPD_STATUS(s)\ + do {\ + SPI_ENABLE();\ + SPI_TXBUF = CC2420_SNOP;\ + SPI_WAITFOREOTx();\ + s = SPI_RXBUF;\ + SPI_DISABLE();\ + } while (0) + +/*********************************************************** + FAST SPI: FIFO Access +***********************************************************/ +// p = pointer to the byte array to be read/written +// c = the number of bytes to read/write +// b = single data byte + +#define FASTSPI_WRITE_FIFO(p,c)\ + do {\ + SPI_ENABLE();\ + u8_t i;\ + FASTSPI_TX_ADDR(CC2420_TXFIFO);\ + for (i = 0; i < (c); i++) {\ + FASTSPI_TX(((u8_t*)(p))[i]);\ + }\ + SPI_DISABLE();\ + } while (0) + +#define FASTSPI_WRITE_FIFO_NOCE(p,c)\ + do {\ + FASTSPI_TX_ADDR(CC2420_TXFIFO);\ + for (u8_t spiCnt = 0; spiCnt < (c); spiCnt++) {\ + FASTSPI_TX(((u8_t*)(p))[spiCnt]);\ + }\ + } while (0) + +#define FASTSPI_READ_FIFO_BYTE(b)\ + do {\ + SPI_ENABLE();\ + FASTSPI_RX_ADDR(CC2420_RXFIFO);\ + SPI_RXBUF;\ + FASTSPI_RX(b);\ + clock_delay(1);\ + SPI_DISABLE();\ + } while (0) + + +#define FASTSPI_READ_FIFO_NO_WAIT(p,c)\ + do {\ + u8_t spiCnt;\ + SPI_ENABLE();\ + FASTSPI_RX_ADDR(CC2420_RXFIFO);\ + SPI_RXBUF;\ + for (spiCnt = 0; spiCnt < (c); spiCnt++) {\ + FASTSPI_RX(((u8_t*)(p))[spiCnt]);\ + }\ + clock_delay(1);\ + SPI_DISABLE();\ + } while (0) + + + +#define FASTSPI_READ_FIFO_GARBAGE(c)\ + do {\ + u8_t spiCnt;\ + SPI_ENABLE();\ + FASTSPI_RX_ADDR(CC2420_RXFIFO);\ + SPI_RXBUF;\ + for (spiCnt = 0; spiCnt < (c); spiCnt++) {\ + FASTSPI_RX_GARBAGE();\ + }\ + clock_delay(1);\ + SPI_DISABLE();\ + } while (0) + + + +/*********************************************************** + FAST SPI: CC2420 RAM access (big or little-endian order) +***********************************************************/ +// FAST SPI: CC2420 RAM access (big or little-endian order) +// p = pointer to the variable to be written +// a = the CC2420 RAM address +// c = the number of bytes to write +// n = counter variable which is used in for/while loops (u8_t) +// +// Example of usage: +// u8_t n; +// u16_t shortAddress = 0xBEEF; +// FASTSPI_WRITE_RAM_LE(&shortAddress, CC2420RAM_SHORTADDR, 2); + + +#define FASTSPI_WRITE_RAM_LE(p,a,c,n)\ + do {\ + SPI_ENABLE();\ + FASTSPI_TX(0x80 | (a & 0x7F));\ + FASTSPI_TX((a >> 1) & 0xC0);\ + for (n = 0; n < (c); n++) {\ + FASTSPI_TX(((u8_t*)(p))[n]);\ + }\ + SPI_DISABLE();\ + } while (0) + +#endif /* SPI_H */ diff --git a/core/dev/watchdog.h b/core/dev/watchdog.h new file mode 100644 index 000000000..2c1fe41ed --- /dev/null +++ b/core/dev/watchdog.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: watchdog.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ +#ifndef __WATCHDOG_H__ +#define __WATCHDOG_H__ + +void watchdog_init(void); +void watchdog_restart(void); +void watchdog_stop(void); + +#endif /* __WATCHDOG_H__ */ diff --git a/core/dev/xmem.h b/core/dev/xmem.h new file mode 100644 index 000000000..22a958ad4 --- /dev/null +++ b/core/dev/xmem.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: xmem.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +#ifndef XMEM_H +#define XMEM_H + +void xmem_init(void); + +int xmem_pread(void *buf, int nbytes, off_t offset); + +int xmem_pwrite(const void *buf, int nbytes, off_t offset); + +int xmem_erase(long nbytes, off_t offset); + +#endif /* XMEM_H */ diff --git a/core/lib/crc16.c b/core/lib/crc16.c new file mode 100644 index 000000000..cdb5a9f05 --- /dev/null +++ b/core/lib/crc16.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: crc16.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +/** \addtogroup crc16 + * @{ */ + +/** + * \file + * Implementation of the CRC16 calculcation + * \author + * Adam Dunkels + * + */ + +/* CITT CRC16 polynomial ^16 + ^12 + ^5 + 1 */ +/*---------------------------------------------------------------------------*/ +unsigned short +crc16_add(unsigned char b, unsigned short acc) +{ + /* + acc = (unsigned char)(acc >> 8) | (acc << 8); + acc ^= b; + acc ^= (unsigned char)(acc & 0xff) >> 4; + acc ^= (acc << 8) << 4; + acc ^= ((acc & 0xff) << 4) << 1; + */ + + acc ^= b; + acc = (acc >> 8) | (acc << 8); + acc ^= (acc & 0xff00) << 4; + acc ^= (acc >> 8) >> 4; + acc ^= (acc & 0xff00) >> 5; + return acc; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/core/lib/crc16.h b/core/lib/crc16.h new file mode 100644 index 000000000..e7264bde4 --- /dev/null +++ b/core/lib/crc16.h @@ -0,0 +1,79 @@ +/** \addtogroup lib + * @{ */ + +/** + * \defgroup crc16 Cyclic Redundancy Check 16 (CRC16) calculcation + * + * The Cyclic Redundancy Check 16 is a hash function that produces a + * checksum that is used to detect errors in transmissions. The CRC16 + * calculation module is an iterative CRC calculator that can be used + * to cummulatively update a CRC checksum for every incoming byte. + * + * @{ + */ + +/** + * \file + * Header file for the CRC16 calculcation + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: crc16.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ +#ifndef __CRC16_H__ +#define __CRC16_H__ + +/** + * \brief Update an accumulated CRC16 checksum with one byte. + * \param b The byte to be added to the checksum + * \param crc The accumulated CRC that is to be updated. + * \return The updated CRC checksum. + * + * This function updates an accumulated CRC16 checksum + * with one byte. It can be used as a running checksum, or + * to checksum an entire data block. + * + * \note The algorithm used in this implementation is + * tailored for a running checksum and does not perform as + * well as a table-driven algorithm when checksumming an + * entire data block. + * + */ +unsigned short crc16_add(unsigned char b, unsigned short crc); + +#endif /* __CRC16_H__ */ + +/** @} */ +/** @} */ diff --git a/core/lib/crtk.c b/core/lib/crtk.c new file mode 100644 index 000000000..0bfc5ed0a --- /dev/null +++ b/core/lib/crtk.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: crtk.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +/* + * RUNES CRTK Implementation + * Version 0.3 + * + * Stefanos Zachariadis, UCL, s.zachariadis@cs.ucl.ac.uk + */ + +#include +#include + +#include "crtk.h" + +static Attribute a = { "Author", "Stefanos Zachariadis", NULL }; +static Entity attributes = { 0, COMPONENT, "crtk", &a, NULL }; +static int entities; + +static void construct(void) { + printf("Instantiating RUNES middleware\n"); +} + +static void destroy(void) { + printf("RUNES Middleware going away...\n"); +} + +static void printregistry(void) { + printf("The Registry Currently Contains:\n"); + Entity *current; + current=&attributes; + while(current!=NULL) { + Attribute *attrs; + attrs=current->attributes; + printf("Entity (%d,%d) \n",current->id, current->type); + while(attrs!=NULL) { + printf(" (%s,%s)\n",attrs->key,(char *)(attrs->value)); + attrs=attrs->next; + } + current=current->next; + } +} + + +static void delent(Entity *e) { + Entity *previous = &attributes; /* Not allowed to delete first! */ + Entity *current = previous->next; + while(current != NULL) { + if(e->id == current->id) { + previous->next = current->next; + current->next = NULL; + return; + } + previous = current; + current = current->next; + } +} + + +static void putattr(Entity *e, Attribute *a) { + Entity *current, *previous = NULL; + current=&attributes; + while(NULL!=current) { + //printf("looping\n"); + if(e->id==current->id) { //the entity already exists in our databas + //we need to see if an attribute with the same key exists + Attribute *tmp; + for(tmp=current->attributes;tmp->next!=NULL;tmp=tmp->next) { + if(strcmp(tmp->key,a->key)==0) { //it does exist + tmp->value=a->value; + return; + } + } + //we need to add this attribute + tmp->next=a; + a->next=NULL; + return; + } + previous=current; + current=current->next; + } + e->next=NULL; + previous->next=e; + e->attributes=a; + a->next=NULL; +} + +static void getattr(Entity e, char *key, Attribute **atr) { + //right, so we're going to go through our registry. + Entity *current; + current=&attributes; + while(current!=NULL) { + if(e.id==current->id) { //we found the element + Attribute *tmp; + for(tmp=current->attributes;tmp!=NULL;tmp=tmp->next) { + if(strcmp(tmp->key,key)==0) { //the key does exist + *atr=tmp; + return; + } + } + } + current=current->next; + } + atr=NULL; +} + +static void connect(Interface i, Receptacle *r) { + *r=i; +} + + + +static void instantiate(Entity *e, Attribute *init) { + e->id=entities++; + putattr(e,init); +} + + +static void getentities(Entity **e) { + *e=&attributes; +} + +IMPLEMENT_COMPONENT(crtk, { printregistry, delent, putattr, getattr, + connect, instantiate, getentities }); diff --git a/core/lib/crtk.h b/core/lib/crtk.h new file mode 100644 index 000000000..ae87b6dec --- /dev/null +++ b/core/lib/crtk.h @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: crtk.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +/* + * RUNES CRTK header, version 0.3 + * + * Stefanos Zachariadis, UCL, s.zachariadis@cs.ucl.ac.uk + */ + +#ifndef CRTK_H +#define CRTK_H + +/* For now this file is intimately dependent on sys/service.h. Really + * mysterious error messages are generated if one forgets to include + * sys/service.h, for this reason it is included here! + */ +#include "sys/service.h" + +#define COMPONENT 0 + +#define INTERFACE 1 + +#define RECEPTACLE 2 + +typedef const char *Receptacle; + +typedef const void *Interface; + +#if 0 +typedef struct INTERFACES { + Interface *i; + struct INTERFACES *next; +} Interfaces; +#endif + +#if 0 +typedef struct RECEPTACLES { + Receptacle *r; + struct RECEPTACLES *next; +} Receptacles; +#endif + +typedef struct ATTRIBUTE { + char *key; + void *value; + struct ATTRIBUTE *next; +} Attribute; + +typedef struct ENTITY { + int id; + int type; + char *name; + Attribute *attributes; + struct ENTITY *next; +} Entity; + +#define INVOKE(receptacle, iface, function) \ + { \ + struct service *service_s; \ + service_s = service_find(receptacle); \ + if(service_s != NULL) { \ + ((struct iface *)service_s->interface)->function; \ + } \ + } + +#define DECLARE_COMPONENT(compname,interface) \ +extern struct process compname##_process; \ +struct compname interface; + +#define DECLARE_INTERFACE(intname,interface)\ + struct intname interface; + +#define IMPLEMENT_COMPONENT(compname, ...)\ + static const struct compname compname##_implementation_interface = __VA_ARGS__;\ + static struct service compname##_implementation = { NULL, NULL, #compname, & compname##_implementation_interface }; \ + static Entity compname##_entity;\ + static void construct(void);\ + static void destroy(void);\ + PROCESS(compname##_process, #compname"_process"); \ + PROCESS_THREAD(compname##_process, ev, data) {\ + static Attribute name = { "template", #compname, NULL };\ + PROCESS_EXITHANDLER(goto exit);\ + PROCESS_BEGIN();\ + compname##_entity.type = COMPONENT;\ + compname##_entity.name = #compname;\ + construct();\ + SERVICE_REGISTER(compname##_implementation);\ + INVOKE("crtk", crtk, instantiate(&compname##_entity,&name));\ + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_SERVICE_REMOVED);\ + exit:\ + destroy();\ + SERVICE_REMOVE(compname##_implementation);\ + INVOKE("crtk", crtk, delent(&compname##_entity));\ + PROCESS_END(); \ + } + +/* Registry crtk is built upon. */ +DECLARE_COMPONENT(crtk, +{ + /* prints the contents of the registry. */ + void (* printregistry)(void); + + /* delete the given entity. */ + void (* delent)(Entity *e); + + /* adds a new attribute for the given entity. */ + void (* putattr)(Entity *e, Attribute *a); + + /* searches for an attribute with the given key, for the given entity. */ + void (* getattr)(Entity e, char *key, Attribute **a); + + /* connects an interface and a receptacle. */ + void (* connect) (Interface i, Receptacle *r); + + /* instantiates a new component. */ + void (* instantiate) (Entity *e, Attribute *init); + + /* returns on e all the entities (and their attributes) available. */ + void (* getentities) (Entity **e); +}); + +#endif /* CRTK_H */ diff --git a/core/lib/ctk-filedialog.c b/core/lib/ctk-filedialog.c new file mode 100644 index 000000000..32815f071 --- /dev/null +++ b/core/lib/ctk-filedialog.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ctk-filedialog.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ + +#include "contiki.h" +#include "lib/ctk-filedialog.h" +#include "ctk/ctk.h" +#include "cfs/cfs.h" + +#include + +#define MAX_NUMFILES 40 +#define FILES_WIDTH 17 +#define FILES_HEIGHT 14 + +static struct ctk_window dialog; +static char leftptr[FILES_HEIGHT]; +static struct ctk_label leftptrlabel = + {CTK_LABEL(0, 1, 1, FILES_HEIGHT, leftptr)}; + +static char files[FILES_WIDTH * MAX_NUMFILES]; +static struct ctk_label fileslabel = + {CTK_LABEL(1, 1, + FILES_WIDTH, FILES_HEIGHT, files)}; + +static char rightptr[FILES_HEIGHT]; +static struct ctk_label rightptrlabel = + {CTK_LABEL(1 + FILES_WIDTH, 1, 1, FILES_HEIGHT, rightptr)}; + +static char filename[FILES_WIDTH + 1]; +static struct ctk_textentry filenameentry = + {CTK_TEXTENTRY(1, 2 + FILES_HEIGHT, FILES_WIDTH, 1, filename, + FILES_WIDTH)}; + +static struct ctk_button button; + +#define STATE_CLOSED 0 +#define STATE_OPEN 1 +static char state = STATE_CLOSED; +static unsigned char fileptr, dirfileptr; +static struct cfs_dir dir; +/*---------------------------------------------------------------------------*/ +static void +clearptr(void) +{ + leftptr[fileptr] = ' '; + rightptr[fileptr] = ' '; +} +/*---------------------------------------------------------------------------*/ +static void +showptr(void) +{ + leftptr[fileptr] = '>'; + rightptr[fileptr] = '<'; + + strncpy(filename, + &files[fileptr * FILES_WIDTH], + FILES_WIDTH); + + CTK_WIDGET_REDRAW(&filenameentry); + CTK_WIDGET_REDRAW(&leftptrlabel); + CTK_WIDGET_REDRAW(&rightptrlabel); +} +/*---------------------------------------------------------------------------*/ +void +ctk_filedialog_init(register struct ctk_filedialog_state *s) +{ + state = STATE_CLOSED; +} +/*---------------------------------------------------------------------------*/ +void +ctk_filedialog_open(register struct ctk_filedialog_state *s, + const char *buttontext, process_event_t event) +{ + ctk_dialog_new(&dialog, 20, 5 + FILES_HEIGHT); + CTK_WIDGET_ADD(&dialog, &leftptrlabel); + CTK_WIDGET_ADD(&dialog, &fileslabel); + CTK_WIDGET_ADD(&dialog, &rightptrlabel); + CTK_WIDGET_ADD(&dialog, &filenameentry); + CTK_BUTTON_NEW(&button, 1, 4 + FILES_HEIGHT, strlen(buttontext), (char *)buttontext); + CTK_WIDGET_ADD(&dialog, &button); + ctk_dialog_open(&dialog); + state = STATE_OPEN; + memset(filename, 0, sizeof(filename)); + memset(leftptr, ' ', sizeof(leftptr)); + memset(rightptr, ' ', sizeof(rightptr)); + memset(files, 0, sizeof(files)); + + fileptr = 0; + dirfileptr = 0; + showptr(); + cfs_opendir(&dir, "."); + process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, s); +} +/*---------------------------------------------------------------------------*/ +char +ctk_filedialog_eventhandler(struct ctk_filedialog_state *s, + process_event_t ev, process_data_t data) +{ + static struct cfs_dirent dirent; + + if(state == STATE_OPEN) { + if(ev == ctk_signal_widget_activate && + data == (process_data_t)&button) { + ctk_dialog_close(); + state = STATE_CLOSED; + process_post(PROCESS_CURRENT(), s->ev, &filename); + return 1; + } else if(ev == PROCESS_EVENT_CONTINUE && + (process_data_t)s == data) { + if(cfs_readdir(&dir, &dirent) == 0 && + dirfileptr < MAX_NUMFILES) { + strncpy(&files[dirfileptr * FILES_WIDTH], + dirent.name, FILES_WIDTH); + CTK_WIDGET_REDRAW(&fileslabel); + ++dirfileptr; + process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, s); + } else { + fileptr = 0; + cfs_closedir(&dir); + } + return 1; + } else if(ev == ctk_signal_keypress) { + if((ctk_arch_key_t)data == CH_CURS_UP) { + clearptr(); + if(fileptr > 0) { + --fileptr; + } + showptr(); + return 1; + } else if((ctk_arch_key_t)data == CH_CURS_DOWN) { + clearptr(); + if(fileptr < FILES_HEIGHT - 1) { + ++fileptr; + } + showptr(); + return 1; + } + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/lib/ctk-filedialog.h b/core/lib/ctk-filedialog.h new file mode 100644 index 000000000..334a964fd --- /dev/null +++ b/core/lib/ctk-filedialog.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ctk-filedialog.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + */ +#ifndef __CTK_FILEDIALOG_H__ +#define __CTK_FILEDIALOG_H__ + +#include "contiki.h" + +struct ctk_filedialog_state { + unsigned char fileptr; + process_event_t ev; +}; + +void ctk_filedialog_init(register struct ctk_filedialog_state *s); +void ctk_filedialog_open(register struct ctk_filedialog_state *s, + const char *buttontext, process_event_t event); +char ctk_filedialog_eventhandler(struct ctk_filedialog_state *s, + process_event_t ev, process_data_t data); + +#endif /* __CTK_FILEDIALOG_H__ */ diff --git a/core/lib/ctk-textedit.c b/core/lib/ctk-textedit.c new file mode 100644 index 000000000..c562c41f6 --- /dev/null +++ b/core/lib/ctk-textedit.c @@ -0,0 +1,181 @@ +/** + * \file + * An experimental CTK text edit widget. + * \author Adam Dunkels + * + * This module contains an experimental CTK widget which is + * implemented in the application process rather than in the CTK + * process. The widget is instantiated in a similar fashion as other + * CTK widgets, but is different from other widgets in that it + * requires a signal handler function to be called by the process + * signal handler function. + * + */ + +/* + * 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: ctk-textedit.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ + + +#include "ctk-textedit.h" + +#include + +/*-----------------------------------------------------------------------------------*/ +void +ctk_textedit_init(struct ctk_textedit *t) +{ + t->xpos = t->ypos = 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Add a CTK textedit widget to a window. + * + * \param w A pointer to the window to which the entry is to be added. + * \param t A pointer to the CTK textentry structure. + */ +/*-----------------------------------------------------------------------------------*/ +void +ctk_textedit_add(struct ctk_window *w, + struct ctk_textedit *t) +{ + CTK_WIDGET_SET_FLAG(t, CTK_WIDGET_FLAG_MONOSPACE); + CTK_WIDGET_ADD(w, t); +} +/*-----------------------------------------------------------------------------------*/ +/** + * The CTK textedit signal handler. + * + * This function must be called as part of the normal signal handler + * of the process that contains the CTK textentry structure. + * + * \param t A pointer to the CTK textentry structure. + * \param s The signal number. + * \param data The signal data. + */ +/*-----------------------------------------------------------------------------------*/ +void +ctk_textedit_eventhandler(struct ctk_textedit *t, + process_event_t s, + process_data_t data) +{ + char *textptr, *textptr2; + unsigned char len; + + if(s == ctk_signal_keypress) { + CTK_WIDGET_FOCUS(t->label.window, &t->label); + textptr = &(t->label.text[t->ypos * t->label.w + t->xpos]); + *textptr &= 0x7f; + switch((ctk_arch_key_t)data) { + case CH_CURS_DOWN: + if(t->ypos < t->label.h - 1) { + ++t->ypos; + } + break; + case CH_CURS_UP: + if(t->ypos > 0) { + --t->ypos; + } + break; + case CH_CURS_RIGHT: + len = strlen(&t->label.text[t->ypos * t->label.w]); + if(t->xpos < len) { + /* if(t->xpos < t->label.w) {*/ + ++t->xpos; + } else { + t->xpos = len; + } + break; + case CH_CURS_LEFT: + if(t->xpos > 0) { + --t->xpos; + } else { + if(t->ypos > 0) { + --t->ypos; + t->xpos = t->label.w - 1; + } + } + break; + case CH_ENTER: + t->xpos = 0; + if(t->ypos < t->label.h - 1) { + ++t->ypos; + } + 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 = t->label.w - t->xpos; + if(len > 0) { + textptr2 = textptr + len - 1; + while(textptr2 + 1 > textptr) { + *(textptr2 + 1) = *textptr2; + --textptr2; + } + + *textptr = (char)data; + ++t->xpos; + if(t->xpos == t->label.w) { + t->xpos = 0; + if(t->ypos < t->label.h - 1) { + ++t->ypos; + } + } + } + break; + } + textptr = &(t->label.text[t->ypos * t->label.w + t->xpos]); + *textptr |= 0x80; + CTK_WIDGET_REDRAW(&t->label); + } 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); + } +} +/*-----------------------------------------------------------------------------------*/ diff --git a/core/lib/ctk-textedit.h b/core/lib/ctk-textedit.h new file mode 100644 index 000000000..851797115 --- /dev/null +++ b/core/lib/ctk-textedit.h @@ -0,0 +1,73 @@ +/** + * \file + * Header file for the experimental application level CTK textedit widget. + * \author Adam Dunkels + * + */ + +/* + * 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: ctk-textedit.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ +#ifndef __CTK_TEXTEDIT_H__ +#define __CTK_TEXTEDIT_H__ + +#include "ctk/ctk.h" + +/** + * Instantiating macro for the CTK textedit widget. + * + * + * \param tx The x position of the widget. + * \param ty The y position of the widget. + * \param tw The width of the widget. + * \param th The height of the widget. + * \param ttext The text buffer to be edited. + */ +#define CTK_TEXTEDIT(tx, ty, tw, th, ttext) \ + {CTK_LABEL(tx, ty, tw, th, ttext)}, 0, 0 +struct ctk_textedit { + struct ctk_label label; + unsigned char xpos, ypos; +}; + +void ctk_textedit_init(struct ctk_textedit *t); + +void ctk_textedit_add(struct ctk_window *w, + struct ctk_textedit *t); + +void ctk_textedit_eventhandler(struct ctk_textedit *t, + process_event_t s, + process_data_t data); + +#endif /* __CTK_TEXTEDIT_H__ */ diff --git a/core/lib/ctk-textentry-checkbox.c b/core/lib/ctk-textentry-checkbox.c new file mode 100644 index 000000000..da8d08c81 --- /dev/null +++ b/core/lib/ctk-textentry-checkbox.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2002-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 operating system. + * + * $Id: ctk-textentry-checkbox.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ + +#include "ctk/ctk.h" + +#include "ctk-textentry-checkbox.h" + +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_textentry_checkbox_input(ctk_arch_key_t c, + struct ctk_textentry *t) +{ + switch(c) { + case 'X': + case 'x': + *t->text = 'x'; + return 1; + + case ' ': + *t->text = *t->text == 'x'? 0:'x'; + return 1; + + case CH_DEL: + case CH_ENTER: + case CTK_CONF_WIDGETDOWN_KEY: + case CTK_CONF_WIDGETUP_KEY: + return 0; + } + return 1; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/core/lib/ctk-textentry-checkbox.h b/core/lib/ctk-textentry-checkbox.h new file mode 100644 index 000000000..13fdd681a --- /dev/null +++ b/core/lib/ctk-textentry-checkbox.h @@ -0,0 +1,41 @@ +/* + * 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: ctk-textentry-checkbox.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ +#ifndef __CTK_TEXTENTRY_CHECKBOX_H__ +#define __CTK_TEXTENTRY_CHECKBOX_H__ + +unsigned char ctk_textentry_checkbox_input(ctk_arch_key_t c, + struct ctk_textentry *t); + +#endif /* __CTK_TEXTENTRY_CHECKBOX_H__ */ diff --git a/core/lib/ctk-textentry-cmdline.c b/core/lib/ctk-textentry-cmdline.c new file mode 100644 index 000000000..c9f0d3ee9 --- /dev/null +++ b/core/lib/ctk-textentry-cmdline.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2002-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 operating system. + * + * $Id: ctk-textentry-cmdline.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ + +#include "ctk/ctk.h" + +#include "lib/ctk-textentry-cmdline.h" + +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_textentry_cmdline_input(ctk_arch_key_t c, + struct ctk_textentry *t) +{ + if(c == CH_ENTER) { + /* ek_post(t->window->owner, ctk_signal_widget_activate, t);*/ + process_post(t->window->owner, ctk_signal_widget_activate, t); + return 1; + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/core/lib/ctk-textentry-cmdline.h b/core/lib/ctk-textentry-cmdline.h new file mode 100644 index 000000000..d3eafc60a --- /dev/null +++ b/core/lib/ctk-textentry-cmdline.h @@ -0,0 +1,41 @@ +/* + * 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: ctk-textentry-cmdline.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ +#ifndef __CTK_TEXTENTRY_CMDLINE_H__ +#define __CTK_TEXTENTRY_CMDLINE_H__ + +unsigned char ctk_textentry_cmdline_input(ctk_arch_key_t c, + struct ctk_textentry *t); + +#endif /* __CTK_TEXTENTRY_CMDLINE_H__ */ diff --git a/core/lib/ctk-textentry-multiline.c b/core/lib/ctk-textentry-multiline.c new file mode 100644 index 000000000..e12d7b87f --- /dev/null +++ b/core/lib/ctk-textentry-multiline.c @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2002-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 operating system. + * + * $Id: ctk-textentry-multiline.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ + +#include + +#include "ctk/ctk.h" + +#include "lib/ctk-textentry-multiline.h" + +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_textentry_multiline_input(ctk_arch_key_t c, + struct ctk_textentry *t) +{ + unsigned char len; + + switch(c) { + case 0: + t->xpos = strlen(&t->text[t->ypos * (t->len + 1)]); + if(t->xpos == t->len) { + --t->xpos; + } + return 1; + + case CH_CURS_UP: + if(t->ypos == 0) { + t->xpos = 0; + return 1; + } + --t->ypos; + break; + + case CH_CURS_DOWN: + if(t->ypos == t->h - 1) { + t->xpos = strlen(&t->text[t->ypos * (t->len + 1)]); + if(t->xpos == t->len) { + --t->xpos; + } + return 1; + } + ++t->ypos; + break; + + case CH_ENTER: + if(t->ypos == t->h - 1) { + return 0; + } + ++t->ypos; + t->xpos = 0; + return 1; + + default: + return 0; + } + + len = strlen(&t->text[t->ypos * (t->len + 1)]); + if(t->xpos > len) { + t->xpos = len; + } + return 1; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/core/lib/ctk-textentry-multiline.h b/core/lib/ctk-textentry-multiline.h new file mode 100644 index 000000000..cf32d24d2 --- /dev/null +++ b/core/lib/ctk-textentry-multiline.h @@ -0,0 +1,41 @@ +/* + * 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: ctk-textentry-multiline.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ +#ifndef __CTK_TEXTENTRY_MULTILINE_H__ +#define __CTK_TEXTENTRY_MULTILINE_H__ + +unsigned char ctk_textentry_multiline_input(ctk_arch_key_t c, + struct ctk_textentry *t); + +#endif /* __CTK_TEXTENTRY_MULTILINE_H__ */ diff --git a/core/lib/libconio.c b/core/lib/libconio.c new file mode 100644 index 000000000..3b00931c6 --- /dev/null +++ b/core/lib/libconio.c @@ -0,0 +1,190 @@ +/* + * 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: libconio.c,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ + +#include +#include "libconio.h" + +static unsigned char cursx, cursy; +static unsigned char reversed; +static unsigned char color; + +/*-----------------------------------------------------------------------------------*/ +unsigned char +wherex(void) +{ + return cursx; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +wherey(void) +{ + return cursy; +} +/*-----------------------------------------------------------------------------------*/ +void +clrscr(void) +{ + unsigned char x, y; + + for(x = 0; x < LIBCONIO_SCREEN_WIDTH; ++x) { + for(y = 0; y < LIBCONIO_SCREEN_HEIGHT; ++y) { + gotoxy(x, y); + cputc(' '); + } + } +} +/*-----------------------------------------------------------------------------------*/ +void +revers(unsigned char c) +{ + reversed = c; +} +/*-----------------------------------------------------------------------------------*/ +void +cputc(char c) +{ + ctk_arch_draw_char(c, cursx, cursy, reversed, color); + ++cursx; +} +/*-----------------------------------------------------------------------------------*/ +void +cputs(char *str) +{ + while(*str != 0) { + cputc(*str++); + } + + /* int i; + for(i = 0; i < strlen(str); ++i) { + cputc(str[i]); + }*/ +} +/*-----------------------------------------------------------------------------------*/ +void +cclear(unsigned char length) +{ + int i; + for(i = 0; i < length; ++i) { + cputc(' '); + } +} +/*-----------------------------------------------------------------------------------*/ +void +chline(unsigned char length) +{ + int i; + for(i = 0; i < length; ++i) { + cputc('-'); + } +} +/*-----------------------------------------------------------------------------------*/ +void +cvline(unsigned char length) +{ + int i; + for(i = 0; i < length; ++i) { + cputc('|'); + --cursx; + ++cursy; + } +} +/*-----------------------------------------------------------------------------------*/ +void +gotoxy(unsigned char x, unsigned char y) +{ + cursx = x; + cursy = y; +} +/*-----------------------------------------------------------------------------------*/ +void +cclearxy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + cclear(length); +} +/*-----------------------------------------------------------------------------------*/ +void +chlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + chline(length); +} +/*-----------------------------------------------------------------------------------*/ +void +cvlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + cvline(length); +} +/*-----------------------------------------------------------------------------------*/ +void +cputsxy(unsigned char x, unsigned char y, char *str) +{ + gotoxy(x, y); + cputs(str); +} +/*-----------------------------------------------------------------------------------*/ +void +cputcxy(unsigned char x, unsigned char y, char c) +{ + gotoxy(x, y); + cputc(c); +} +/*-----------------------------------------------------------------------------------*/ +void +textcolor(unsigned char c) +{ + color = c; +} +/*-----------------------------------------------------------------------------------*/ +void +bgcolor(unsigned char c) +{ + +} +/*-----------------------------------------------------------------------------------*/ +void +bordercolor(unsigned char c) +{ + +} +/*-----------------------------------------------------------------------------------*/ +void +screensize(unsigned char *x, unsigned char *y) +{ + *x = LIBCONIO_SCREEN_WIDTH; + *y = LIBCONIO_SCREEN_HEIGHT; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/core/lib/libconio.h b/core/lib/libconio.h new file mode 100644 index 000000000..5adf1f37b --- /dev/null +++ b/core/lib/libconio.h @@ -0,0 +1,85 @@ +/* + * 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: libconio.h,v 1.1 2006/06/17 22:41:17 adamdunkels Exp $ + * + */ + +#ifndef __LIBCONIO_H__ +#define __LIBCONIO_H__ + +/* This function must be implemented specifically for the + architecure: */ +void ctk_arch_draw_char(char c, + unsigned char xpos, + unsigned char ypos, + unsigned char reversedflag, + unsigned char color); + +/* Default definitions that should be overridden by calling module. */ +#ifndef LIBCONIO_CONF_SCREEN_WIDTH +#define LIBCONIO_SCREEN_WIDTH 40 +#else +#define LIBCONIO_SCREEN_WIDTH LIBCONIO_CONF_SCREEN_WIDTH +#endif /* LIBCONIO_SCREEN_WIDTH */ + +#ifndef LIBCONIO_CONF_SCREEN_HEIGHT +#define LIBCONIO_SCREEN_HEIGHT 25 +#else +#define LIBCONIO_SCREEN_HEIGHT LIBCONIO_CONF_SCREEN_HEIGHT +#endif /* LIBCONIO_CONF_SCREEN_HEIGHT */ + + + +/* These are function declarations for functions implemented in libconio.c */ +unsigned char wherex(void); +unsigned char wherey(void); +void clrscr(void); +void bgcolor(unsigned char c); +void bordercolor(unsigned char c); +void screensize(unsigned char *x, unsigned char *y); +void revers(unsigned char c); +void cputc(char c); +void cputs(char *str); +void cclear(unsigned char length); +void chline(unsigned char length); +void cvline(unsigned char length); +void gotoxy(unsigned char x, unsigned char y); +void cclearxy(unsigned char x, unsigned char y, unsigned char length); +void chlinexy(unsigned char x, unsigned char y, unsigned char length); +void cvlinexy(unsigned char x, unsigned char y, unsigned char length); +void cputsxy(unsigned char x, unsigned char y, char *str); +void cputcxy(unsigned char x, unsigned char y, char c); +void textcolor(unsigned char c); + + + +#endif /* __LIBCONIO_H__ */ diff --git a/core/lib/list.c b/core/lib/list.c new file mode 100644 index 000000000..96272e36c --- /dev/null +++ b/core/lib/list.c @@ -0,0 +1,306 @@ +/** + * \addtogroup list + * @{ + */ + +/** + * \file + * Linked list library implementation. + * + * \author Adam Dunkels + * + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: list.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#include "lib/list.h" + +#define NULL 0 + +struct list { + struct list *next; +}; + +/*---------------------------------------------------------------------------*/ +/** + * Initialize a list. + * + * This function initalizes a list. The list will be empty after this + * function has been called. + * + * \param list The list to be initialized. + */ +void +list_init(list_t list) +{ + *list = NULL; +} +/*---------------------------------------------------------------------------*/ +/** + * Get a pointer to the first element of a list. + * + * This function returns a pointer to the first element of the + * list. The element will \b not be removed from the list. + * + * \param list The list. + * \return A pointer to the first element on the list. + * + * \sa list_tail() + */ +void * +list_head(list_t list) +{ + return *list; +} +/*---------------------------------------------------------------------------*/ +/** + * Duplicate a list. + * + * This function duplicates a list by copying the list reference, but + * not the elements. + * + * \note This function does \b not copy the elements of the list, but + * merely duplicates the pointer to the first element of the list. + * + * \param dest The destination list. + * \param src The source list. + */ +void +list_copy(list_t dest, list_t src) +{ + *dest = *src; +} +/*---------------------------------------------------------------------------*/ +/** + * Get the tail of a list. + * + * This function returns a pointer to the elements following the first + * element of a list. No elements are removed by this function. + * + * \param list The list + * \return A pointer to the element after the first element on the list. + * + * \sa list_head() + */ +void * +list_tail(list_t list) +{ + struct list *l; + + if(*list == NULL) { + return NULL; + } + + for(l = *list; l->next != NULL; l = l->next); + + return l; +} +/*---------------------------------------------------------------------------*/ +/** + * Add an item at the end of a list. + * + * This function adds an item to the end of the list. + * + * \param list The list. + * \param item A pointer to the item to be added. + * + * \sa list_push() + * + */ +void +list_add(list_t list, void *item) +{ + struct list *l; + + ((struct list *)item)->next = NULL; + + l = list_tail(list); + + if(l == NULL) { + *list = item; + } else { + l->next = item; + } +} +/*---------------------------------------------------------------------------*/ +/** + * Add an item to the start of the list. + */ +void +list_push(list_t list, void *item) +{ + /* struct list *l;*/ + + ((struct list *)item)->next = *list; + *list = item; +} +/*---------------------------------------------------------------------------*/ +/** + * Remove the last object on the list. + * + * This function removes the last object on the list and returns it. + * + * \param list The list + * \return The removed object + * + */ +void * +list_chop(list_t list) +{ + struct list *l, *r; + + if(*list == NULL) { + return NULL; + } + if(((struct list *)*list)->next == NULL) { + l = *list; + *list = NULL; + return l; + } + + for(l = *list; l->next->next != NULL; l = l->next); + + r = l->next; + l->next = NULL; + + return r; +} +/*---------------------------------------------------------------------------*/ +/** + * Remove the first object on a list. + * + * This function removes the first object on the list and returns a + * pointer to the list. + * + * \param list The list. + * \return The new head of the list. + */ +/*---------------------------------------------------------------------------*/ +void * +list_pop(list_t list) +{ + if(*list != NULL) { + *list = ((struct list *)*list)->next; + } + + return *list; +} +/*---------------------------------------------------------------------------*/ +/** + * Remove a specific element from a list. + * + * This function removes a specified element from the list. + * + * \param list The list. + * \param item The item that is to be removed from the list. + * + */ +/*---------------------------------------------------------------------------*/ +void +list_remove(list_t list, void *item) +{ + struct list *l, *r; + + if(*list == NULL) { + return; + } + + r = NULL; + for(l = *list; l != NULL; l = l->next) { + if(l == item) { + if(r == NULL) { + /* First on list */ + *list = l->next; + } else { + /* Not first on list */ + r->next = l->next; + } + l->next = NULL; + return; + } + r = l; + } +} +/*---------------------------------------------------------------------------*/ +/** + * Get the length of a list. + * + * This function counts the number of elements on a specified list. + * + * \param list The list. + * \return The length of the list. + */ +/*---------------------------------------------------------------------------*/ +int +list_length(list_t list) +{ + struct list *l; + int n = 0; + + for(l = *list; l != NULL; l = l->next) { + ++n; + } + + return n; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Insert an item after a specified item on the list + * \param list The list + * \param previtem The item after which the new item should be inserted + * \param newitem The new item that is to be inserted + * \author Adam Dunkels + * + * This function inserts an item right after a specified + * item on the list. This function is useful when using + * the list module to ordered lists. + * + * If previtem is NULL, the new item is placed at the + * start of the list. + * + */ +void +list_insert(list_t list, void *previtem, void *newitem) +{ + if(previtem == NULL) { + list_push(list, newitem); + } else { + + ((struct list *)newitem)->next = ((struct list *)previtem)->next; + ((struct list *)previtem)->next = newitem; + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/lib/list.h b/core/lib/list.h new file mode 100644 index 000000000..8925429f2 --- /dev/null +++ b/core/lib/list.h @@ -0,0 +1,115 @@ +/** \addtogroup lib + @{ */ +/** + * \defgroup list Linked list library + * + * The linked list library provides a set of functions for + * manipulating linked lists. + * + * A linked list is made up of elements where the first element \b + * must be a pointer. This pointer is used by the linked list library + * to form lists of the elements. + * + * Lists are declared with the LIST() macro. The declaration specifies + * the name of the list that later is used with all list functions. + * + * Lists can be manipulated by inserting or removing elements from + * either sides of the list (list_push(), list_add(), list_pop(), + * list_chop()). A specified element can also be removed from inside a + * list with list_remove(). The head and tail of a list can be + * extracted using list_head() and list_tail(), respecitively. + * + * @{ + */ + +/** + * \file + * Linked list manipulation routines. + * \author Adam Dunkels + * + * + */ + + + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: list.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __LIST_H__ +#define __LIST_H__ + +#define LIST_CONCAT2(s1, s2) s1##s2 +#define LIST_CONCAT(s1, s2) LIST_CONCAT2(s1, s2) + +/** + * Declare a linked list. + * + * This macro declares a linked list with the specified \c type. The + * type \b must be a structure (\c struct) with its first element + * being a pointer. This pointer is used by the linked list library to + * form the linked lists. + * + * \param name The name of the list. + */ +#define LIST(name) \ + static void *LIST_CONCAT(name,_list) = NULL; \ + static list_t name = (list_t)&LIST_CONCAT(name,_list) + +/** + * The linked list type. + * + */ +typedef void ** list_t; + +void list_init(list_t list); +void * list_head(list_t list); +void * list_tail(list_t list); +void * list_pop (list_t list); +void list_push(list_t list, void *item); + +void * list_chop(list_t list); + +void list_add(list_t list, void *item); +void list_remove(list_t list, void *item); + +int list_length(list_t list); + +void list_copy(list_t dest, list_t src); + +void list_insert(list_t list, void *previtem, void *newitem); + +#endif /* __LIST_H__ */ + +/** @} */ +/** @} */ diff --git a/core/lib/malloc.c b/core/lib/malloc.c new file mode 100644 index 000000000..a06404596 --- /dev/null +++ b/core/lib/malloc.c @@ -0,0 +1,439 @@ +/* Copyright (c) 2002, 2004 Joerg Wunsch + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. +*/ + + +/* $Id: malloc.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ */ + +#include + +#ifdef MALLOC_TEST +#include "malloc.h" +char mymem[256]; +#else +#include +#include "contiki.h" +#include "lib/malloc.h" +#endif /* !MALLOC_TEST */ + +/* + * Exported interface: + * + * When extending the data segment, the allocator will not try to go + * beyond the current stack limit, decreased by __malloc_margin bytes. + * Thus, all possible stack frames of interrupt routines that could + * interrupt the current function, plus all further nested function + * calls must not require more stack space, or they'll risk to collide + * with the data segment. + */ + +char *__brkval; +struct __freelist *__flp; + +#define handle nx + +void * +malloc(size_t len) +{ + struct __freelist *fp1, *fp2; + char *cp; + size_t s, avail; + + if (len <= 0) + return 0; + + len = (len + MALLOC_ROUNDUP) & ~MALLOC_ROUNDUP; + + /* + * First, walk the free list and try finding a chunk that + * would match exactly. If we found one, we are done. While + * walking, note down the size of the largest chunk we found + * that would still fit the request -- we need it for step 2. + * + */ + for (s = 0, fp1 = __flp, fp2 = 0; + fp1; + fp2 = fp1, fp1 = fp1->nx) { + if (fp1->sz == len) { + /* + * Found it. Disconnect the chunk from the + * freelist, and return it. + */ + if (fp2) + fp2->nx = fp1->nx; + else + __flp = fp1->nx; + fp1->handle = NULL; + return &fp1[1]; + } + if (fp1->sz > len) { + if (s == 0 || fp1->sz < s) + s = fp1->sz; + } + } + /* + * Step 2: If we found a chunk on the freelist that would fit + * (but was too large), look it up again and use it, since it + * is our closest match now. Since the freelist entry needs + * to be split into two entries then, watch out that the + * difference between the requested size and the size of the + * chunk found is large enough for another freelist entry; if + * not, just enlarge the request size to what we have found, + * and use the entire chunk. + */ + if (s) { + if (s - len < sizeof(struct __freelist)) + len = s; + for (fp1 = __flp, fp2 = 0; + fp1; + fp2 = fp1, fp1 = fp1->nx) { + if (fp1->sz == s) { + if (len == s) { + /* + * Use entire chunk; same as + * above. + */ + if (fp2) + fp2->nx = fp1->nx; + else + __flp = fp1->nx; + fp1->handle = NULL; + return &fp1[1]; + } + /* + * Split them up. Note that we leave + * the first part as the new (smaller) + * freelist entry, and return the + * upper portion to the caller. This + * saves us the work to fix up the + * freelist chain; we just need to + * fixup the size of the current + * entry, and note down the size of + * the new chunk before returning it + * to the caller. + */ + cp = (char *)fp1; + s -= len; + cp += s; + fp2 = (struct __freelist *)cp; + fp2->sz = len; + fp1->sz = s - sizeof(struct __freelist); + fp2->handle = NULL; + return &fp2[1]; + } + } + } + /* + * Step 3: If the request could not be satisfied from a + * freelist entry, just prepare a new chunk. This means we + * need to obtain more memory first. The largest address just + * not allocated so far is remembered in the brkval variable. + * Under Unix, the "break value" was the end of the data + * segment as dynamically requested from the operating system. + * Since we don't have an operating system, just make sure + * that we don't collide with the stack. + */ + if (__brkval == 0) + __brkval = __malloc_heap_start; + cp = __malloc_heap_end; + avail = cp - __brkval; + /* + * Both tests below are needed to catch the case len >= 0xfffe. + */ + if (avail >= len && avail >= len + sizeof(struct __freelist)) { + fp1 = (struct __freelist *)__brkval; + __brkval += len + sizeof(struct __freelist); + fp1->sz = len; + fp1->handle = NULL; + return &fp1[1]; + } + /* + * Step 4: There's no help, just fail. :-/ + */ + return 0; +} + +void +free(void *p) +{ + struct __freelist *fp1, *fp2, *fpnew; + char *cp1, *cp2, *cpnew; + + /* ISO C says free(NULL) must be a no-op */ + if (p == 0) + return; + + cpnew = p; + cpnew -= sizeof(struct __freelist); + fpnew = (struct __freelist *)cpnew; + fpnew->nx = 0; + + /* + * Trivial case first: if there's no freelist yet, our entry + * will be the only one on it. + */ + if (__flp == 0) { + __flp = fpnew; + return; + } + + /* + * Now, find the position where our new entry belongs onto the + * freelist. Try to aggregate the chunk with adjacent chunks + * if possible. + */ + for (fp1 = __flp, fp2 = 0; + fp1; + fp2 = fp1, fp1 = fp1->nx) { + if (fp1 < fpnew) + continue; + cp1 = (char *)fp1; + fpnew->nx = fp1; + if (((char *)&fpnew[1]) + fpnew->sz == cp1) { + /* upper chunk adjacent, assimilate it */ + fpnew->sz += fp1->sz + sizeof(struct __freelist); + fpnew->nx = fp1->nx; + } + if (fp2 == 0) { + /* new head of freelist */ + __flp = fpnew; + return; + } + break; + } + /* + * Note that we get here either if we hit the "break" above, + * or if we fell off the end of the loop. The latter means + * we've got a new topmost chunk. Either way, try aggregating + * with the lower chunk if possible. + */ + fp2->nx = fpnew; + cp2 = (char *)&fp2[1]; + if (cp2 + fp2->sz == cpnew) { + /* lower junk adjacent, merge */ + fp2->sz += fpnew->sz + sizeof(struct __freelist); + fp2->nx = fpnew->nx; + } +} + +#ifdef MALLOC_TEST + +#include +#include +#include +#include + +void *handles[32]; +size_t sizes[32]; + + +void * +alloc(size_t s) +{ + void *p; + + if ((p = malloc(s)) == 0) { + malloc_compact(); + if ((p = malloc(s)) == 0) + return 0; + } + memset(p, 0xd0, s); + return p; +} + +void +printfreelist(void) +{ + struct __freelist *fp1; + int i; + + if (!__flp) { + printf("no free list\n"); + return; + } + + for (i = 0, fp1 = __flp; fp1; i++, fp1 = fp1->nx) { + printf("free %d @ %u: size %u, next ", + i, (char *)fp1 - mymem, fp1->sz); + if (fp1->nx) + printf("%u\n", (char *)fp1->nx - mymem); + else + printf("NULL\n"); + } +} + +int +compare(const void *p1, const void *p2) +{ + return *((size_t *)p1) - *((size_t *)p2); +} + +void +printalloc(void) +{ + int j, k; + size_t i; + size_t sum, sum2; + void *sortedhandles[32]; + struct __freelist *fp; + char *cp; + + for (i = j = k = sum = sum2 = 0; + i < sizeof handles / sizeof (void *); + i++) + if (sizes[i]) { + j++; + sum += sizes[i]; + if (handles[i]) { + k++; + sum2 += sizes[i]; + } + } + printf("brkval: %d, %d request%s => sum %u bytes " + "(actually %d reqs => %u bytes)\n", + (char *)__brkval - mymem, j, j == 1? "": "s", sum, k, sum2); + memcpy(sortedhandles, handles, sizeof sortedhandles); + qsort(sortedhandles, 32, sizeof(void *), compare); + for (i = j = 0; i < sizeof sortedhandles / sizeof (void *); i++) + if ((cp = sortedhandles[i])) { + cp -= sizeof(struct __freelist); + fp = (struct __freelist *)cp; + printf("alloc %d @ %u: %u bytes, handle %p\n", + j, (char *)fp - mymem, fp->sz, fp->handle); + j++; + } + +} + + +void +printblk(void) +{ + struct __freelist *fp = __flp; + struct __freelist *ap = (struct __freelist *)__malloc_heap_start; + struct __freelist *end = (struct __freelist *)__brkval; + int b = 0; + int e = 0; + + if (fp == 0) + fp = end; + + alloclist: + while (ap < fp) { + printf("Alloc %d @ %u: %u bytes, handle %p\n", + b, (char *)ap - mymem, ap->sz, ap->handle); + ap = (void *)(((char *)ap) + sizeof(struct __freelist) + ap->sz); + b++; + } + + if (fp < end) { + printf("Free %d @ %u: size %u, next ", + e, (char *)fp - mymem, fp->sz); + if (fp->nx) + printf("%u\n", (char *)fp->nx - mymem); + else + printf("NULL\n"); + ap = (void *)(((char *)fp) + sizeof(struct __freelist) + fp->sz); + fp = fp->nx; + if (fp == 0) + fp = end; + e++; + } + + if (ap < end) + goto alloclist; +} + +int +main(void) +{ + int i, j, k, l, m, om, p, f; + size_t s; + + srand(time(0) ^ getpid()); + + for (k = 0; k < 100; k++) { + memset(handles, 0, sizeof handles); + memset(sizes, 0, sizeof sizes); + + j = rand() % 16 + 15; + l = rand() % 80 + 7; + + for (i = s = 0; i < j && s < 256; i++) { + sizes[i] = rand() % l + 1; + s += sizes[i]; + } + j = i; + for (m = om = 1, p = 1, f = 0; m < 1000; m++) { + for (i = s = 0; i < j; i++) + if (handles[i]) + s++; + if (s == (unsigned)j) + break; + + if (m / om > 10) { + p <<= 1; + p |= 1; + } + + for (i = 0; i < j; i++) + if (rand() & p) { + if (!handles[i]) { + if ((handles[i] = alloc(sizes[i])) == 0) + f++; + else if (sizes[i] & 1) + malloc_unlock(&handles[i]); + } + } + for (i = 0; i < j; i++) { + if (rand() & 1) { + free(handles[i]); + handles[i] = 0; + } + } + } + if (f) + printf("%d alloc failure%s total\n", + f, f == 1? "": "s"); + printf("After alloc:\n"); + printalloc(); + //printfreelist(); + printblk(); + for (i = 0; i < j; i++) + free(handles[i]); + printf("After cleanup:\n"); + printfreelist(); + //printblk(); + } + + return 0; +} + +#endif /* MALLOC_TEST */ diff --git a/core/lib/malloc.h b/core/lib/malloc.h new file mode 100644 index 000000000..af8e6bc72 --- /dev/null +++ b/core/lib/malloc.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2004, Joerg Wunsch + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. +*/ + +/* $Id: malloc.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ */ + +#ifndef MALLOC_H +#define MALLOC_H + +#if !defined(__DOXYGEN__) + +struct __freelist { + size_t sz; + struct __freelist *nx; +}; + +#endif + +/* + * Only unlocked memory can be subject to compaction. + * + * Malloc and realloc return locked memory. + */ +void malloc_unlock(void **h); +void malloc_lock(void **h); +void malloc_compact(void); +void malloc_compact_one(void); + +void *malloc(size_t size); +void *realloc(void *ptr, size_t size); +void free(void *ptr); + +extern char *__brkval; /* first location not yet allocated */ +extern struct __freelist *__flp; /* freelist pointer (head of freelist) */ + +#define MALLOC_ROUNDUP (sizeof(int) - 1) + +#ifdef MALLOC_TEST +/* + * When compiling malloc.c/realloc.c natively on a host machine, it will + * include a main() that performs a regression test. This is meant as + * a debugging aid, where a normal source-level debugger will help to + * verify that the various allocator structures have the desired + * appearance at each stage. + * + */ + +extern void *mymalloc(size_t); +extern void myfree(void *); +extern void *myrealloc(void *, size_t); + +#define malloc mymalloc +#define free myfree +#define realloc myrealloc + +#define __malloc_heap_start &mymem[0] +#define __malloc_heap_end &mymem[256] +extern char mymem[]; + +#endif /* MALLOC_TEST */ + +#endif /* MALLOC_H */ diff --git a/core/lib/malloc_compact.c b/core/lib/malloc_compact.c new file mode 100644 index 000000000..04cf8e0bd --- /dev/null +++ b/core/lib/malloc_compact.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: malloc_compact.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include +#include + +#ifdef MALLOC_TEST +#include "malloc.h" +#else +#include "contiki.h" +#include "lib/malloc.h" +#endif /* !MALLOC_TEST */ + +#define handle nx + +void +malloc_unlock(void **h) +{ + struct __freelist *t = *h; + t = &t[-1]; + t->handle = (void *)h; +} + +void +malloc_lock(void **h) +{ + struct __freelist *t = *h; + t = &t[-1]; + t->handle = NULL; +} + +static int +compact1(struct __freelist **flp) +{ + struct __freelist *fp = *flp, *fp2; + struct __freelist *ap1, *ap2; + struct __freelist *end = (struct __freelist *)__brkval; + + ap1 = (void *)(((char *)fp) + sizeof(struct __freelist) + fp->sz); + if (ap1 >= end) + return 0; + if (ap1->handle == NULL) + return 0; + + ap2 = (void *)(((char *)ap1) + sizeof(struct __freelist) + ap1->sz); + fp2 = fp->nx; + + if (ap2 != fp2) { /* 2 blocks become 2 */ + size_t s = fp->sz; + + fp->sz = ap1->sz; + fp->handle = ap1->handle; + memcpy(&fp[1], &ap1[1], ap1->sz); + *(void **)(fp->handle) = &fp[1]; + + fp = (void *)(((char *)fp) + sizeof(struct __freelist) + fp->sz); + fp->sz = s; + fp->nx = fp2; + *flp = fp; + return 1; + } + + if (ap2 == fp2) { /* 3 blocks become 2 */ + size_t s = fp->sz + fp2->sz + sizeof(struct __freelist); + + fp->sz = ap1->sz; + fp->handle = ap1->handle; + memcpy(&fp[1], &ap1[1], ap1->sz); + *(void **)(fp->handle) = &fp[1]; + + fp = (void *)(((char *)fp) + sizeof(struct __freelist) + fp->sz); + fp->sz = s; + fp->nx = fp2->nx; + *flp = fp; + return 1; + } + + return 0; +} + +void +malloc_compact(void) +{ + struct __freelist **flp; + + flp = &__flp; + while (*flp != NULL) { + while (compact1(flp)) + ; + flp = &((*flp)->nx); + } +} + +void +malloc_compact_one(void) +{ + struct __freelist **flp; + + flp = &__flp; + while (*flp != NULL) { + if (compact1(flp)) + return ; + flp = &((*flp)->nx); + } +} diff --git a/core/lib/me.c b/core/lib/me.c new file mode 100644 index 000000000..3d706b532 --- /dev/null +++ b/core/lib/me.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: me.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** \addtogroup me + * @{ */ + +/** + * \file + * Implementation of the table-driven Manchester encoding and decoding. + * \author + * Adam Dunkels + */ + +#include "me_tabs.h" + +/*---------------------------------------------------------------------------*/ +/** + * Manchester encode an 8-bit byte. + * + * This function Manchester encodes an 8-bit byte into a 16-bit + * word. The function me_decode() does the inverse operation. + * + * \param c The byte to be encoded + * + * \retval The encoded word. + */ +/*---------------------------------------------------------------------------*/ +unsigned short +me_encode(unsigned char c) +{ + return me_encode_tab[c]; +} +/*---------------------------------------------------------------------------*/ +/** + * Decode a Manchester encoded 16-bit word. + * + * This function decodes a Manchester encoded 16-bit word into a 8-bit + * byte. The function does not check for parity errors in the encoded + * byte. + * + * \param m The 16-bit Manchester encoded word + * \return The decoded 8-bit byte + */ +/*---------------------------------------------------------------------------*/ +unsigned char +me_decode16(unsigned short m) +{ + unsigned char m1, m2, c; + + m1 = m >> 8; + m2 = m & 0xff; + + c = (me_decode_tab[m1] << 4) | + me_decode_tab[m2]; + return c; +} +/*---------------------------------------------------------------------------*/ +/** + * Decode a Manchester encoded 8-bit byte. + * + * This function decodes a Manchester encoded 8-bit byte into 4 + * decoded bits.. The function does not check for parity errors in the + * encoded byte. + * + * \param m The 8-bit Manchester encoded byte + * \return The decoded 4 bits + */ +/*---------------------------------------------------------------------------*/ +unsigned char +me_decode8(unsigned char m) +{ + return me_decode_tab[m]; +} +/*---------------------------------------------------------------------------*/ +/** + * Check if an encoded byte is valid. + */ +/*---------------------------------------------------------------------------*/ +unsigned char +me_valid(unsigned char m) +{ + return me_valid_tab[m]; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ + diff --git a/core/lib/me.h b/core/lib/me.h new file mode 100644 index 000000000..0849558d8 --- /dev/null +++ b/core/lib/me.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: me.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** \addtogroup lib + @{ */ + +/** + * \defgroup me Table-driven Manchester encoding and decoding + * + * Manchester encoding is a bit encoding scheme which translates each + * bit into two bits: the original bit and the inverted bit. + * + * Manchester encoding is used for transmitting ones and zeroes + * between two computers. The Manchester encoding reduces the receive + * oscillator drift by making sure that no consecutive ones or zeroes + * are ever transmitted. + * + * The table driven method of Manchester encoding and decoding uses + * two tables with 256 entries. One table is a direct mapping of an + * 8-bit byte into a 16-bit Manchester encoding of the byte. The + * second table is a mapping of a Manchester encoded 8-bit byte to 4 + * decoded bits. + * + * @{ + */ + +/** + * \file + * Header file for the table-driven Manchester encoding and decoding + * \author + * Adam Dunkels + * + */ + +#ifndef __ME_H__ +#define __ME_H__ + +unsigned char me_valid(unsigned char m); +unsigned short me_encode(unsigned char c); +unsigned char me_decode16(unsigned short m); +unsigned char me_decode8(unsigned char m); + +#endif /* __ME_H__ */ + +/** @} */ +/** @} */ diff --git a/core/lib/me_tabs.c b/core/lib/me_tabs.c new file mode 100644 index 000000000..7846c31fd --- /dev/null +++ b/core/lib/me_tabs.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: me_tabs.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +const unsigned short me_encode_tab[256] = { +0x5555, 0x5556, 0x5559, 0x555a, 0x5565, 0x5566, 0x5569, 0x556a, 0x5595, +0x5596, 0x5599, 0x559a, 0x55a5, 0x55a6, 0x55a9, 0x55aa, 0x5655, 0x5656, +0x5659, 0x565a, 0x5665, 0x5666, 0x5669, 0x566a, 0x5695, 0x5696, 0x5699, +0x569a, 0x56a5, 0x56a6, 0x56a9, 0x56aa, 0x5955, 0x5956, 0x5959, 0x595a, +0x5965, 0x5966, 0x5969, 0x596a, 0x5995, 0x5996, 0x5999, 0x599a, 0x59a5, +0x59a6, 0x59a9, 0x59aa, 0x5a55, 0x5a56, 0x5a59, 0x5a5a, 0x5a65, 0x5a66, +0x5a69, 0x5a6a, 0x5a95, 0x5a96, 0x5a99, 0x5a9a, 0x5aa5, 0x5aa6, 0x5aa9, +0x5aaa, 0x6555, 0x6556, 0x6559, 0x655a, 0x6565, 0x6566, 0x6569, 0x656a, +0x6595, 0x6596, 0x6599, 0x659a, 0x65a5, 0x65a6, 0x65a9, 0x65aa, 0x6655, +0x6656, 0x6659, 0x665a, 0x6665, 0x6666, 0x6669, 0x666a, 0x6695, 0x6696, +0x6699, 0x669a, 0x66a5, 0x66a6, 0x66a9, 0x66aa, 0x6955, 0x6956, 0x6959, +0x695a, 0x6965, 0x6966, 0x6969, 0x696a, 0x6995, 0x6996, 0x6999, 0x699a, +0x69a5, 0x69a6, 0x69a9, 0x69aa, 0x6a55, 0x6a56, 0x6a59, 0x6a5a, 0x6a65, +0x6a66, 0x6a69, 0x6a6a, 0x6a95, 0x6a96, 0x6a99, 0x6a9a, 0x6aa5, 0x6aa6, +0x6aa9, 0x6aaa, 0x9555, 0x9556, 0x9559, 0x955a, 0x9565, 0x9566, 0x9569, +0x956a, 0x9595, 0x9596, 0x9599, 0x959a, 0x95a5, 0x95a6, 0x95a9, 0x95aa, +0x9655, 0x9656, 0x9659, 0x965a, 0x9665, 0x9666, 0x9669, 0x966a, 0x9695, +0x9696, 0x9699, 0x969a, 0x96a5, 0x96a6, 0x96a9, 0x96aa, 0x9955, 0x9956, +0x9959, 0x995a, 0x9965, 0x9966, 0x9969, 0x996a, 0x9995, 0x9996, 0x9999, +0x999a, 0x99a5, 0x99a6, 0x99a9, 0x99aa, 0x9a55, 0x9a56, 0x9a59, 0x9a5a, +0x9a65, 0x9a66, 0x9a69, 0x9a6a, 0x9a95, 0x9a96, 0x9a99, 0x9a9a, 0x9aa5, +0x9aa6, 0x9aa9, 0x9aaa, 0xa555, 0xa556, 0xa559, 0xa55a, 0xa565, 0xa566, +0xa569, 0xa56a, 0xa595, 0xa596, 0xa599, 0xa59a, 0xa5a5, 0xa5a6, 0xa5a9, +0xa5aa, 0xa655, 0xa656, 0xa659, 0xa65a, 0xa665, 0xa666, 0xa669, 0xa66a, +0xa695, 0xa696, 0xa699, 0xa69a, 0xa6a5, 0xa6a6, 0xa6a9, 0xa6aa, 0xa955, +0xa956, 0xa959, 0xa95a, 0xa965, 0xa966, 0xa969, 0xa96a, 0xa995, 0xa996, +0xa999, 0xa99a, 0xa9a5, 0xa9a6, 0xa9a9, 0xa9aa, 0xaa55, 0xaa56, 0xaa59, +0xaa5a, 0xaa65, 0xaa66, 0xaa69, 0xaa6a, 0xaa95, 0xaa96, 0xaa99, 0xaa9a, +0xaaa5, 0xaaa6, 0xaaa9, 0xaaaa, }; +const unsigned char me_decode_tab[256] = { +0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x2, +0x2, 0x3, 0x3, 0x2, 0x2, 0x3, 0x3, 0x0, 0x0, +0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, 0x3, +0x3, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, 0x5, +0x4, 0x4, 0x5, 0x5, 0x6, 0x6, 0x7, 0x7, 0x6, +0x6, 0x7, 0x7, 0x4, 0x4, 0x5, 0x5, 0x4, 0x4, +0x5, 0x5, 0x6, 0x6, 0x7, 0x7, 0x6, 0x6, 0x7, +0x7, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, +0x2, 0x2, 0x3, 0x3, 0x2, 0x2, 0x3, 0x3, 0x0, +0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x2, 0x2, +0x3, 0x3, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, +0x5, 0x4, 0x4, 0x5, 0x5, 0x6, 0x6, 0x7, 0x7, +0x6, 0x6, 0x7, 0x7, 0x4, 0x4, 0x5, 0x5, 0x4, +0x4, 0x5, 0x5, 0x6, 0x6, 0x7, 0x7, 0x6, 0x6, +0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0x8, 0x8, 0x9, +0x9, 0xa, 0xa, 0xb, 0xb, 0xa, 0xa, 0xb, 0xb, +0x8, 0x8, 0x9, 0x9, 0x8, 0x8, 0x9, 0x9, 0xa, +0xa, 0xb, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, 0xc, +0xd, 0xd, 0xc, 0xc, 0xd, 0xd, 0xe, 0xe, 0xf, +0xf, 0xe, 0xe, 0xf, 0xf, 0xc, 0xc, 0xd, 0xd, +0xc, 0xc, 0xd, 0xd, 0xe, 0xe, 0xf, 0xf, 0xe, +0xe, 0xf, 0xf, 0x8, 0x8, 0x9, 0x9, 0x8, 0x8, +0x9, 0x9, 0xa, 0xa, 0xb, 0xb, 0xa, 0xa, 0xb, +0xb, 0x8, 0x8, 0x9, 0x9, 0x8, 0x8, 0x9, 0x9, +0xa, 0xa, 0xb, 0xb, 0xa, 0xa, 0xb, 0xb, 0xc, +0xc, 0xd, 0xd, 0xc, 0xc, 0xd, 0xd, 0xe, 0xe, +0xf, 0xf, 0xe, 0xe, 0xf, 0xf, 0xc, 0xc, 0xd, +0xd, 0xc, 0xc, 0xd, 0xd, 0xe, 0xe, 0xf, 0xf, +0xe, 0xe, 0xf, 0xf, }; +const unsigned char me_valid_tab[256] = { +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, +0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, +0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x1, 0x1, 0x0, 0x0, 0x1, 0x1, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, +0x0, 0x0, 0x0, 0x0, }; diff --git a/core/lib/me_tabs.h b/core/lib/me_tabs.h new file mode 100644 index 000000000..2c88cea99 --- /dev/null +++ b/core/lib/me_tabs.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: me_tabs.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __ME_TABS_H__ +#define __ME_TABS_H__ + +const unsigned short me_encode_tab[256]; +const unsigned char me_decode_tab[256]; +const unsigned char me_valid_tab[256]; + +#endif /* __ME_TABS_H__ */ + diff --git a/core/lib/memb.c b/core/lib/memb.c new file mode 100644 index 000000000..7994ce1c8 --- /dev/null +++ b/core/lib/memb.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: memb.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** + * \addtogroup memb + * @{ + */ + + /** + * \file + * Memory block allocation routines. + * \author Adam Dunkels + */ +#include + +#include "lib/memb.h" + +/*---------------------------------------------------------------------------*/ +void +memb_init(struct memb_blocks *m) +{ + memset(m->count, 0, m->num); + memset(m->mem, 0, m->size * m->num); +} +/*---------------------------------------------------------------------------*/ +void * +memb_alloc(struct memb_blocks *m) +{ + int i; + + for(i = 0; i < m->num; ++i) { + if(m->count[i] == 0) { + /* If this block was unused, we increase the reference count to + indicate that it now is used and return a pointer to the + memory block. */ + ++(m->count[i]); + return (void *)((char *)m->mem + (i * m->size)); + } + } + + /* No free block was found, so we return NULL to indicate failure to + allocate block. */ + return NULL; +} +/*---------------------------------------------------------------------------*/ +char +memb_free(struct memb_blocks *m, void *ptr) +{ + int i; + char *ptr2; + + /* Walk through the list of blocks and try to find the block to + which the pointer "ptr" points to. */ + ptr2 = (char *)m->mem; + for(i = 0; i < m->num; ++i) { + + if(ptr2 == (char *)ptr) { + /* We've found to block to which "ptr" points so we decrease the + reference count and return the new value of it. */ + if(m->count[i] > 0) { + /* Make sure that we don't deallocate free memory. */ + --(m->count[i]); + } + return m->count[i]; + } + ptr2 += m->size; + } + return -1; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/core/lib/memb.h b/core/lib/memb.h new file mode 100644 index 000000000..0b533f155 --- /dev/null +++ b/core/lib/memb.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: memb.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** + * \addtogroup mem + * @{ + */ + + +/** + * \defgroup memb Memory block management functions + * + * The memory block allocation routines provide a simple yet powerful + * set of functions for managing a set of memory blocks of fixed + * size. A set of memory blocks is statically declared with the + * MEMB() macro. Memory blocks are allocated from the declared + * memory by the memb_alloc() function, and are deallocated with the + * memb_free() function. + * + * \note Because of namespace clashes only one MEMB() can be + * declared per C module, and the name scope of a MEMB() memory + * block is local to each C module. + * + * The following example shows how to declare and use a memory block + * called "cmem" which has 8 chunks of memory with each memory chunk + * being 20 bytes large. + * + * @{ + */ + + +/** + * \file + * Memory block allocation routines. + * \author + * Adam Dunkels + * + */ + +#ifndef __MEMB_H__ +#define __MEMB_H__ + +/* + * Here we define a C preprocessing macro for concatenating to + * strings. We need use two macros in order to allow concatenation of + * two #defined macros. + */ +#define MEMB_CONCAT2(s1, s2) s1##s2 +#define MEMB_CONCAT(s1, s2) MEMB_CONCAT2(s1, s2) + +/** + * Declare a memory block. + * + * This macro is used to staticall declare a block of memory that can + * be used by the block allocation functions. The macro statically + * declares a C array with a size that matches the specified number of + * blocks and their individual sizes. + * + * Example: + \code +MEMB(connections, sizeof(struct connection), 16); + \endcode + * + * \param name The name of the memory block (later used with + * memb_init(), memb_alloc() and memb_free()). + * + * \param size The size of each memory chunk, in bytes. + * + * \param num The total number of memory chunks in the block. + * + */ +#define MEMB(name, structure, num) \ + static char MEMB_CONCAT(name,_memb_count)[num]; \ + static structure MEMB_CONCAT(name,_memb_mem)[num]; \ + static struct memb_blocks name = {sizeof(structure), num, \ + MEMB_CONCAT(name,_memb_count), \ + (void *)MEMB_CONCAT(name,_memb_mem)} + +struct memb_blocks { + unsigned short size; + unsigned short num; + char *count; + void *mem; +}; + +/** + * Initialize a memory block that was declared with MEMB(). + * + * \param m A memory block previosly declared with MEMB(). + */ +void memb_init(struct memb_blocks *m); + +/** + * Allocate a memory block from a block of memory declared with MEMB(). + * + * \param m A memory block previosly declared with MEMB(). + */ +void *memb_alloc(struct memb_blocks *m); + +/** + * Deallocate a memory block from a memory block previously declared + * with MEMB(). + * + * \param m m A memory block previosly declared with MEMB(). + * + * \param ptr A pointer to the memory block that is to be deallocated. + * + * \return The new reference count for the memory block (should be 0 + * if successfully deallocated) or -1 if the pointer "ptr" did not + * point to a legal memory block. + */ +char memb_free(struct memb_blocks *m, void *ptr); + +/** @} */ +/** @} */ + +#endif /* __MEMB_H__ */ diff --git a/core/lib/mmem.c b/core/lib/mmem.c new file mode 100644 index 000000000..067b4f0b3 --- /dev/null +++ b/core/lib/mmem.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: mmem.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** + * \addtogroup mmem + * @{ + */ + +/** + * \file + * Implementation of the managed memory allocator + * \author + * Adam Dunkels + * + */ + + +#include "mmem.h" +#include "list.h" + +#include + +#define MMEM_SIZE 4096 + +LIST(mmemlist); +unsigned int avail_memory; +static char memory[MMEM_SIZE]; + +/*---------------------------------------------------------------------------*/ +/** + * \brief Allocate a managed memory block + * \param m A pointer to a struct mmem. + * \param size The size of the requested memory block + * \return Non-zero if the memory could be allocated, zero if memory + * was not available. + * \author Adam Dunkels + * + * This function allocates a chunk of managed memory. The + * memory allocated with this function must be deallocated + * using the mmem_free() function. + * + * \note This function does NOT return a pointer to the + * allocated memory, but a pointer to a structure that + * contains information about the managed memory. The + * macro MMEM_PTR() is used to get a pointer to the + * allocated memory. + * + */ +int +mmem_alloc(struct mmem *m, unsigned int size) +{ + /* Check if we have enough memory left for this allocation. */ + if(avail_memory < size) { + return 0; + } + + /* We had enough memory so we add this memory block to the end of + the list of allocated memory blocks. */ + list_add(mmemlist, m); + + /* Set up the pointer so that it points to the first available byte + in the memory block. */ + m->ptr = &memory[MMEM_SIZE - avail_memory]; + + /* Remember the size of this memory block. */ + m->size = size; + + /* Decrease the amount of available memory. */ + avail_memory -= size; + + /* Return non-zero to indicate that we were able to allocate + memory. */ + return 1; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Deallocate a managed memory block + * \param m A pointer to the managed memory block + * \author Adam Dunkels + * + * This function deallocates a managed memory block that + * previously has been allocated with mmem_alloc(). + * + */ +void +mmem_free(struct mmem *m) +{ + struct mmem *n; + + if(m->next != NULL) { + /* Compact the memory after the allocation that is to be removed + by moving it downwards. */ + memmove(m->ptr, m->next->ptr, + &memory[MMEM_SIZE - avail_memory] - (char *)m->next->ptr); + + /* Update all the memory pointers that points to memory that is + after the allocation that is to be removed. */ + for(n = m->next; n != NULL; n = n->next) { + n->ptr = (void *)((char *)n->ptr - m->size); + } + } + + avail_memory += m->size; + + /* Remove the memory block from the list. */ + list_remove(mmemlist, m); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Initialize the managed memory module + * \author Adam Dunkels + * + * This function initializes the managed memory module and + * should be called before any other function from the + * module. + * + */ +void +mmem_init(void) +{ + list_init(mmemlist); + avail_memory = MMEM_SIZE; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/core/lib/mmem.h b/core/lib/mmem.h new file mode 100644 index 000000000..3b427fb78 --- /dev/null +++ b/core/lib/mmem.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: mmem.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +/** + * \addtogroup mem + * @{ + */ + +/** + * \defgroup mmem Managed memory allocator + * + * The managed memory allocator is a fragmentation-free memory + * manager. It keeps the allocated memory free from fragmentation by + * compacting the memory when blocks are freed. A program that uses + * the managed memory module cannot be sure that allocated memory + * stays in place. Therefore, a level of indirection is used: access + * to allocated memory must always be done using a special macro. + * + * \note This module has not been heavily tested. + * @{ + */ + +/** + * \file + * Header file for the managed memory allocator + * \author + * Adam Dunkels + * + */ + +#ifndef __MMEM_H__ +#define __MMEM_H__ + +/*---------------------------------------------------------------------------*/ +/** + * \brief Get a pointer to the managed memory + * \param m A pointer to the struct mmem + * \return A pointer to the memory block, or NULL if memory could + * not be allcated. + * \author Adam Dunkels + * + * This macro is used to get a pointer to a memory block + * allocated with mmem_alloc(). + * + * \hideinitializer + */ +#define MMEM_PTR(m) (struct mmem *)(m)->ptr + +struct mmem { + struct mmem *next; + unsigned int size; + void *ptr; +}; + +/* XXX: tagga minne med "interrupt usage", vilke gör att man är + speciellt varsam under free(). */ + +int mmem_alloc(struct mmem *m, unsigned int size); +void mmem_free(struct mmem *); +void mmem_init(void); + +#endif /* __MMEM_H__ */ + +/** @} */ +/** @} */ diff --git a/core/lib/petsciiconv.c b/core/lib/petsciiconv.c new file mode 100644 index 000000000..58b598914 --- /dev/null +++ b/core/lib/petsciiconv.c @@ -0,0 +1,116 @@ +/* + * 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: petsciiconv.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* +static unsigned char petscii2ascii[128] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x14,0x09,0x0d,0x11,0x93,0x0a,0x0e,0x0f, + 0x10,0x0b,0x12,0x13,0x08,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67, + 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77, + 0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x7e,0x5f, + 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, + 0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7, + 0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0x7e,0xdf +}; +*/ + +static unsigned char ascii2petscii[128] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x14,0x09,0x0d,0x11,0x93,0x0a,0x0e,0x0f, + 0x10,0x0b,0x12,0x13,0x08,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27, + 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x40,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, + 0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf, + 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7, + 0xd8,0xd9,0xda,0x5b,0x5c,0x5d,0x5e,0x5f, + 0xc0,0x41,0x42,0x43,0x44,0x45,0x46,0x47, + 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, + 0x58,0x59,0x5a,0xdb,0xdd,0xdd,0x5e,0xdf, +}; + +static unsigned int i; +static unsigned char *ptr; + +/*-----------------------------------------------------------------------------------*/ +void +petsciiconv_toascii(char *buf, unsigned int len) +{ + static char c; + + ptr = buf; + for(i = len; i > 0; --i) { + c = *ptr; + if(c == 0x0a) { + c = 0x0d; + } else if(c == 0x0d) { + c = 0x0a; + } + switch (c & 0xe0) { + case 0x40: + case 0x60: + c ^= 0x20; + break; + case 0xc0: + c ^= 0x80; + break; + } + *ptr = c & 0x7f; + ++ptr; + } +} +/*-----------------------------------------------------------------------------------*/ +void +petsciiconv_topetscii(char *buf, unsigned int len) +{ + ptr = buf; + for(i = len; i > 0; --i) { + *ptr = ascii2petscii[*ptr & 0x7f]; + ++ptr; + } +} +/*-----------------------------------------------------------------------------------*/ diff --git a/core/lib/petsciiconv.h b/core/lib/petsciiconv.h new file mode 100644 index 000000000..3b15fc2e9 --- /dev/null +++ b/core/lib/petsciiconv.h @@ -0,0 +1,79 @@ +/** + * \file + * PETSCII/ASCII conversion functions. + * \author Adam Dunkels + * + * The Commodore based Contiki targets all have a special character + * encoding called PETSCII which differs from the ASCII encoding that + * normally is used for representing characters. + * + * \note For targets that do not use PETSCII encoding the C compiler + * define WITH_ASCII should be used to avoid the PETSCII converting + * functions. + * + */ + +/* + * 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: petsciiconv.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ +#ifndef __PETSCIICONV_H__ +#define __PETSCIICONV_H__ + +#ifdef WITH_PETSCII + +#include "contiki-conf.h" + +/** + * Convert a text buffer from PETSCII to ASCII. + * + * \param buf A pointer to the buffer which is to be converted. + * \param len The length of the buffer to be converted. + */ +void petsciiconv_toascii(char *buf, unsigned int len); +/** + * Convert a text buffer from ASCII to PETSCII. + * + * \param buf A pointer to the buffer which is to be converted. + * \param len The length of the buffer to be converted. + */ +void petsciiconv_topetscii(char *buf, unsigned int len); + +#else /* WITH_PETSCII */ + +#define petsciiconv_toascii(buf, len) +#define petsciiconv_topetscii(buf, len) + +#endif /* WITH_PETSCII */ + +#endif /* __PETSCIICONV_H__ */ diff --git a/core/lib/rand.c b/core/lib/rand.c new file mode 100644 index 000000000..d073c19f8 --- /dev/null +++ b/core/lib/rand.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: rand.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#include "rand.h" + +/* + * Minimal standard random number generator. + * + * Simple crappy ANSI C compatible random number generator that is + * good enough for us! + * + * Park, S.K. and K.W. Miller, 1988; + * Random Number Generators: Good Ones are Hard to Find, + * Comm. of the ACM, V. 31. No. 10, pp 1192-1201 + */ + +unsigned long rand_state = 123459876ul; + +int +rand() +{ + rand_state = (16807*rand_state) % 2147483647ul; + return rand_state & RAND_MAX; +} + +void +srand(unsigned int seed) +{ + rand_state = seed; +} diff --git a/core/lib/rand.h b/core/lib/rand.h new file mode 100644 index 000000000..189efbe8c --- /dev/null +++ b/core/lib/rand.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: rand.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +/* -*- C -*- */ +/* @(#)$Id: rand.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ */ + +#ifndef RAND_H +#define RAND_H + +#undef RAND_MAX +#define RAND_MAX 0x7fff + +/* + * Minimal standard random number generator. + * + * Simple crappy ANSI C compatible random number generator that is + * good enough for us! + * + * Park, S.K. and K.W. Miller, 1988; + * Random Number Generators: Good Ones are Hard to Find, + * Comm. of the ACM, V. 31. No. 10, pp 1192-1201 + */ + +extern unsigned long rand_state; + +int rand(void); + +void srand(unsigned int); + +#endif /* RAND_H */ diff --git a/core/lib/random.c b/core/lib/random.c new file mode 100644 index 000000000..489b970d6 --- /dev/null +++ b/core/lib/random.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: random.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/* + From: + + D. Seetharam and S. Rhee, ``An Efficient Random Number Generator + for Low-Power Sensor Networks'' First IEEE Workshop on Embedded + Networked Sensors (EmNets-I), November 2004. + + http://www.dseetharam.org/papers/emnets.pdf +*/ + +#include "lib/random.h" +#include "sys/clock.h" + +static clock_time_t time; + +static unsigned short key; + +void +random_init(unsigned short seed) +{ + key = seed; +} + +unsigned short +random_rand(void) +{ + unsigned short rv, tv; + + rv = tv = 0; + + tv = time + clock_time(); + rv = tv ^ key; + + key = ~tv + 4711; + tv = ~rv; + time = tv; + + return rv; +} diff --git a/core/lib/random.h b/core/lib/random.h new file mode 100644 index 000000000..c2f89ebdd --- /dev/null +++ b/core/lib/random.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: random.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __RANDOM_H__ +#define __RANDOM_H__ + +/* + * Initialize the pseudo-random generator. + * + */ +void random_init(unsigned short seed); + +/* + * Calculate a pseudo random number between 0 and 65535. + * + * \return A pseudo-random number between 0 and 65535. + */ +unsigned short random_rand(void); + +#define RANDOM_MAX 65535U + +#endif /* __RANDOM_H__ */ diff --git a/core/lib/realloc.c b/core/lib/realloc.c new file mode 100644 index 000000000..53f7938bc --- /dev/null +++ b/core/lib/realloc.c @@ -0,0 +1,160 @@ +/* Copyright (c) 2004 Joerg Wunsch + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * 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. + + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. +*/ +/* $Id: realloc.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ */ + +#include +#include +#include + +#ifdef MALLOC_TEST +#include "malloc.h" +#else +#include "contiki.h" +#include "lib/malloc.h" +#endif /* !MALLOC_TEST */ + +void * +realloc(void *ptr, size_t len) +{ + struct __freelist *fp1, *fp2, *fp3, *ofp3; + char *cp, *cp1; + void *memp; + size_t s, incr; + + /* Trivial case, required by C standard. */ + if (ptr == 0) + return malloc(len); + + if (len < 0) + return 0; + + len = (len + MALLOC_ROUNDUP) & ~MALLOC_ROUNDUP; + + cp1 = (char *)ptr; + cp1 -= sizeof(struct __freelist); + fp1 = (struct __freelist *)cp1; + + cp = (char *)ptr + len; /* new next pointer */ + if (cp < cp1) + /* Pointer wrapped across top of RAM, fail. */ + return 0; + fp2 = (struct __freelist *)cp; + + /* + * See whether we are growing or shrinking. When shrinking, + * we split off a chunk for the released portion, and call + * free() on it. Therefore, we can only shrink if the new + * size is at least sizeof(struct __freelist) smaller than the + * previous size. + */ + if (len <= fp1->sz) { + /* The first test catches a possible unsigned int + * rollover condition. */ + if (fp1->sz <= sizeof(struct __freelist) || + len > fp1->sz - sizeof(struct __freelist)) + return ptr; + fp2->sz = fp1->sz - len - sizeof(struct __freelist); + fp1->sz = len; + free(&fp2[1]); + return ptr; + } + + /* + * If we get here, we are growing. First, see whether there + * is space in the free list on top of our current chunk. + */ + incr = len - fp1->sz - sizeof(struct __freelist); + cp = (char *)ptr + fp1->sz; + fp2 = (struct __freelist *)cp; + for (s = 0, ofp3 = 0, fp3 = __flp; + fp3; + ofp3 = fp3, fp3 = fp3->nx) { + if (fp3 == fp2 && fp3->sz >= incr) { + /* found something that fits */ + if (incr <= fp3->sz && + incr > fp3->sz - sizeof(struct __freelist)) { + /* it just fits, so use it entirely */ + fp1->sz += fp3->sz + sizeof(struct __freelist); + if (ofp3) + ofp3->nx = fp3->nx; + else + __flp = fp3->nx; + return ptr; + } + /* split off a new freelist entry */ + cp = (char *)ptr + len; + fp2 = (struct __freelist *)cp; + fp2->nx = fp3->nx; + fp2->sz = fp3->sz - incr - sizeof(struct __freelist); + if (ofp3) + ofp3->nx = fp2; + else + __flp = fp2; + fp1->sz = len; + return ptr; + } + /* + * Find the largest chunk on the freelist while + * walking it. + */ + if (fp3->sz > s) + s = fp3->sz; + } + /* + * If we are the topmost chunk in memory, and there was no + * large enough chunk on the freelist that could be re-used + * (by a call to malloc() below), quickly extend the + * allocation area if possible, without need to copy the old + * data. + */ + if (__brkval == (char *)ptr + fp1->sz && len > s) { + cp1 = __malloc_heap_end; + cp = (char *)ptr + len; + if (cp < cp1) { + __brkval = cp; + fp1->sz = len; + return ptr; + } + /* If that failed, we are out of luck. */ + return 0; + } + + /* + * Call malloc() for a new chunk, then copy over the data, and + * release the old region. + */ + if ((memp = malloc(len)) == 0) + return 0; + memcpy(memp, ptr, fp1->sz); + free(ptr); + return memp; +} + diff --git a/core/lib/sensors.c b/core/lib/sensors.c new file mode 100644 index 000000000..20f754f03 --- /dev/null +++ b/core/lib/sensors.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: sensors.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +/* exeperimental code, will be renamed to sensors.c when done */ + + +#include + +#include "contiki.h" + +#include "lib/sensors.h" + +extern struct sensors_sensor *sensors[]; +extern unsigned char sensors_flags[]; +extern struct process *sensors_selecting_proc[]; + +#define FLAG_CHANGED 0x80 + +process_event_t sensors_event; + +static unsigned char num_sensors; + +PROCESS(sensors_process, "Sensors"); + +/*---------------------------------------------------------------------------*/ +static int +get_sensor_index(const struct sensors_sensor *s) +{ + int i; + for(i = 0; i < num_sensors; ++i) { + if(sensors[i] == s) { + return i; + } + } + return i; +} +/*---------------------------------------------------------------------------*/ +void +sensors_add_irq(const struct sensors_sensor *s, unsigned char irq) +{ + sensors_flags[get_sensor_index(s)] |= irq; +} +/*---------------------------------------------------------------------------*/ +void +sensors_remove_irq(const struct sensors_sensor *s, unsigned char irq) +{ + sensors_flags[get_sensor_index(s)] &= ~irq; +} +/*---------------------------------------------------------------------------*/ +int +sensors_handle_irq(unsigned char irq_flag) +{ + int i, w; + + w = 0; + for(i = 0; i < num_sensors; ++i) { + if(sensors_flags[i] & irq_flag) { + w += sensors[i]->irq(); + } + } + + return w; +} +/*---------------------------------------------------------------------------*/ +struct sensors_sensor * +sensors_first(void) +{ + return sensors[0]; +} +/*---------------------------------------------------------------------------*/ +struct sensors_sensor * +sensors_next(const struct sensors_sensor *s) +{ + return sensors[get_sensor_index(s) + 1]; +} +/*---------------------------------------------------------------------------*/ +void +sensors_changed(const struct sensors_sensor *s) +{ + sensors_flags[get_sensor_index(s)] |= FLAG_CHANGED; + process_poll(&sensors_process); +} +/*---------------------------------------------------------------------------*/ +struct sensors_sensor * +sensors_find(char *prefix) +{ + int i; + unsigned short len; + + /* Search through all processes and search for the specified process + name. */ + len = strlen(prefix); + + for(i = 0; i < num_sensors; ++i) { + if(strncmp(prefix, sensors[i]->type, len) == 0) { + return sensors[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +#define SELCOLL ((struct process *)0x1) + +void +sensors_select(const struct sensors_sensor *s, struct process *p) +{ + int i = get_sensor_index(s); + + if(sensors_selecting_proc[i] == NULL) { + sensors_selecting_proc[i] = p; + } else if(sensors_selecting_proc[i] == p) { + /* If the selecting process is already registered we do nothing */ + } else { + /* Collision, revert to broadcast! */ + sensors_selecting_proc[i] = SELCOLL; + } +} +/*---------------------------------------------------------------------------*/ +void +sensors_unselect(const struct sensors_sensor *s, const struct process *p) +{ + int i = get_sensor_index(s); + + if(sensors_selecting_proc[i] == p) { + sensors_selecting_proc[i] = NULL; + } else { + /* We collided and must continue to use broadcast! */ + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sensors_process, ev, data) +{ + int i; + + PROCESS_BEGIN(); + + for(i = 0; sensors[i] != NULL; ++i) { + sensors_flags[i] = 0; + sensors[i]->init(); + } + num_sensors = i; + + sensors_event = process_alloc_event(); + + irq_init(); + + while(1) { + + PROCESS_WAIT_EVENT(); + + for(i = 0; i < num_sensors; ++i) { + if(sensors_flags[i] & FLAG_CHANGED) { + if(sensors_selecting_proc[i] == SELCOLL + || sensors_selecting_proc[i] == NULL) + process_post(PROCESS_BROADCAST, sensors_event, sensors[i]); + else + process_post(sensors_selecting_proc[i], sensors_event, sensors[i]); + sensors_flags[i] &= ~FLAG_CHANGED; + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/lib/sensors.h b/core/lib/sensors.h new file mode 100644 index 000000000..7722ed8d7 --- /dev/null +++ b/core/lib/sensors.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: sensors.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#ifndef __SENSORS_H__ +#define __SENSORS_H__ + +#include "contiki.h" + +#define SENSORS_SENSOR(name, type, init, irq, activate, deactivate, \ + active, value, configure, status) \ +const struct sensors_sensor name = { type , \ + init, irq, activate, deactivate, \ + active, value, configure, status } + +#define SENSORS_NUM (sizeof(sensors) / sizeof(struct sensors_sensor *)) + +#define SENSORS(...) \ +const struct sensors_sensor *sensors[] = {__VA_ARGS__, NULL}; \ +unsigned char sensors_flags[SENSORS_NUM]; \ +struct process *sensors_selecting_proc[SENSORS_NUM]; + +struct sensors_sensor { + char * type; + void (* init) (void); + int (* irq) (void); + void (* activate) (void); + void (* deactivate)(void); + int (* active) (void); + unsigned int (* value) (int type); + int (* configure) (int type, void *parameters); + void * (* status) (int type); +}; + +struct sensors_sensor *sensors_find(char *type); +struct sensors_sensor *sensors_next(const struct sensors_sensor *s); +struct sensors_sensor *sensors_first(void); + +void sensors_changed(const struct sensors_sensor *s); + + +void sensors_add_irq(const struct sensors_sensor *s, unsigned char irq); +void sensors_remove_irq(const struct sensors_sensor *s, unsigned char irq); + +int sensors_handle_irq(unsigned char irq_flag); + +void sensors_select(const struct sensors_sensor *s, struct process *p); +void sensors_unselect(const struct sensors_sensor *s, const struct process *p); + +extern process_event_t sensors_event; + +PROCESS_NAME(sensors_process); + +void irq_init(void); + +#endif /* __SENSORS_H__ */ diff --git a/core/lib/strncasecmp.c b/core/lib/strncasecmp.c new file mode 100644 index 000000000..4455f3278 --- /dev/null +++ b/core/lib/strncasecmp.c @@ -0,0 +1,70 @@ +/* + * 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: strncasecmp.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* This file contains a naive and non-stanrdards compliant + implementation of strncasecmp() for systems that don't implement + the function. It works with Contiki, but should most probably not + be used anywhere else. + + It copies the n first bytes two strings into two buffers and + compares them with strcasecmp. +*/ + +#define MAX_STRLEN 40 + + +int strncmp(const char *s1, const char *s2, int len); + +/*static char buf1[MAX_STRLEN], + buf2[MAX_STRLEN];*/ +/*-----------------------------------------------------------------------------------*/ +unsigned char +strncasecmp(const char *s1, const char *s2, unsigned char n) +{ + unsigned char len; + + return strncmp(s1, s2, n); + + /* len = MAX_STRLEN; + if(n < MAX_STRLEN) { + len = n; + } + strncpy(buf1, s1, len); + buf1[MAX_STRLEN - 1] = 0; + strncpy(buf2, s2, len); + buf2[MAX_STRLEN - 1] = 0; + return strcasecmp(buf1, buf2);*/ +} +/*-----------------------------------------------------------------------------------*/ diff --git a/core/loader/dlloader.c b/core/loader/dlloader.c new file mode 100644 index 000000000..7c325581a --- /dev/null +++ b/core/loader/dlloader.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: dlloader.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#include +#include +#include + +#include "contiki.h" + +/*---------------------------------------------------------------------------*/ +int +dlloader_load(char *path, char *arg) +{ + void *handle; + struct process **p; + + /* Load and link the program. */ + handle = dlopen(path, RTLD_NOW); + + printf("Loading '%s'\n", path); + + if(handle == NULL) { + printf("dlloader_load: loading failed: %s\n", dlerror()); + return LOADER_ERR_FMT; + } + + /* Find the main process of the loaded program. */ + p = dlsym(handle, "process_load"); + if(p == NULL) { + printf("dlloader_load: could not find process startpoint 'process_load'\n"); + return LOADER_ERR_FMT; + } + + /* Start the process. */ + printf("Starting '%s'\n", (*p)->name); + process_start(*p, arg); + + return LOADER_OK; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/loader/dlloader.h b/core/loader/dlloader.h new file mode 100644 index 000000000..d4341db90 --- /dev/null +++ b/core/loader/dlloader.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: dlloader.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __DLLOADER_H__ +#define __DLLOADER_H__ + +int dlloader_load(char *name, char *arg); + +#endif /* __SOLOADR_H__ */ diff --git a/core/loader/elfloader-arch.h b/core/loader/elfloader-arch.h new file mode 100644 index 000000000..90c5260c2 --- /dev/null +++ b/core/loader/elfloader-arch.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader-arch.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +/** + * \addtogroup elfloader + * @{ + */ + +/** + * \defgroup elfloaderarch Architecture specific functionality for the ELF loader. + * + * The architecture specific functionality for the Contiki ELF loader + * has to be implemented for each processor type Contiki runs on. + * + * Since the ELF format is slightly different for different processor + * types, the Contiki ELF loader is divided into two parts: the + * generic ELF loader module (\ref elfloader) and the architecture + * specific part (this module). The architecture specific part deals + * with memory allocation, code and data relocation, and writing the + * relocated ELF code into program memory. + * + * To port the Contiki ELF loader to a new processor type, this module + * has to be implemented for the new processor type. + * + * @{ + */ + +/** + * \file + * Header file for the architecture specific parts of the Contiki ELF loader. + * + * \author + * Adam Dunkels + * + */ + +#ifndef __ELFLOADER_ARCH_H__ +#define __ELFLOADER_ARCH_H__ + +#include "elfloader-tmp.h" + +/** + * \brief Allocate RAM for a new module. + * \param size The size of the requested memory. + * \return A pointer to the allocated RAM + * + * This function is called from the Contiki ELF loader to + * allocate RAM for the module to be loaded into. + * + * \bug The Contiki ELF loader currently does not contain a + * mechanism for deallocating the memory allocated with + * this function. + */ +void *elfloader_arch_allocate_ram(int size); + +/** + * \brief Allocate program memory for a new module. + * \param size The size of the requested memory. + * \return A pointer to the allocated program memory + * + * This function is called from the Contiki ELF loader to + * allocate program memory (typically ROM) for the module + * to be loaded into. + * + * \bug The Contiki ELF loader currently does not contain a + * mechanism for deallocating the memory allocated with + * this function. + */ +void *elfloader_arch_allocate_rom(int size); + +/** + * \brief Perform a relocation. + * \param fd The file descriptor for the ELF file. + * \param sectionoffset The file offset at which the relocation can be found. + * \param rela A pointer to an ELF32 rela structure (struct elf32_rela). + * \param addr The relocated address. + * + * This function is called from the Contiki ELF loader to + * perform a relocation on a piece of code or data. The + * relocated address is calculated by the Contiki ELF + * loader, based on information in the ELF file, and it is + * the responsibility of this function to patch the + * executable code. The Contiki ELF loader passes a + * pointer to an ELF32 rela structure (struct elf32_rela) + * that contains information about how to patch the + * code. This information is different from processor to + * processor. + */ +void elfloader_arch_relocate(int fd, unsigned int sectionoffset, + struct elf32_rela *rela, char *addr); + +/** + * \brief Write the program code (text segment) into program memory. + * \param fd The file descriptor for the ELF file. + * \param size The size of the text segment. + * \param mem A pointer to the where the text segment should be flashed + * + * This function is called from the Contiki ELF loader to + * write the program code (text segment) of a loaded + * module into memory. The function is called when all + * relocations have been performed. + */ +void elfloader_arch_write_text(int fd, unsigned int size, char *mem); + +#endif /* __ELFLOADER_ARCH_H__ */ + +/** @} */ +/** @} */ diff --git a/core/loader/elfloader-avr.c b/core/loader/elfloader-avr.c new file mode 100644 index 000000000..ae6c6f824 --- /dev/null +++ b/core/loader/elfloader-avr.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader-avr.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#include "elfloader-arch.h" + +/*#include "dev/flash.h"*/ + +#define R_AVR_NONE 0 +#define R_AVR_32 1 +#define R_AVR_7_PCREL 2 +#define R_AVR_13_PCREL 3 +#define R_AVR_16 4 +#define R_AVR_16_PM 5 +#define R_AVR_LO8_LDI 6 +#define R_AVR_HI8_LDI 7 +#define R_AVR_HH8_LDI 8 +#define R_AVR_LO8_LDI_NEG 9 +#define R_AVR_HI8_LDI_NEG 10 +#define R_AVR_HH8_LDI_NEG 11 +#define R_AVR_LO8_LDI_PM 12 +#define R_AVR_HI8_LDI_PM 13 +#define R_AVR_HH8_LDI_PM 14 +#define R_AVR_LO8_LDI_PM_NEG 15 +#define R_AVR_HI8_LDI_PM_NEG 16 +#define R_AVR_HH8_LDI_PM_NEG 17 +#define R_AVR_CALL 18 + +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +static char datamemory[ELFLOADER_DATAMEMORY_SIZE]; +static const char textmemory[ELFLOADER_TEXTMEMORY_SIZE]; +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_ram(int size) +{ + return datamemory; +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_rom(int size) +{ + /* Return an 512-byte aligned pointer. */ + return (char *) + ((unsigned long)&textmemory[0] & 0xfffffe00) + + (((unsigned long)&textmemory[0] & 0x1ff) == 0? 0: 0x200); +} +/*---------------------------------------------------------------------------*/ +#define READSIZE 32 +void +elfloader_arch_write_text(int fd, unsigned int size, char *mem) +{ +#if 0 + int i; + unsigned int ptr; + unsigned short *flashptr; + + flash_setup(); + + flashptr = (unsigned short *)elfloader_arch_textmemory; + + for(ptr = 0; ptr < size; ptr += READSIZE) { + + /* Read data from file into RAM. */ + cfs_read(fd, (unsigned char *)elfloader_arch_datamemory, READSIZE); + + /* Clear flash page on 512 byte boundary. */ + if((((unsigned short)flashptr) & 0x01ff) == 0) { + flash_clear(flashptr); + } + + /* Burn data from RAM into flash ROM. Flash is burned one 16-bit + word at a time, so we need to be careful when incrementing + pointers. The flashptr is already a short pointer, so + incrementing it by one will actually increment the address by + two. */ + for(i = 0; i < READSIZE / 2; ++i) { + flash_write(flashptr, ((unsigned short *)elfloader_arch_datamemory)[i]); + ++flashptr; + } + } + + flash_done(); +#endif +} +/*---------------------------------------------------------------------------*/ +static void +write_ldi(int fd, unsigned char *instr, unsigned char byte) +{ + instr[0] = (instr[0] & 0xf0) | (byte & 0x0f); + instr[1] = (instr[0] & 0xf0) | (byte >> 4); + cfs_write(fd, instr, 2); +} +/*---------------------------------------------------------------------------*/ +void +elfloader_arch_relocate(int fd, unsigned int sectionoffset, + struct elf32_rela *rela, char *addr) +{ + unsigned int type; + unsigned char instr[4]; + + cfs_seek(fd, sectionoffset); + cfs_read(fd, instr, 4); + cfs_seek(fd, sectionoffset); + + addr += rela->r_addend; + + type = ELF32_R_TYPE(rela->r_info); + + printf("elfloader_arch_relocate: type %d\n", type); + + switch(type) { + case R_AVR_NONE: + case R_AVR_32: + case R_AVR_7_PCREL: /* >> 1 */ + case R_AVR_13_PCREL: /* >> 1 */ + printf("elfloader-avr.c: unsupported relocation type %d\n", type); + break; + + case R_AVR_16: + cfs_write(fd, (char *)addr, 2); + break; + case R_AVR_16_PM: + addr = (char *)((unsigned long)addr >> 1); + cfs_write(fd, (char *)addr, 2); + break; + + case R_AVR_LO8_LDI: + write_ldi(fd, instr, (unsigned long)addr); + break; + case R_AVR_HI8_LDI: + write_ldi(fd, instr, (unsigned long)addr >> 8); + break; + case R_AVR_HH8_LDI: + write_ldi(fd, instr, (unsigned long)addr >> 16); + break; + + case R_AVR_LO8_LDI_NEG: + addr = (char *)(0 - (unsigned long)addr); + write_ldi(fd, instr, (unsigned long)addr); + break; + case R_AVR_HI8_LDI_NEG: + addr = (char *)(0 - (unsigned long)addr); + write_ldi(fd, instr, (unsigned long)addr >> 8); + break; + case R_AVR_HH8_LDI_NEG: + addr = (char *)(0 - (unsigned long)addr); + write_ldi(fd, instr, (unsigned long)addr >> 16); + break; + + case R_AVR_LO8_LDI_PM: + write_ldi(fd, instr, (unsigned long)addr >> 1); + break; + case R_AVR_HI8_LDI_PM: + write_ldi(fd, instr, (unsigned long)addr >> 9); + break; + case R_AVR_HH8_LDI_PM: + write_ldi(fd, instr, (unsigned long)addr >> 17); + break; + + case R_AVR_LO8_LDI_PM_NEG: + addr = (char *)(0 - (unsigned long)addr); + write_ldi(fd, instr, (unsigned long)addr >> 1); + break; + case R_AVR_HI8_LDI_PM_NEG: + addr = (char *)(0 - (unsigned long)addr); + write_ldi(fd, instr, (unsigned long)addr >> 9); + break; + addr = (char *)(0 - (unsigned long)addr); + case R_AVR_HH8_LDI_PM_NEG: + write_ldi(fd, instr, (unsigned long)addr >> 17); + break; + + case R_AVR_CALL: + addr = (char *)((unsigned long)addr >> 1); + instr[3] = (unsigned long)addr >> 8; + instr[4] = (unsigned long)addr & 0xff; + printf("R_AVR_CALL:Writing 0x%02x 0x%02x 0x%02x 0x%02x\n", + instr[0], instr[1], instr[2], instr[3]); + cfs_write(fd, instr, 4); + break; + + } + +} +/*---------------------------------------------------------------------------*/ diff --git a/core/loader/elfloader-msp430.c b/core/loader/elfloader-msp430.c new file mode 100644 index 000000000..feebe5447 --- /dev/null +++ b/core/loader/elfloader-msp430.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader-msp430.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#include "elfloader-arch.h" + +#include "dev/flash.h" + +static char datamemory[ELFLOADER_DATAMEMORY_SIZE]; +static const char textmemory[ELFLOADER_TEXTMEMORY_SIZE] = {0}; +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_ram(int size) +{ + return datamemory; +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_rom(int size) +{ + /* Return an 512-byte aligned pointer. */ + return (char *) + ((unsigned long)&textmemory[0] & 0xfffffe00) + + (((unsigned long)&textmemory[0] & 0x1ff) == 0? 0: 0x200); +} +/*---------------------------------------------------------------------------*/ +#define READSIZE 32 +void +elfloader_arch_write_text(int fd, unsigned int size, char *mem) +{ + int i; + unsigned int ptr; + unsigned short *flashptr; + + flash_setup(); + + flashptr = (unsigned short *)mem; + + for(ptr = 0; ptr < size; ptr += READSIZE) { + + /* Read data from file into RAM. */ + cfs_read(fd, (unsigned char *)datamemory, READSIZE); + + /* Clear flash page on 512 byte boundary. */ + if((((unsigned short)flashptr) & 0x01ff) == 0) { + flash_clear(flashptr); + } + + /* Burn data from RAM into flash ROM. Flash is burned one 16-bit + word at a time, so we need to be careful when incrementing + pointers. The flashptr is already a short pointer, so + incrementing it by one will actually increment the address by + two. */ + for(i = 0; i < READSIZE / 2; ++i) { + flash_write(flashptr, ((unsigned short *)datamemory)[i]); + ++flashptr; + } + } + + flash_done(); +} +/*---------------------------------------------------------------------------*/ +void +elfloader_arch_relocate(int fd, unsigned int sectionoffset, + struct elf32_rela *rela, char *addr) +{ + addr += rela->r_addend; + + cfs_seek(fd, sectionoffset + rela->r_offset); + cfs_write(fd, (char *)&addr, 2); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/loader/elfloader-stub.c b/core/loader/elfloader-stub.c new file mode 100644 index 000000000..3b582ef1b --- /dev/null +++ b/core/loader/elfloader-stub.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader-stub.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#include "elfloader-arch.h" + +static char datamemory[ELFLOADER_DATAMEMORY_SIZE]; +static const char textmemory[ELFLOADER_TEXTMEMORY_SIZE] = {0}; +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_ram(int size) +{ + return (void *)datamemory; +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_rom(int size) +{ + return (void *)textmemory; +} +/*---------------------------------------------------------------------------*/ +void +elfloader_arch_write_text(int fd, unsigned int size, char *mem) +{ + printf("elfloader_arch_write_text: size %d, mem %p\n", size, mem); +} +/*---------------------------------------------------------------------------*/ +void +elfloader_arch_relocate(int fd, unsigned int sectionoffset, + struct elf32_rela *rela, char *addr) +{ + printf("elfloader_arch_relocate: sectionoffset 0x%04x, r_offset 0x%04x, r_info 0x%04x, r_addend 0x%04x, addr %p\n", sectionoffset, rela->r_offset, rela->r_info, rela->r_addend, addr); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/loader/elfloader-tmp.c b/core/loader/elfloader-tmp.c new file mode 100644 index 000000000..47fa195f2 --- /dev/null +++ b/core/loader/elfloader-tmp.c @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader-tmp.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include "contiki.h" + +#include "loader/elfloader-tmp.h" +#include "loader/elfloader-arch.h" + +#include "cfs/cfs.h" +#include "loader/symtab.h" + +#include +#include +#include + +#if 0 +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) do {} while (0) +#endif + +#define EI_NIDENT 16 + + +struct elf32_ehdr { + unsigned char e_ident[EI_NIDENT]; /* ident bytes */ + elf32_half e_type; /* file type */ + elf32_half e_machine; /* target machine */ + elf32_word e_version; /* file version */ + elf32_addr e_entry; /* start address */ + elf32_off e_phoff; /* phdr file offset */ + elf32_off e_shoff; /* shdr file offset */ + elf32_word e_flags; /* file flags */ + elf32_half e_ehsize; /* sizeof ehdr */ + elf32_half e_phentsize; /* sizeof phdr */ + elf32_half e_phnum; /* number phdrs */ + elf32_half e_shentsize; /* sizeof shdr */ + elf32_half e_shnum; /* number shdrs */ + elf32_half e_shstrndx; /* shdr string index */ +}; + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ + +struct elf32_shdr { + elf32_word sh_name; /* section name */ + elf32_word sh_type; /* SHT_... */ + elf32_word sh_flags; /* SHF_... */ + elf32_addr sh_addr; /* virtual address */ + elf32_off sh_offset; /* file offset */ + elf32_word sh_size; /* section size */ + elf32_word sh_link; /* misc info */ + elf32_word sh_info; /* misc info */ + elf32_word sh_addralign; /* memory alignment */ + elf32_word sh_entsize; /* entry size if table */ +}; + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +struct elf32_rel { + elf32_addr r_offset; /* Location to be relocated. */ + elf32_word r_info; /* Relocation type and symbol index. */ +}; + +struct elf32_sym { + elf32_word st_name; /* String table index of name. */ + elf32_addr st_value; /* Symbol value. */ + elf32_word st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + elf32_half st_shndx; /* Section index of symbol. */ +}; + +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +struct relevant_section { + unsigned char number; + unsigned int offset; + char *address; +}; + +char elfloader_unknown[30]; /* Name that caused link error. */ + +struct process **elfloader_autostart_processes; + +static struct relevant_section bss, data, text; + +const static unsigned char elf_magic_header[] = + {0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */ + 0x01, /* Only 32-bit objects. */ + 0x01, /* Only LSB data. */ + 0x01, /* Only ELF version 1. */ + }; + +/*---------------------------------------------------------------------------*/ +static void +seek_read(int fd, unsigned int offset, char *buf, int len) +{ + cfs_seek(fd, offset); + cfs_read(fd, buf, len); +} +/*---------------------------------------------------------------------------*/ +/* +static void +seek_write(int fd, unsigned int offset, char *buf, int len) +{ + cfs_seek(fd, offset); + cfs_write(fd, buf, len); +} +*/ +/*---------------------------------------------------------------------------*/ +static void * +find_local_symbol(int fd, const char *symbol, + unsigned int symtab, unsigned short symtabsize, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + struct relevant_section *sect; + + for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, symbol) == 0) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == text.number) { + sect = &text; + } else { + return NULL; + } + return &(sect->address[s.st_value]); + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static int +relocate_section(int fd, + unsigned int section, unsigned short size, + unsigned int sectionaddr, + unsigned int strs, + unsigned int strtab, + unsigned int symtab, unsigned short symtabsize) +{ + struct elf32_rela rela; + struct elf32_sym s; + unsigned int a; + char name[30]; + char *addr; + struct relevant_section *sect; + + for(a = section; a < section + size; a += sizeof(struct elf32_rela)) { + seek_read(fd, a, (char *)&rela, sizeof(rela)); + seek_read(fd, + symtab + sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info), + (char *)&s, sizeof(s)); + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + PRINTF("name: %s\n", name); + addr = (char *)symtab_lookup(name); + /* ADDED */ + if(addr == NULL) { + PRINTF("name not found in global: %s\n", name); + addr = find_local_symbol(fd, name, symtab, symtabsize, strtab); + PRINTF("found address %p\n", addr); + } + if(addr == NULL) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == text.number) { + sect = &text; + } else { + PRINTF("elfloader unknown name: '%30s'\n", name); + memcpy(elfloader_unknown, name, sizeof(elfloader_unknown)); + elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0; + return ELFLOADER_SYMBOL_NOT_FOUND; + } + addr = sect->address; + } + } else { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == text.number) { + sect = &text; + } else { + return ELFLOADER_SEGMENT_NOT_FOUND; + } + + addr = sect->address; + } + + elfloader_arch_relocate(fd, sectionaddr, &rela, addr); + + } + return ELFLOADER_OK; +} +/*---------------------------------------------------------------------------*/ +static void * +find_program_processes(int fd, + unsigned int symtab, unsigned short size, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + + for(a = symtab; a < symtab + size; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, "autostart_processes") == 0) { + return &data.address[s.st_value]; + } + } + } + return NULL; +/* return find_local_symbol(fd, "autostart_processes", symtab, size, strtab); */ +} +/*---------------------------------------------------------------------------*/ +void +elfloader_init(void) +{ + elfloader_autostart_processes = NULL; +} +/*---------------------------------------------------------------------------*/ +#if 0 +static void +print_chars(unsigned char *ptr, int num) +{ + int i; + for(i = 0; i < num; ++i) { + PRINTF("%d", ptr[i]); + if(i == num - 1) { + PRINTF("\n"); + } else { + PRINTF(", "); + } + } +} +#endif /* 0 */ +/*---------------------------------------------------------------------------*/ +int +elfloader_load(int fd) +{ + struct elf32_ehdr ehdr; + struct elf32_shdr shdr; + struct elf32_shdr strtable; + unsigned int strs; + unsigned int shdrptr; + unsigned int nameptr; + char name[12]; + + int i; + unsigned short shdrnum, shdrsize; + + unsigned short textoff = 0, textsize, textrelaoff = 0, textrelasize; + unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize; + unsigned short symtaboff = 0, symtabsize; + unsigned short strtaboff = 0, strtabsize; + unsigned short bsssize = 0; + + struct process **process; + int ret; + + elfloader_unknown[0] = 0; + + /* The ELF header is located at the start of the buffer. */ + seek_read(fd, 0, (char *)&ehdr, sizeof(ehdr)); + + /* print_chars(ehdr.e_ident, sizeof(elf_magic_header)); + print_chars(elf_magic_header, sizeof(elf_magic_header));*/ + /* Make sure that we have a correct and compatible ELF header. */ + if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { + PRINTF("ELF header problems\n"); + return ELFLOADER_BAD_ELF_HEADER; + } + + /* Grab the section header. */ + shdrptr = ehdr.e_shoff; + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* Get the size and number of entries of the section header. */ + shdrsize = ehdr.e_shentsize; + shdrnum = ehdr.e_shnum; + + /* The string table section: holds the names of the sections. */ + seek_read(fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx, + (char *)&strtable, sizeof(strtable)); + + /* Get a pointer to the actual table of strings. This table holds + the names of the sections, not the names of other symbols in the + file (these are in the sybtam section). */ + strs = strtable.sh_offset; + + /* Go through all sections and pick out the relevant ones. The + ".text" segment holds the actual code from the ELF file, the + ".data" segment contains initialized data, the ".bss" segment + holds the size of the unitialized data segment. The ".rela.text" + and ".rela.data" segments contains relocation information for the + contents of the ".text" and ".data" segments, respectively. The + ".symtab" segment contains the symbol table for this file. The + ".strtab" segment points to the actual string names used by the + symbol table. + + In addition to grabbing pointers to the relevant sections, we + also save the section number for resolving addresses in the + relocator code. + */ + + + /* Initialize the segment sizes to zero so that we can check if + their sections was found in the file or not. */ + textsize = textrelasize = datasize = datarelasize = + symtabsize = strtabsize = 0; + + bss.number = data.number = text.number = 0; + + shdrptr = ehdr.e_shoff; + for(i = 0; i < shdrnum; ++i) { + + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* The name of the section is contained in the strings table. */ + nameptr = strs + shdr.sh_name; + seek_read(fd, nameptr, name, sizeof(name)); + + /* Match the name of the section with a predefined set of names + (.text, .data, .bss, .rela.text, .rela.data, .symtab, and + .strtab). */ + + if(strncmp(name, ".text", 5) == 0) { + textoff = shdr.sh_offset; + textsize = shdr.sh_size; + text.number = i; + text.offset = textoff; + } else if(strncmp(name, ".rela.text", 10) == 0) { + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".data", 5) == 0) { + dataoff = shdr.sh_offset; + datasize = shdr.sh_size; + data.number = i; + data.offset = dataoff; + } else if(strncmp(name, ".rela.data", 10) == 0) { + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".symtab", 7) == 0) { + symtaboff = shdr.sh_offset; + symtabsize = shdr.sh_size; + } else if(strncmp(name, ".strtab", 7) == 0) { + strtaboff = shdr.sh_offset; + strtabsize = shdr.sh_size; + } else if(strncmp(name, ".bss", 4) == 0) { + bsssize = shdr.sh_size; + bss.number = i; + bss.offset = 0; + } + + /* Move on to the next section header. */ + shdrptr += shdrsize; + } + + if(symtabsize == 0) { + return ELFLOADER_NO_SYMTAB; + } + if(strtabsize == 0) { + return ELFLOADER_NO_STRTAB; + } + if(textsize == 0) { + return ELFLOADER_NO_TEXT; + } + + bss.address = (char *)elfloader_arch_allocate_ram(bsssize + datasize); + data.address = (char *)bss.address + bsssize; + text.address = (char *)elfloader_arch_allocate_rom(textsize); + + + /* If we have text segment relocations, we process them. */ + PRINTF("elfloader: relocate text\n"); + if(textrelasize > 0) { + ret = relocate_section(fd, + textrelaoff, textrelasize, + textoff, + strs, + strtaboff, + symtaboff, symtabsize); + if(ret != ELFLOADER_OK) { + return ret; + } + } + + /* If we have any data segment relocations, we process them too. */ + PRINTF("elfloader: relocate data\n"); + if(datarelasize > 0) { + ret = relocate_section(fd, + datarelaoff, datarelasize, + dataoff, + strs, + strtaboff, + symtaboff, symtabsize); + if(ret != ELFLOADER_OK) { + PRINTF("elfloader: data failed\n"); + return ret; + } + } + + /* Write text segment into flash and data segment into RAM. */ + cfs_seek(fd, textoff); + elfloader_arch_write_text(fd, textsize, text.address); + + memset(bss.address, 0, bsssize); + seek_read(fd, dataoff, data.address, datasize); + + PRINTF("elfloader: autostart search\n"); + process = find_local_symbol(fd, "autostart_processes", symtaboff, symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: autostart found\n"); + elfloader_autostart_processes = process; + return ELFLOADER_OK; + } else { + PRINTF("elfloader: no autostart\n"); + process = find_program_processes(fd, symtaboff, symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: FOUND PRG\n"); + } + return ELFLOADER_NO_STARTPOINT; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/loader/elfloader-tmp.h b/core/loader/elfloader-tmp.h new file mode 100644 index 000000000..f1e7a676a --- /dev/null +++ b/core/loader/elfloader-tmp.h @@ -0,0 +1,170 @@ +/** + * \addtogroup loader + * @{ + */ + +/** + * \defgroup elfloader ELF object code loader + * + * The Contiki ELF loader is able to load and relocate ELF object + * files. + * + * @{ + */ + +/** + * \file + * Header file for the Contiki ELF loader. + * \author + * Adam Dunkels + * + */ + +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader-tmp.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __ELFLOADER_H__ +#define __ELFLOADER_H__ + +#include "cfs/cfs.h" + +/** + * Return value from elfloader_load() indicating that loading worked. + */ +#define ELFLOADER_OK 0 +/** + * Return value from elfloader_load() indicating that the ELF file had + * a bad header. + */ +#define ELFLOADER_BAD_ELF_HEADER 1 +/** + * Return value from elfloader_load() indicating that no symbol table + * could be find in the ELF file. + */ +#define ELFLOADER_NO_SYMTAB 2 +/** + * Return value from elfloader_load() indicating that no string table + * could be find in the ELF file. + */ +#define ELFLOADER_NO_STRTAB 3 +/** + * Return value from elfloader_load() indicating that the size of the + * .text segment was zero. + */ +#define ELFLOADER_NO_TEXT 4 +/** + * Return value from elfloader_load() indicating that a symbol + * specific symbol could not be found. + * + * If this value is returned from elfloader_load(), the symbol has + * been copied into the elfloader_unknown[] array. + */ +#define ELFLOADER_SYMBOL_NOT_FOUND 5 +/** + * Return value from elfloader_load() indicating that one of the + * required segments (.data, .bss, or .text) could not be found. + */ +#define ELFLOADER_SEGMENT_NOT_FOUND 6 +/** + * Return value from elfloader_load() indicating that no starting + * point could be found in the loaded module. + */ +#define ELFLOADER_NO_STARTPOINT 7 + +/** + * elfloader initialization function. + * + * This function should be called at boot up to initilize the elfloader. + */ +void elfloader_init(void); + +/** + * \brief Load and relocate an ELF file. + * \param fd An open file descriptor. + * \return ELFLOADER_OK if loading and relocation worked. + * Otherwise an error value. + * + * This function loads and relocates an ELF file. The ELF + * file must have been opened with cfs_open() prior to + * calling this function. + * + * If the function is able to load the ELF file, a pointer + * to the process structure in the model is stored in the + * elfloader_loaded_process variable. + * + * \note This function modifies the ELF file opened with cfs_open()! + * If the contents of the file is required to be intact, + * the file must be backed up first. + * + */ +int elfloader_load(int fd); + +/** + * A pointer to the processes loaded with elfloader_load(). + */ +extern struct process **elfloader_autostart_processes; + +/** + * If elfloader_load() could not find a specific symbol, it is copied + * into this array. + */ +extern char elfloader_unknown[30]; + +#ifdef ELFLOADER_CONF_DATAMEMORY_SIZE +#define ELFLOADER_DATAMEMORY_SIZE ELFLOADER_CONF_DATAMEMORY_SIZE +#else +#define ELFLOADER_DATAMEMORY_SIZE 0x100 +#endif + +#ifdef ELFLOADER_CONF_TEXTMEMORY_SIZE +#define ELFLOADER_TEXTMEMORY_SIZE ELFLOADER_CONF_TEXTMEMORY_SIZE +#else +#define ELFLOADER_TEXTMEMORY_SIZE 0x100 +#endif + +typedef unsigned long elf32_word; +typedef signed long elf32_sword; +typedef unsigned short elf32_half; +typedef unsigned long elf32_off; +typedef unsigned long elf32_addr; + +struct elf32_rela { + elf32_addr r_offset; /* Location to be relocated. */ + elf32_word r_info; /* Relocation type and symbol index. */ + elf32_sword r_addend; /* Addend. */ +}; + + +#endif /* __ELFLOADER_H__ */ + +/** @} */ +/** @} */ diff --git a/core/loader/elfloader.c b/core/loader/elfloader.c new file mode 100644 index 000000000..78f1307a9 --- /dev/null +++ b/core/loader/elfloader.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include +#include +#include + +#include + +#include "contiki.h" + +#include "loader/elfloader.h" +#include "loader/symtab.h" + +#include "lib/malloc.h" +#include "dev/rom.h" +#include "dev/xmem.h" + +#if 0 +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) do {} while (0) +#endif + +#define IMAX(a, b) (((a) > (b)) ? (a) : (b)) + +static char *datamemory; + +#define TEXTADDRESS \ + (((uintptr_t)&_etext + (uintptr_t)&_edata - (uintptr_t)&__data_start \ + + ROM_ERASE_UNIT_SIZE) & ~(ROM_ERASE_UNIT_SIZE - 1)) + +#define EI_NIDENT 16 + +typedef unsigned long elf32_word; +typedef signed long elf32_sword; +typedef unsigned short elf32_half; +typedef unsigned long elf32_off; +typedef unsigned long elf32_addr; + + +struct elf32_ehdr { + unsigned char e_ident[EI_NIDENT]; /* ident bytes */ + elf32_half e_type; /* file type */ + elf32_half e_machine; /* target machine */ + elf32_word e_version; /* file version */ + elf32_addr e_entry; /* start address */ + elf32_off e_phoff; /* phdr file offset */ + elf32_off e_shoff; /* shdr file offset */ + elf32_word e_flags; /* file flags */ + elf32_half e_ehsize; /* sizeof ehdr */ + elf32_half e_phentsize; /* sizeof phdr */ + elf32_half e_phnum; /* number phdrs */ + elf32_half e_shentsize; /* sizeof shdr */ + elf32_half e_shnum; /* number shdrs */ + elf32_half e_shstrndx; /* shdr string index */ +}; + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ + +struct elf32_shdr { + elf32_word sh_name; /* section name */ + elf32_word sh_type; /* SHT_... */ + elf32_word sh_flags; /* SHF_... */ + elf32_addr sh_addr; /* virtual address */ + elf32_off sh_offset; /* file offset */ + elf32_word sh_size; /* section size */ + elf32_word sh_link; /* misc info */ + elf32_word sh_info; /* misc info */ + elf32_word sh_addralign; /* memory alignment */ + elf32_word sh_entsize; /* entry size if table */ +}; + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +struct elf32_rel { + elf32_addr r_offset; /* Location to be relocated. */ + elf32_word r_info; /* Relocation type and symbol index. */ +}; + +struct elf32_rela { + elf32_addr r_offset; /* Location to be relocated. */ + elf32_word r_info; /* Relocation type and symbol index. */ + elf32_sword r_addend; /* Addend. */ +}; + +struct elf32_sym { + elf32_word st_name; /* String table index of name. */ + elf32_addr st_value; /* Symbol value. */ + elf32_word st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + elf32_half st_shndx; /* Section index of symbol. */ +}; + +#define ELF32_R_SYM(info) ((info) >> 8) +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +struct relevant_section { + unsigned char number; + //off_t offset; + char *address; +}; + +char elfloader_unknown[30]; /* Name that caused link error. */ + +static struct relevant_section bss, data, text; + +/*static unsigned char bss_sectionno, data_sectionno, text_sectionno;*/ + +static const unsigned char elf_magic_header[] = + {0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */ + 0x01, /* Only 32-bit objects. */ + 0x01, /* Only LSB data. */ + 0x01, /* Only ELF version 1. */ + }; + +/*---------------------------------------------------------------------------*/ +static int +relocate_section(off_t section, unsigned short size, + off_t sectionaddr, + off_t strs, + off_t strtab, + off_t symtab, + char *mem) +{ + struct elf32_rela rela; + struct elf32_sym s; + off_t a; + char name[30]; + char *addr; + struct relevant_section *sect; + + + for(a = section; a < section + size; a += sizeof(struct elf32_rela)) { + xmem_pread(&rela, sizeof(rela), a); + xmem_pread(&s, sizeof(s), + symtab + sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info)); + if(s.st_name == 0) { /* Local symbol (static) */ + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == text.number) { + sect = &text; + } else { + return ELFLOADER_SEGMENT_NOT_FOUND; + } + addr = sect->address + rela.r_addend; + } else { + xmem_pread(name, sizeof(name), strtab + s.st_name); + addr = (char *)symtab_lookup(name); + if(addr != NULL) { /* Global symbol */ + addr += rela.r_addend; + } else { /* Exported symbol */ + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == text.number) { + sect = &text; + } else { + PRINTF("elfloader unkown name: '%30s'\n", name); + memcpy(elfloader_unknown, name, sizeof(elfloader_unknown)); + elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0; + return ELFLOADER_SYMBOL_NOT_FOUND; + } + addr = sect->address + s.st_value + rela.r_addend; + } + } + memcpy(&mem[rela.r_offset], &addr, 2); /* Write reloc */ + } + return ELFLOADER_OK; +} +/*---------------------------------------------------------------------------*/ +typedef void (*PFV)(void); + +struct process *elfloader_loaded_process; +void (*elfloader_fini)(void); + +static PFV +find_init_and_fini(off_t symtab, unsigned short size, off_t strtab) +{ + struct elf32_sym s; + off_t a; + char name[30]; + void (*elfloader_init)(void); + + elfloader_init = NULL; + + for(a = symtab; a < symtab + size; a += sizeof(s)) { + xmem_pread(&s, sizeof(s), a); + + if(s.st_name != 0) { + xmem_pread(name, sizeof(name), strtab + s.st_name); + if(strcmp(name, "process_load") == 0) { + elfloader_loaded_process = + *(struct process **)&data.address[s.st_value]; + } else if (strcmp(name, "_init") == 0) { + /* XXX Check segment == text. */ + elfloader_init = (PFV)&text.address[s.st_value]; + } else if (strcmp(name, "_fini") == 0) { + /* XXX Check segment == text. */ + elfloader_fini = (PFV)&text.address[s.st_value]; + } + } + } + return elfloader_init; +} +/*---------------------------------------------------------------------------*/ +int +elfloader_load(off_t eepromaddr) +{ + struct elf32_ehdr ehdr; + struct elf32_shdr shdr; + struct elf32_shdr strtable; + off_t strs; + off_t shdrptr; + off_t nameptr; + char name[12]; + + int i; + unsigned short shdrnum, shdrsize; + + unsigned short textoff = 0, textsize, textrelaoff = 0, textrelasize; + unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize; + unsigned short symtaboff = 0, symtabsize; + unsigned short strtaboff = 0, strtabsize; + unsigned short bsssize = 0; + + int ret; + + void (*elfloader_init)(void); + elfloader_unknown[0] = 0; + + /* The ELF header is located at the start of the buffer. */ + xmem_pread(&ehdr, sizeof(ehdr), eepromaddr); + + /* Make sure that we have a correct and compatible ELF header. */ + if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { + return ELFLOADER_BAD_ELF_HEADER; + } + + /* Grab the section header. */ + shdrptr = eepromaddr + ehdr.e_shoff; + xmem_pread(&shdr, sizeof(shdr), shdrptr); + + /* Get the size and number of entries of the section header. */ + shdrsize = ehdr.e_shentsize; + shdrnum = ehdr.e_shnum; + + /* The string table section: holds the names of the sections. */ + xmem_pread(&strtable, sizeof(strtable), + eepromaddr + ehdr.e_shoff + shdrsize * ehdr.e_shstrndx); + + /* Get a pointer to the actual table of strings. This table holds + the names of the sections, not the names of other symbols in the + file (these are in the sybtam section). */ + strs = eepromaddr + strtable.sh_offset; + + /* Go through all sections and pick out the relevant ones. The + ".text" segment holds the actual code from the ELF file, the + ".data" segment contains initialized data, the ".bss" segment + holds the size of the unitialized data segment. The ".rela.text" + and ".rela.data" segments contains relocation information for the + contents of the ".text" and ".data" segments, respectively. The + ".symtab" segment contains the symbol table for this file. The + ".strtab" segment points to the actual string names used by the + symbol table. + + In addition to grabbing pointers to the relevant sections, we + also save the section number for resolving addresses in the + relocator code. + */ + + + /* Initialize the segment sizes to zero so that we can check if + their sections was found in the file or not. */ + textsize = textrelasize = datasize = datarelasize = + symtabsize = strtabsize = 0; + + bss.number = data.number = text.number = 0; + + shdrptr = eepromaddr + ehdr.e_shoff; + for(i = 0; i < shdrnum; ++i) { + + xmem_pread(&shdr, sizeof(shdr), shdrptr); + + /* The name of the section is contained in the strings table. */ + nameptr = strs + shdr.sh_name; + xmem_pread(name, sizeof(name), nameptr); + + /* Match the name of the section with a predefined set of names + (.text, .data, .bss, .rela.text, .rela.data, .symtab, and + .strtab). */ + + if(strncmp(name, ".text", 5) == 0) { + textoff = shdr.sh_offset; + textsize = shdr.sh_size; + text.number = i; + //text.offset = eepromaddr + textoff; + } else if(strncmp(name, ".rela.text", 10) == 0) { + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".data", 5) == 0) { + dataoff = shdr.sh_offset; + datasize = shdr.sh_size; + data.number = i; + //data.offset = eepromaddr + dataoff; + } else if(strncmp(name, ".rela.data", 10) == 0) { + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".symtab", 7) == 0) { + symtaboff = shdr.sh_offset; + symtabsize = shdr.sh_size; + } else if(strncmp(name, ".strtab", 7) == 0) { + strtaboff = shdr.sh_offset; + strtabsize = shdr.sh_size; + } else if(strncmp(name, ".bss", 4) == 0) { + bsssize = shdr.sh_size; + bss.number = i; + //bss.offset = 0; + } else { + PRINTF("elfloader: unknown '%12s' %d\n", name, shdrsize); + } + + /* Move on to the next section header. */ + shdrptr += shdrsize; + } + + + if(symtabsize == 0) { + return ELFLOADER_NO_SYMTAB; + } + if(strtabsize == 0) { + return ELFLOADER_NO_STRTAB; + } + if(textsize == 0) { + return ELFLOADER_NO_TEXT; + } + + if(datamemory != NULL) { + free(datamemory); + } + + /* We are making semi-permanent allocations, first compact heap! */ + malloc_compact(); + datamemory = malloc(IMAX(textsize, datasize + bsssize)); + if(datamemory == NULL) { + return ELFLOADER_DATA_TO_LARGE; /* XXX or text to large */ + } + + bss.address = (char *)datamemory; + data.address = (char *)datamemory + bsssize; + text.address = (char *)TEXTADDRESS; + + PRINTF("elfloader: copy text segment to RAM %p %p\n", + datamemory, datamemory + textsize); + xmem_pread(datamemory, textsize, eepromaddr + textoff); + if(textrelasize > 0) { + PRINTF("elfloader: relocate text in RAM\n"); + ret = relocate_section(eepromaddr + textrelaoff, textrelasize, + eepromaddr + textoff, + strs, + eepromaddr + strtaboff, + eepromaddr + symtaboff, + datamemory); + if(ret != ELFLOADER_OK) { + return ret; + } + } + PRINTF("elfloader: copy text segment to ROM %p %p\n", + text.address, text.address + textsize); + rom_erase((textsize + ROM_ERASE_UNIT_SIZE) & ~(ROM_ERASE_UNIT_SIZE - 1), + (uintptr_t)text.address); + rom_pwrite(datamemory, textsize, (uintptr_t)text.address); + + PRINTF("elfloader: copy data segment to RAM %p %p\n", + data.address, data.address + datasize); + xmem_pread(data.address, datasize, eepromaddr + dataoff); + if(datarelasize > 0) { + PRINTF("elfloader: relocate data segment\n"); + ret = relocate_section(eepromaddr + datarelaoff, datarelasize, + eepromaddr + dataoff, + strs, + eepromaddr + strtaboff, + eepromaddr + symtaboff, + data.address); + if(ret != ELFLOADER_OK) { + return ret; + } + } + + PRINTF("elfloader: zero bss %p %p\n", bss.address, bss.address + bsssize); + memset(bss.address, 0, bsssize); + datamemory = realloc(datamemory, datasize + bsssize); + if(datamemory != bss.address) { + free(bss.address); + return ELFLOADER_BSS_TO_LARGE; /* XXX realloc moved data */ + } + + /* Find _init, _fini, and loaded_process. */ + elfloader_loaded_process = NULL; + elfloader_fini = NULL; + elfloader_init = find_init_and_fini(eepromaddr + symtaboff, + symtabsize, + eepromaddr + strtaboff); + + if(elfloader_init != NULL) { + PRINTF("init=%p fini=%p\n", elfloader_init, elfloader_fini); + (*elfloader_init)(); + elfloader_loaded_process = NULL; + return ELFLOADER_OK; + } + + if(elfloader_loaded_process != NULL) { + PRINTF("elfloader: launch program\n"); + process_start(elfloader_loaded_process, NULL); + elfloader_fini = NULL; + return ELFLOADER_OK; + } else { + return ELFLOADER_NO_STARTPOINT; + } +} +/*---------------------------------------------------------------------------*/ +void +elfloader_unload(void) +{ + if(elfloader_fini != NULL) { + (*elfloader_fini)(); + elfloader_fini = NULL; + } else if(elfloader_loaded_process != NULL) { + process_exit(elfloader_loaded_process); + elfloader_loaded_process = NULL; + } + if(datamemory != NULL) { + free(datamemory); + datamemory = NULL; + } +} diff --git a/core/loader/elfloader.h b/core/loader/elfloader.h new file mode 100644 index 000000000..b819202b7 --- /dev/null +++ b/core/loader/elfloader.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: elfloader.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __ELFLOADER_H__ +#define __ELFLOADER_H__ + +#define ELFLOADER_OK 0 +#define ELFLOADER_BAD_ELF_HEADER 1 +#define ELFLOADER_NO_SYMTAB 2 +#define ELFLOADER_NO_STRTAB 3 +#define ELFLOADER_NO_TEXT 4 +#define ELFLOADER_SYMBOL_NOT_FOUND 5 +#define ELFLOADER_SEGMENT_NOT_FOUND 6 +#define ELFLOADER_NO_STARTPOINT 7 +#define ELFLOADER_TEXT_TO_LARGE 8 +#define ELFLOADER_DATA_TO_LARGE 9 +#define ELFLOADER_BSS_TO_LARGE 10 + +int elfloader_load(off_t eepromaddr); +void elfloader_unload(void); + +extern struct process *elfloader_loaded_process; +extern void (*elfloader_fini)(void); +extern char elfloader_unknown[30]; + +#endif /* __ELFLOADER_H__ */ diff --git a/core/loader/symbols.h b/core/loader/symbols.h new file mode 100644 index 000000000..e2e056d0b --- /dev/null +++ b/core/loader/symbols.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: symbols.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __SYMBOLS_H__ +#define __SYMBOLS_H__ + +struct symbols { + const char *name; + const char *value; +}; + +extern const struct symbols symbols[]; + +#endif /* __SYMBOLS_H__ */ diff --git a/core/loader/symtab.c b/core/loader/symtab.c new file mode 100644 index 000000000..fe8e0fb8c --- /dev/null +++ b/core/loader/symtab.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: symtab.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include "symtab.h" + +#include "loader/symbols.h" + +#include + +/*---------------------------------------------------------------------------*/ +const char * +symtab_lookup(const char *name) +{ + const struct symbols *s; + for(s = symbols; s->name != (const void *)0; ++s) { + if(strcmp(name, s->name) == 0) { + return s->value; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/loader/symtab.h b/core/loader/symtab.h new file mode 100644 index 000000000..b393761e6 --- /dev/null +++ b/core/loader/symtab.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: symtab.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __SYMTAB_H__ +#define __SYMTAB_H__ + +const char *symtab_lookup(const char *name); + +#endif /* __SYMTAB_H__ */ diff --git a/core/net/adhoc-service.h b/core/net/adhoc-service.h new file mode 100644 index 000000000..65041286f --- /dev/null +++ b/core/net/adhoc-service.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: adhoc-service.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** + * \file + * Header file for the ad hoc routing service + * \author + * Adam Dunkels + */ + +#ifndef __ADHOC_SERVICE_H__ +#define __ADHOC_SERVICE_H__ + +#include "contiki.h" + +SERVICE_INTERFACE(adhoc_service, +{ + void (* send)(uip_ipaddr_t addr, char *buf, int len); + process_event_t sent; +}); + +#define adhoc_service_name "Ad hoc routing service" + +#endif /* __ADHOC_SERVICE_H__ */ diff --git a/core/net/ahdlc.c b/core/net/ahdlc.c new file mode 100644 index 000000000..23e2dc7bc --- /dev/null +++ b/core/net/ahdlc.c @@ -0,0 +1,381 @@ +/* www.mycal.com + *--------------------------------------------------------------------------- + * ahdlc.c - Ahdlc receive and transmit processor for PPP engine. + * + *--------------------------------------------------------------------------- + * Version + * 0.1 Original Version Jan 11, 1998 + * + *--------------------------------------------------------------------------- + * + * Copyright (C) 1998, Mycal Labs www.mycal.com + * + *--------------------------------------------------------------------------- + */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: ahdlc.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#include "net/uip.h" +#include "ppp.h" + +#if 0 +#define DEBUG1(x) +#else +#include +#define DEBUG1(x) debug_printf x +#endif + +#define PACKET_TX_DEBUG 1 + +/*--------------------------------------------------------------------------- + * ahdlc flags bit defins, for ahdlc_flags variable + ---------------------------------------------------------------------------*/ +/* Escaped mode bit */ +#define AHDLC_ESCAPED 0x1 +/* Frame is ready bit */ +#define AHDLC_RX_READY 0x2 +#define AHDLC_RX_ASYNC_MAP 0x4 +#define AHDLC_TX_ASYNC_MAP 0x8 +#define AHDLC_PFC 0x10 +#define AHDLC_ACFC 0x20 + +/*--------------------------------------------------------------------------- + * Private Local Globals + * 10 bytes - standard + * - with counters + ---------------------------------------------------------------------------*/ +/* running tx CRC */ +u16_t ahdlc_tx_crc; +/* running rx CRC */ +u16_t ahdlc_rx_crc; +/* number of rx bytes processed, cur frame */ +u16_t ahdlc_rx_count; +/* ahdlc state flags, see above */ +u8_t ahdlc_flags; + +u8_t ahdlc_tx_offline; + +/* + * The following can be optimized out + */ +u8_t *ahdlc_rx_buffer; /* What to do here? +++ */ +u16_t ahdlc_max_rx_buffer_size; + +/* + * Optional statistics counters. + */ +#ifdef AHDLC_COUNTERS +u8_t ahdlc_rx_tobig_error; +#endif + +/*---------------------------------------------------------------------------*/ +/* Simple and fast CRC16 routine for embedded processors. + * Just slightly slower than the table lookup method but consumes + * almost no space. Much faster and smaller than the loop and + * shift method that is widely used in the embedded space. + * Can be optimized even more in .ASM + * + * data = (crcvalue ^ inputchar) & 0xff; + * data = (data ^ (data << 4)) & 0xff; + * crc = (crc >> 8) ^ ((data << 8) ^ (data <<3) ^ (data >> 4)) + */ +/*---------------------------------------------------------------------------*/ +static u16_t +crcadd(u16_t crcvalue, u8_t c) +{ + u16_t b; + + b = (crcvalue ^ c) & 0xFF; + b = (b ^ (b << 4)) & 0xFF; + b = (b << 8) ^ (b << 3) ^ (b >> 4); + + return ((crcvalue >> 8) ^ b); +} +/*---------------------------------------------------------------------------*/ +/* ahdlc_init(buffer, buffersize) - this initializes the ahdlc engine to + * allow for rx frames. + */ +/*---------------------------------------------------------------------------*/ +void +ahdlc_init(u8_t *buffer, u16_t maxrxbuffersize) +{ + ahdlc_flags = 0 | AHDLC_RX_ASYNC_MAP; + ahdlc_rx_buffer = buffer; + ahdlc_max_rx_buffer_size = maxrxbuffersize; + /* ahdlc_async_map = 0; */ +#ifdef AHDLC_COUNTERS + ahdlc_rx_tobig_error = 0; + ahdl_tx_offline = 0; +#endif +} +/*---------------------------------------------------------------------------*/ +/* ahdlc_rx_ready() - resets the ahdlc engine to the beginning of frame + * state. + */ +/*---------------------------------------------------------------------------*/ +void +ahdlc_rx_ready(void) +{ + ahdlc_rx_count = 0; + ahdlc_rx_crc = 0xffff; + ahdlc_flags |= AHDLC_RX_READY; +} +/*---------------------------------------------------------------------------*/ +/* ahdlc receive function - This routine processes incoming bytes and tries + * to build a PPP frame. + * + * Two possible reasons that ahdlc_rx will not process characters: + * o Buffer is locked - in this case ahdlc_rx returns 1, char + * sending routing should retry. + */ +/*---------------------------------------------------------------------------*/ +u8_t +ahdlc_rx(u8_t c) +{ + static u16_t protocol; + + /* check to see if PPP packet is useable, we should have hardware + flow control set, but if host ignores it and sends us a char when + the PPP Receive packet is in use, discard the character. +++ */ + + if(ahdlc_flags & AHDLC_RX_READY) { + /* check to see if character is less than 0x20 hex we really + should set AHDLC_RX_ASYNC_MAP on by default and only turn it + off when it is negotiated off to handle some buggy stacks. */ + if((c < 0x20) && + ((ahdlc_flags & AHDLC_RX_ASYNC_MAP) == 0)) { + /* discard character */ + DEBUG1(("Discard because char is < 0x20 hex and asysnc map is 0\n")); + return 0; + } + /* are we in escaped mode? */ + if(ahdlc_flags & AHDLC_ESCAPED) { + /* set escaped to FALSE */ + ahdlc_flags &= ~AHDLC_ESCAPED; + + /* if value is 0x7e then silently discard and reset receive packet */ + if(c == 0x7e) { + ahdlc_rx_ready(); + return 0; + } + /* incomming char = itself xor 20 */ + c = c ^ 0x20; + } else if(c == 0x7e) { + /* handle frame end */ + if(ahdlc_rx_crc == CRC_GOOD_VALUE) { + DEBUG1(("\nReceiving packet with good crc value, len %d\n",ahdlc_rx_count)); + /* we hae a good packet, turn off CTS until we are done with + this packet */ + /*CTS_OFF();*/ + /* remove CRC bytes from packet */ + ahdlc_rx_count -= 2; + + /* lock PPP buffer */ + ahdlc_flags &= ~AHDLC_RX_READY; + /* + * upcall routine must fully process frame before return + * as returning signifies that buffer belongs to AHDLC again. + */ + if((c & 0x1) && (ahdlc_flags & PPP_PFC)) { + /* Send up packet */ + ppp_upcall((u16_t)ahdlc_rx_buffer[0], + (u8_t *)&ahdlc_rx_buffer[1], + (u16_t)(ahdlc_rx_count - 1)); + } else { + /* Send up packet */ + ppp_upcall((u16_t)(ahdlc_rx_buffer[0] << 8 | ahdlc_rx_buffer[1]), + (u8_t *)&ahdlc_rx_buffer[2], (u16_t)(ahdlc_rx_count - 2)); + } + ahdlc_tx_offline = 0; // The remote side is alive + ahdlc_rx_ready(); + return 0; + } else if(ahdlc_rx_count > 3) { + DEBUG1(("\nReceiving packet with bad crc value, was 0x%04x len %d\n",ahdlc_rx_crc, ahdlc_rx_count)); +#ifdef AHDLC_COUNTERS + ++ahdlc_crc_error; +#endif + /* Shouldn't we dump the packet and not pass it up? */ + /*ppp_upcall((u16_t)ahdlc_rx_buffer[0], + (u8_t *)&ahdlc_rx_buffer[0], (u16_t)(ahdlc_rx_count+2)); + dump_ppp_packet(&ahdlc_rx_buffer[0],ahdlc_rx_count);*/ + + } + ahdlc_rx_ready(); + return 0; + } else if(c == 0x7d) { + /* handle escaped chars*/ + ahdlc_flags |= PPP_ESCAPED; + return 0; + } + + /* try to store char if not to big */ + if(ahdlc_rx_count >= ahdlc_max_rx_buffer_size /*PPP_RX_BUFFER_SIZE*/) { +#ifdef AHDLC_COUNTERS + ++ahdlc_rx_tobig_error; +#endif + ahdlc_rx_ready(); + } else { + /* Add CRC in */ + ahdlc_rx_crc = crcadd(ahdlc_rx_crc, c); + /* do auto ACFC, if packet len is zero discard 0xff and 0x03 */ + if(ahdlc_rx_count == 0) { + if((c == 0xff) || (c == 0x03)) + return 0; + } + /* Store char */ + ppp_rx_buffer[ahdlc_rx_count++] = c; + } + } else { + /* we are busy and didn't process the character. */ + DEBUG1(("Busy/not active\n")); + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/* ahdlc_tx_char(char) - write a character to the serial device, + * escape if necessary. + * + * Relies on local global vars : ahdlc_tx_crc, ahdlc_flags. + * Modifies local global vars : ahdlc_tx_crc. + */ +/*---------------------------------------------------------------------------*/ +void +ahdlc_tx_char(u16_t protocol, u8_t c) +{ + /* add in crc */ + ahdlc_tx_crc = crcadd(ahdlc_tx_crc, c); + /* + * See if we need to escape char, we always escape 0x7d and 0x7e, in the case + * of char < 0x20 we only support async map of default or none, so escape if + * ASYNC map is not set. We may want to modify this to support a bitmap set + * ASYNC map. + */ + if((c == 0x7d) || (c == 0x7e) || + ((c < 0x20) && ((protocol == LCP) || + (ahdlc_flags & PPP_TX_ASYNC_MAP) == 0))) { + /* send escape char and xor byte by 0x20 */ + ppp_arch_putchar(0x7d); + c ^= 0x20; + } + ppp_arch_putchar(c); +} +/*---------------------------------------------------------------------------*/ +/* ahdlc_tx(protocol,buffer,len) - Transmit a PPP frame. + * Buffer contains protocol data, ahdlc_tx addes address, control and + * protocol data. + * + * Relies on local global vars : ahdlc_tx_crc, ahdlc_flags. + * Modifies local global vars : ahdlc_tx_crc. + */ +/*---------------------------------------------------------------------------*/ +u8_t +ahdlc_tx(u16_t protocol, u8_t *header, u8_t *buffer, + u16_t headerlen, u16_t datalen) +{ + u16_t i; + u8_t c; + + DEBUG1(("\nAHDLC_TX - transmit frame, protocol 0x%04x, length %d offline %d\n",protocol,datalen+headerlen,ahdlc_tx_offline)); + if (AHDLC_TX_OFFLINE && (ahdlc_tx_offline++ > AHDLC_TX_OFFLINE)) { + ahdlc_tx_offline = 0; + DEBUG1(("\nAHDLC_TX to many outstanding TX packets => ppp_reconnect()\n")); + ppp_reconnect(); + return 0; + } + +#if PACKET_TX_DEBUG + DEBUG1(("\n")); + for(i = 0; i < headerlen; ++i) { + DEBUG1(("0x%02x ", header[i])); + } + for(i = 0; i < datalen; ++i) { + DEBUG1(("0x%02x ", buffer[i])); + } + DEBUG1(("\n\n")); +#endif + + /* Check to see that physical layer is up, we can assume is some + cases */ + + /* write leading 0x7e */ + ppp_arch_putchar(0x7e); + + /* set initial CRC value */ + ahdlc_tx_crc = 0xffff; + /* send HDLC control and address if not disabled or of LCP frame type */ + /*if((0==(ahdlc_flags & PPP_ACFC)) || ((0xc0==buffer[0]) && (0x21==buffer[1]))) */ + if((0 == (ahdlc_flags & PPP_ACFC)) || (protocol == LCP)) { + ahdlc_tx_char(protocol, 0xff); + ahdlc_tx_char(protocol, 0x03); + } + + /* Write Protocol */ + ahdlc_tx_char(protocol,(u8_t)(protocol >> 8)); + ahdlc_tx_char(protocol,(u8_t)(protocol & 0xff)); + + /* write header if it exists */ + for(i = 0; i < headerlen; ++i) { + /* Get next byte from buffer */ + c = header[i]; + /* Write it...*/ + ahdlc_tx_char(protocol, c); + } + + /* Write frame bytes */ + for(i = 0; i < datalen; ++i) { + /* Get next byte from buffer */ + c = buffer[i]; + /* Write it...*/ + ahdlc_tx_char(protocol, c); + } + + /* send crc, lsb then msb */ + i = ahdlc_tx_crc ^ 0xffff; + ahdlc_tx_char(protocol, (u8_t)(i & 0xff)); + ahdlc_tx_char(protocol, (u8_t)((i >> 8) & 0xff)); + + /* write trailing 0x7e, probably not needed but it doesn't hurt*/ + ppp_arch_putchar(0x7e); + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ahdlc.h b/core/net/ahdlc.h new file mode 100644 index 000000000..4afd895ac --- /dev/null +++ b/core/net/ahdlc.h @@ -0,0 +1,57 @@ +#ifndef __AHDLC_H__ +#define __AHDLC_H__ + +/*--------------------------------------------------------------------------- + ahdlc.h - ahdlc header file +--------------------------------------------------------------------------- + Version + 0.1 Original Version Jan 11, 1998 + (c)1998 Mycal Labs, All Rights Reserved + ---------------------------------------------------------------------------*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: ahdlc.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +#include "net/uip.h" + +void ahdlc_init(u8_t *, u16_t); +void ahdlc_rx_ready(void); +u8_t ahdlc_rx(u8_t); +u8_t ahdlc_tx(u16_t protocol, u8_t *header, u8_t *buffer, + u16_t headerlen, u16_t datalen); + +#endif /* __AHDLC_H__ */ diff --git a/core/net/dhcpc.c b/core/net/dhcpc.c new file mode 100644 index 000000000..5f772a932 --- /dev/null +++ b/core/net/dhcpc.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: dhcpc.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include +#include + +#include "contiki.h" +#include "contiki-net.h" +#include "net/dhcpc.h" + +#define STATE_INITIAL 0 +#define STATE_SENDING 1 +#define STATE_OFFER_RECEIVED 2 +#define STATE_CONFIG_RECEIVED 3 + +static struct dhcpc_state s; + +struct dhcp_msg { + u8_t op, htype, hlen, hops; + u8_t xid[4]; + u16_t secs, flags; + u8_t ciaddr[4]; + u8_t yiaddr[4]; + u8_t siaddr[4]; + u8_t giaddr[4]; + u8_t chaddr[16]; +#ifndef UIP_CONF_DHCP_LIGHT + u8_t sname[64]; + u8_t file[128]; +#endif + u8_t options[312]; +}; + +#define BOOTP_BROADCAST 0x8000 + +#define DHCP_REQUEST 1 +#define DHCP_REPLY 2 +#define DHCP_HTYPE_ETHERNET 1 +#define DHCP_HLEN_ETHERNET 6 +#define DHCP_MSG_LEN 236 + +#define DHCPC_SERVER_PORT 67 +#define DHCPC_CLIENT_PORT 68 + +#define DHCPDISCOVER 1 +#define DHCPOFFER 2 +#define DHCPREQUEST 3 +#define DHCPDECLINE 4 +#define DHCPACK 5 +#define DHCPNAK 6 +#define DHCPRELEASE 7 + +#define DHCP_OPTION_SUBNET_MASK 1 +#define DHCP_OPTION_ROUTER 3 +#define DHCP_OPTION_DNS_SERVER 6 +#define DHCP_OPTION_REQ_IPADDR 50 +#define DHCP_OPTION_LEASE_TIME 51 +#define DHCP_OPTION_MSG_TYPE 53 +#define DHCP_OPTION_SERVER_ID 54 +#define DHCP_OPTION_REQ_LIST 55 +#define DHCP_OPTION_END 255 + +static u32_t xid; +static const u8_t magic_cookie[4] = {99, 130, 83, 99}; +/*---------------------------------------------------------------------------*/ +static u8_t * +add_msg_type(u8_t *optptr, u8_t type) +{ + *optptr++ = DHCP_OPTION_MSG_TYPE; + *optptr++ = 1; + *optptr++ = type; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_server_id(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_SERVER_ID; + *optptr++ = 4; + memcpy(optptr, s.serverid, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_ipaddr(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_IPADDR; + *optptr++ = 4; + memcpy(optptr, s.ipaddr, 4); + return optptr + 4; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_req_options(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_REQ_LIST; + *optptr++ = 3; + *optptr++ = DHCP_OPTION_SUBNET_MASK; + *optptr++ = DHCP_OPTION_ROUTER; + *optptr++ = DHCP_OPTION_DNS_SERVER; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static u8_t * +add_end(u8_t *optptr) +{ + *optptr++ = DHCP_OPTION_END; + return optptr; +} +/*---------------------------------------------------------------------------*/ +static void +create_msg(register struct dhcp_msg *m) +{ + m->op = DHCP_REQUEST; + m->htype = DHCP_HTYPE_ETHERNET; + m->hlen = s.mac_len; + m->hops = 0; + memcpy(m->xid, &xid, sizeof(m->xid)); + m->secs = 0; + m->flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */ + /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/ + memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr)); + memset(m->yiaddr, 0, sizeof(m->yiaddr)); + memset(m->siaddr, 0, sizeof(m->siaddr)); + memset(m->giaddr, 0, sizeof(m->giaddr)); + memcpy(m->chaddr, s.mac_addr, s.mac_len); + memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len); +#ifndef UIP_CONF_DHCP_LIGHT + memset(m->sname, 0, sizeof(m->sname)); + memset(m->file, 0, sizeof(m->file)); +#endif + + memcpy(m->options, magic_cookie, sizeof(magic_cookie)); +} +/*---------------------------------------------------------------------------*/ +static void +send_discover(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPDISCOVER); + end = add_req_options(end); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static void +send_request(void) +{ + u8_t *end; + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + create_msg(m); + + end = add_msg_type(&m->options[4], DHCPREQUEST); + end = add_server_id(end); + end = add_req_ipaddr(end); + end = add_end(end); + + uip_send(uip_appdata, end - (u8_t *)uip_appdata); +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_options(u8_t *optptr, int len) +{ + u8_t *end = optptr + len; + u8_t type = 0; + + while(optptr < end) { + switch(*optptr) { + case DHCP_OPTION_SUBNET_MASK: + memcpy(s.netmask, optptr + 2, 4); + break; + case DHCP_OPTION_ROUTER: + memcpy(s.default_router, optptr + 2, 4); + break; + case DHCP_OPTION_DNS_SERVER: + memcpy(s.dnsaddr, optptr + 2, 4); + break; + case DHCP_OPTION_MSG_TYPE: + type = *(optptr + 2); + break; + case DHCP_OPTION_SERVER_ID: + memcpy(s.serverid, optptr + 2, 4); + break; + case DHCP_OPTION_LEASE_TIME: + memcpy(s.lease_time, optptr + 2, 4); + break; + case DHCP_OPTION_END: + return type; + } + + optptr += optptr[1] + 2; + } + return type; +} +/*---------------------------------------------------------------------------*/ +static u8_t +parse_msg(void) +{ + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + + if(m->op == DHCP_REPLY && + memcmp(m->xid, &xid, sizeof(xid)) == 0 && + memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { + memcpy(s.ipaddr, m->yiaddr, 4); + return parse_options(&m->options[4], uip_datalen()); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +/* + * Is this a "fresh" reply for me? If it is, return the type. + */ +static int +msg_for_me(void) +{ + struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata; + u8_t *optptr = &m->options[4]; + u8_t *end = uip_appdata + uip_datalen(); + + if(m->op == DHCP_REPLY && + memcmp(m->xid, &xid, sizeof(xid)) == 0 && + memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) { + while(optptr < end) { + if(*optptr == DHCP_OPTION_MSG_TYPE) { + return *(optptr + 2); + } else if (*optptr == DHCP_OPTION_END) { + return -1; + } + optptr += optptr[1] + 2; + } + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_dhcp(process_event_t ev, void *data)) +{ + PT_BEGIN(&s.pt); + + init: + xid++; + s.state = STATE_SENDING; + s.ticks = CLOCK_SECOND; + while (1) { + while(ev != tcpip_event) { + tcpip_poll_udp(s.conn); + PT_YIELD(&s.pt); + } + send_discover(); + etimer_set(&s.etimer, s.ticks); + do { + PT_YIELD(&s.pt); + if(ev == tcpip_event && uip_newdata() && msg_for_me() == DHCPOFFER) { + parse_msg(); + s.state = STATE_OFFER_RECEIVED; + goto selecting; + } + } while (!etimer_expired(&s.etimer)); + + if(s.ticks < CLOCK_SECOND * 60) { + s.ticks *= 2; + } + } + + selecting: + xid++; + s.ticks = CLOCK_SECOND; + do { + while(ev != tcpip_event) { + tcpip_poll_udp(s.conn); + PT_YIELD(&s.pt); + } + send_request(); + etimer_set(&s.etimer, s.ticks); + do { + PT_YIELD(&s.pt); + if(ev == tcpip_event && uip_newdata() && msg_for_me() == DHCPACK) { + parse_msg(); + s.state = STATE_CONFIG_RECEIVED; + goto bound; + } + } while (!etimer_expired(&s.etimer)); + + if(s.ticks <= CLOCK_SECOND * 10) { + s.ticks += CLOCK_SECOND; + } else { + goto init; + } + } while(s.state != STATE_CONFIG_RECEIVED); + + bound: +#if 0 + printf("Got IP address %d.%d.%d.%d\n", + uip_ipaddr1(s.ipaddr), uip_ipaddr2(s.ipaddr), + uip_ipaddr3(s.ipaddr), uip_ipaddr4(s.ipaddr)); + printf("Got netmask %d.%d.%d.%d\n", + uip_ipaddr1(s.netmask), uip_ipaddr2(s.netmask), + uip_ipaddr3(s.netmask), uip_ipaddr4(s.netmask)); + printf("Got DNS server %d.%d.%d.%d\n", + uip_ipaddr1(s.dnsaddr), uip_ipaddr2(s.dnsaddr), + uip_ipaddr3(s.dnsaddr), uip_ipaddr4(s.dnsaddr)); + printf("Got default router %d.%d.%d.%d\n", + uip_ipaddr1(s.default_router), uip_ipaddr2(s.default_router), + uip_ipaddr3(s.default_router), uip_ipaddr4(s.default_router)); + printf("Lease expires in %ld seconds\n", + ntohs(s.lease_time[0])*65536ul + ntohs(s.lease_time[1])); +#endif + + dhcpc_configured(&s); + + if((s.lease_time[0]*65536ul + ntohs(s.lease_time[1]))*CLOCK_SECOND/2 + <= (clock_time_t)~0ul) { + s.ticks = (s.lease_time[0]*65536ul +ntohs(s.lease_time[1]))*CLOCK_SECOND/2; + } else { + s.ticks = ~0u; + } + + etimer_set(&s.etimer, s.ticks); + PT_YIELD_UNTIL(&s.pt, etimer_expired(&s.etimer)); + + /* renewing: */ + xid++; + do { + while(ev != tcpip_event) { + tcpip_poll_udp(s.conn); + PT_YIELD(&s.pt); + } + send_request(); + s.ticks /= 2; + etimer_set(&s.etimer, s.ticks); + do { + PT_YIELD(&s.pt); + if(ev == tcpip_event && uip_newdata() && msg_for_me() == DHCPACK) { + parse_msg(); + goto bound; + } + } while(!etimer_expired(&s.etimer)); + } while(s.ticks >= CLOCK_SECOND*3); + + /* rebinding: */ + + /* lease_expired: */ + dhcpc_unconfigured(&s); + goto init; + + PT_END(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_init(const void *mac_addr, int mac_len) +{ + u16_t addr[2]; + + s.mac_addr = mac_addr; + s.mac_len = mac_len; + + s.state = STATE_INITIAL; + uip_ipaddr(addr, 255,255,255,255); + s.conn = udp_new(addr, HTONS(DHCPC_SERVER_PORT), NULL); + if(s.conn != NULL) { + udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT)); + } + PT_INIT(&s.pt); +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_appcall(process_event_t ev, void *data) +{ + if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { + handle_dhcp(ev, data); + } +} +/*---------------------------------------------------------------------------*/ +void +dhcpc_request(void) +{ + u16_t ipaddr[2]; + + if(s.state == STATE_INITIAL) { + uip_ipaddr(ipaddr, 0,0,0,0); + uip_sethostaddr(ipaddr); + handle_dhcp(PROCESS_EVENT_NONE, NULL); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/dhcpc.h b/core/net/dhcpc.h new file mode 100644 index 000000000..c86f0d602 --- /dev/null +++ b/core/net/dhcpc.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: dhcpc.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __DHCPC_H__ +#define __DHCPC_H__ + +struct dhcpc_state { + struct pt pt; + char state; + struct uip_udp_conn *conn; + struct etimer etimer; + u16_t ticks; + const void *mac_addr; + int mac_len; + + u8_t serverid[4]; + + u16_t lease_time[2]; + u16_t ipaddr[2]; + u16_t netmask[2]; + u16_t dnsaddr[2]; + u16_t default_router[2]; +}; + +void dhcpc_init(const void *mac_addr, int mac_len); +void dhcpc_request(void); + +void dhcpc_appcall(process_event_t ev, void *data); + +/* Mandatory callbacks provided by the user. */ +void dhcpc_configured(const struct dhcpc_state *s); +void dhcpc_unconfigured(const struct dhcpc_state *s); + +#endif /* __DHCPC_H__ */ diff --git a/core/net/hc-service.c b/core/net/hc-service.c new file mode 100644 index 000000000..bdc28c827 --- /dev/null +++ b/core/net/hc-service.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: hc-service.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include "hc-service.h" + +static void +compress(void) +{ + +} + +static void +decompress(void) +{ + +} + +SERVICE(hc_service, { compress, decompress }); + + +PROCESS(hc_service_process, "Header compression"); + +PROCESS_THREAD(hc_service_process, ev, data) +{ + PROCESS_BEGIN(); + + PROCESS_SET_FLAGS(PROCESS_NO_BROADCAST); + + SERVICE_REGISTER(hc_service); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT); + } + + SERVICE_REMOVE(hc_service); + + PROCESS_END(); +} diff --git a/core/net/hc-service.h b/core/net/hc-service.h new file mode 100644 index 000000000..ad43f7c2b --- /dev/null +++ b/core/net/hc-service.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: hc-service.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __HC_SERVICE_H__ +#define __HC_SERVICE_H__ + +#include "service.h" + +SERVICE_INTERFACE(hc_service, { + void (* compress)(void); + void (* decompress)(void); +}); + +#define hc_service_name "Header compression" + +#endif /* __HC_SERVICE_H__ */ diff --git a/core/net/hc.c b/core/net/hc.c new file mode 100644 index 000000000..1aa000dac --- /dev/null +++ b/core/net/hc.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: hc.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** + * \file + * TCP/IP header compression implementation + * \author Adam Dunkels + * + */ + +#include "net/hc.h" + +#include "net/uip.h" + +#include + +#define FLAGS_COMPRESSED 0x8000 +#define FLAGS_BROADCASTDATA 0x4000 + +struct hc_hdr { + u16_t flagsport; + u16_t srcipaddr[2]; +}; + +struct udpip_hdr { + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; + + /* UDP header. */ + u16_t srcport, + destport; + u16_t udplen; + u16_t udpchksum; +}; + +#include + +/*---------------------------------------------------------------------------*/ +/** + * Initialize the header compression module. + */ +/*---------------------------------------------------------------------------*/ +void +hc_init(void) +{ + +} +/*---------------------------------------------------------------------------*/ +/** + * Compress the header found in the uip_buf. + * + * This function compresses the TCP/IP headers in the uip_buf and + * should be called just before sending out data on the network. A + * pointer to the compressed header is returned, and uip_len is + * adjusted. + * + * If the header could not be compressed, the function does nothing + * and returns a NULL pointer. + * + * \return A pointer to the start of the compressed header or NULL if + * the header could not be compressed. + */ +/*---------------------------------------------------------------------------*/ +int +hc_compress(void) +{ + struct hc_hdr *hdr; + struct udpip_hdr *uhdr; + + hdr = (struct hc_hdr *)&uip_buf[UIP_LLH_LEN]; + uhdr = (struct udpip_hdr *)&uip_buf[UIP_LLH_LEN]; + + /* Check the original TCP/IP header to see if it matches our + pattern, and compress if it does. */ + + if(uhdr->vhl == 0x45 && /* Only IPv4 without + options. */ + uhdr->len[0] == 0x00 && /* Only packets < 256 + bytes long. */ + uhdr->ipoffset[0] == 0x00 && /* No fragmented IP + packets. */ + uhdr->ipoffset[1] == 0x00 && /* No fragmented IP + packets. */ + uhdr->proto == UIP_PROTO_UDP && /* Only UDP packets. */ + uhdr->destipaddr[0] == 0xffffU && /* Only link-local + broadcast + packets. */ + uhdr->destipaddr[1] == 0xffffU && /* Only link-local + broadcast + packets. */ + uhdr->destport == uhdr->srcport && /* Only packets with + the same destination + and source port + number. */ + (uhdr->destport & HTONS(0xc000)) == 0) { /* Only packets with the two + highest bits in the port + number equal to zero. */ + + hdr->flagsport = htons( + FLAGS_COMPRESSED | /* Compressed header. */ + FLAGS_BROADCASTDATA | /* Broadcast data. */ + (htons(uhdr->destport) & 0x3fff)); + uip_ipaddr_copy(&hdr->srcipaddr, &uhdr->srcipaddr); + + /* Move the packet data to the end of the compressed header. */ + memcpy((char *)hdr + HC_HLEN, + &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], + uip_len - UIP_IPUDPH_LEN); + + /* Return the new packet length. */ + return uip_len - (UIP_IPUDPH_LEN - HC_HLEN); + } + + /* No compression possible, return NULL pointer. */ + return uip_len; + +} +/*---------------------------------------------------------------------------*/ +/** + * Inflate (decompress) a header in the uip_buf buffer. + * + * This function should be called to inflate a possibly compressed + * packet header just after a packet has been received from the + * network. The function will copy the packet data so that the + * original header fits and adjusts uip_len. + * + */ +/*---------------------------------------------------------------------------*/ +int +hc_inflate(void) +{ + struct udpip_hdr *uhdr; + struct hc_hdr *hdr; + + hdr = (struct hc_hdr *)&uip_buf[UIP_LLH_LEN]; + + /* First, check if the header in uip_buf is compressed or not. */ + if((hdr->flagsport & HTONS(FLAGS_COMPRESSED)) != 0 && + (hdr->flagsport & HTONS(FLAGS_BROADCASTDATA)) != 0) { + + /* Move packet data in memory to make room for the uncompressed header. */ + memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN - HC_HLEN], + &uip_buf[UIP_LLH_LEN], uip_len); + uhdr = (struct udpip_hdr *)&uip_buf[UIP_LLH_LEN]; + hdr = (struct hc_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN - + HC_HLEN]; + + uhdr->srcipaddr[0] = hdr->srcipaddr[0]; + uhdr->srcipaddr[1] = hdr->srcipaddr[1]; + uhdr->srcport = hdr->flagsport & HTONS(0x3fff); + uhdr->destport = hdr->flagsport & HTONS(0x3fff); + + uhdr->udplen = uip_len; + + uip_len += UIP_IPUDPH_LEN - HC_HLEN; + + + uhdr->vhl = 0x45; + uhdr->tos = 0; + uhdr->len[0] = 0; + uhdr->len[1] = uip_len; + uhdr->ipid[0] = uhdr->ipid[1] = 0xAD; + uhdr->ipoffset[0] = uhdr->ipoffset[1] = 0; + uhdr->ttl = 2; + uhdr->proto = UIP_PROTO_UDP; + uhdr->destipaddr[0] = uhdr->destipaddr[1] = 0xffff; + uhdr->udpchksum = 0; + + uhdr->ipchksum = 0; + uhdr->ipchksum = ~(uip_ipchksum()); + + } + + return uip_len; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/hc.h b/core/net/hc.h new file mode 100644 index 000000000..e7c290cf3 --- /dev/null +++ b/core/net/hc.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: hc.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +/** + * \file + * TCP/IP header compresison header file. + * \author Adam Dunkels + * + */ + +#ifndef __HC_H__ +#define __HC_H__ + +void hc_init(void); +int hc_compress(void); +int hc_inflate(void); + +#define HC_HLEN 6 + +#endif /* __HC_H__ */ diff --git a/core/net/ipcp.c b/core/net/ipcp.c new file mode 100644 index 000000000..878c8e12d --- /dev/null +++ b/core/net/ipcp.c @@ -0,0 +1,462 @@ +/* + *--------------------------------------------------------------------------- + * ipcp.c - PPP IPCP (intrnet protocol) Processor/Handler + * + *--------------------------------------------------------------------------- + * + * Version + * 0.1 Original Version Jun 3, 2000 + * + *--------------------------------------------------------------------------- + * + * Copyright (C) 2000, Mycal Labs www.mycal.com + * + *--------------------------------------------------------------------------- + */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: ipcp.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#if 0 +#define DEBUG1(x) +#else +#include +#define DEBUG1(x) debug_printf x +#endif + +#include "net/uip.h" +/*#include "time.h"*/ +#include "ipcp.h" +#include "ppp.h" +#include "ahdlc.h" + +#define TIMER_expire() +#define TIMER_set() +#define TIMER_timeout(x) 1 + +#ifdef IPCP_GET_PEER_IP +uip_ipaddr_t peer_ip_addr; +#endif + +#ifdef IPCP_GET_PRI_DNS +uip_ipaddr_t pri_dns_addr; +#endif + +#ifdef IPCP_GET_SEC_DNS +uip_ipaddr_t sec_dns_addr; +#endif + +static unsigned long prev_ipcp_seconds = 0; + +/* + * Local IPCP state + */ +u8_t ipcp_state; + +/* + * in the future add copression protocol and name servers (possibly for servers only) + */ +u8_t ipcplist[] = {0x3, 0}; + +/*---------------------------------------------------------------------------*/ +#if 1 +void +printip(uip_ipaddr_t ip2) +{ + char *ip = (u8_t*)ip2; + DEBUG1((" %d.%d.%d.%d ",ip[0],ip[1],ip[2],ip[3])); +} +#else +#define printip(x) +#endif +/*---------------------------------------------------------------------------*/ +void +ipcp_init(void) +{ + DEBUG1(("ipcp init\n")); + ipcp_state = 0; + ppp_retry = 0; + pppif.ipaddr[0] = pppif.ipaddr[1] = 0; +} +/*---------------------------------------------------------------------------*/ +/* + * IPCP RX protocol Handler + */ +void +ipcp_rx(u8_t *buffer, u16_t count) +{ + u8_t *bptr = buffer; + IPCPPKT *pkt=(IPCPPKT *)buffer; + u16_t len; + + DEBUG1(("IPCP len %d\n",count)); + + switch(*bptr++) { + case CONF_REQ: + /* parce request and see if we can ACK it */ + ++bptr; + len = (*bptr++ << 8); + len |= *bptr++; + /* len-=2; */ + + DEBUG1(("check lcplist\n")); + if(scan_packet(IPCP, ipcplist, buffer, bptr, (u16_t)(len - 4))) { + DEBUG1(("option was bad\n")); + } else { + DEBUG1(("IPCP options are good\n")); + /* + * Parse out the results + */ + /* lets try to implement what peer wants */ + /* Reject any protocol not */ + /* Error? if we we need to send a config Reject ++++ this is + good for a subroutine*/ + /* All we should get is the peer IP address */ + if(IPCP_IPADDRESS == *bptr++) { + /* dump length */ + ++bptr; +#ifdef IPCP_GET_PEER_IP + ((u8_t*)peer_ip_addr)[0] = *bptr++; + ((u8_t*)peer_ip_addr)[1] = *bptr++; + ((u8_t*)peer_ip_addr)[2] = *bptr++; + ((u8_t*)peer_ip_addr)[3] = *bptr++; + DEBUG1(("Peer IP ")); + /* printip(peer_ip_addr);*/ + DEBUG1(("\n")); +#else + bptr += 4; +#endif + } else { + DEBUG1(("HMMMM this shouldn't happen IPCP1\n")); + } + +#if 0 + if(error) { + /* write the config NAK packet we've built above, take on the header */ + bptr = buffer; + *bptr++ = CONF_NAK; /* Write Conf_rej */ + *bptr++; + /*tptr++;*/ /* skip over ID */ + + /* Write new length */ + *bptr++ = 0; + *bptr = tptr - buffer; + + /* write the reject frame */ + DEBUG1(("Writing NAK frame \n")); + ahdlc_tx(IPCP, buffer, (u16_t)(tptr - buffer)); + DEBUG1(("- End NAK Write frame\n")); + + } else { + } +#endif + /* + * If we get here then we are OK, lets send an ACK and tell the rest + * of our modules our negotiated config. + */ + ipcp_state |= IPCP_RX_UP; + DEBUG1(("Send IPCP ACK!\n")); + bptr = buffer; + *bptr++ = CONF_ACK; /* Write Conf_ACK */ + bptr++; /* Skip ID (send same one) */ + /* + * Set stuff + */ + /* ppp_flags |= tflag; */ + DEBUG1(("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer))); + + /* write the ACK frame */ + DEBUG1(("Writing ACK frame \n")); + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + ahdlc_tx(IPCP, 0, buffer, 0, count /*bptr-buffer*/); + DEBUG1(("- End ACK Write frame\n")); + + /* expire the timer to make things happen after a state change */ + /*timer_expire(); */ + + /* } */ + } + break; + case CONF_ACK: /* config Ack */ + DEBUG1(("CONF ACK\n")); + /* + * Parse out the results + * + * Dump the ID and get the length. + */ + /* dump the ID */ + bptr++; + + /* get the length */ + len = (*bptr++ << 8); + len |= *bptr++; +#if 0 + /* Parse ACK and set data */ + while(bptr < buffer + len) { + switch(*bptr++) { + case IPCP_IPADDRESS: + /* dump length */ + bptr++; + ((u8_t*)ipaddr)[0] = *bptr++; + ((u8_t*)ipaddr)[1] = *bptr++; + ((u8_t*)ipaddr)[2] = *bptr++; + ((u8_t*)ipaddr)[3] = *bptr++; + break; + case IPCP_PRIMARY_DNS: + bptr++; + ((u8_t*)pri_dns_addr)[0] = *bptr++; + ((u8_t*)pri_dns_addr)[1] = *bptr++; + ((u8_t*)pri_dns_addr)[2] = *bptr++; + ((u8_t*)pri_dns_addr)[3] = *bptr++; + break; + case IPCP_SECONDARY_DNS: + bptr++; + ((u8_t*)sec_dns_addr)[0] = *bptr++; + ((u8_t*)sec_dns_addr)[1] = *bptr++; + ((u8_t*)sec_dns_addr)[2] = *bptr++; + ((u8_t*)sec_dns_addr)[3] = *bptr++; + break; + default: + DEBUG1(("IPCP CONFIG_ACK problem1\n")); + } + } +#endif + ipcp_state |= IPCP_TX_UP; + /*ipcp_state &= ~IPCP_RX_UP;*/ + DEBUG1(("were up! \n")); + printip(pppif.ipaddr); +#ifdef IPCP_GET_PRI_DNS + printip(pri_dns_addr); +#endif +#ifdef IPCP_GET_SEC_DNS + printip(sec_dns_addr); +#endif + DEBUG1(("\n")); + + /* expire the timer to make things happen after a state change */ + TIMER_expire(); + break; + case CONF_NAK: /* Config Nack */ + DEBUG1(("CONF NAK\n")); + /* dump the ID */ + bptr++; + /* get the length */ + len = (*bptr++ << 8); + len |= *bptr++; + + /* Parse ACK and set data */ + while(bptr < buffer + len) { + switch(*bptr++) { + case IPCP_IPADDRESS: + /* dump length */ + bptr++; + ((u8_t*)pppif.ipaddr)[0] = *bptr++; + ((u8_t*)pppif.ipaddr)[1] = *bptr++; + ((u8_t*)pppif.ipaddr)[2] = *bptr++; + ((u8_t*)pppif.ipaddr)[3] = *bptr++; + uip_fw_register( &pppif ); + DEBUG1(("My PPP-ipno: (%d.%d.%d.%d)\n", ((u8_t*)pppif.ipaddr)[0], ((u8_t*)pppif.ipaddr)[1], ((u8_t*)pppif.ipaddr)[2], ((u8_t*)pppif.ipaddr)[3])); + break; +#ifdef IPCP_GET_PRI_DNS + case IPCP_PRIMARY_DNS: + bptr++; + ((u8_t*)pri_dns_addr)[0] = *bptr++; + ((u8_t*)pri_dns_addr)[1] = *bptr++; + ((u8_t*)pri_dns_addr)[2] = *bptr++; + ((u8_t*)pri_dns_addr)[3] = *bptr++; + break; +#endif +#ifdef IPCP_GET_SEC_DNS + case IPCP_SECONDARY_DNS: + bptr++; + ((u8_t*)sec_dns_addr)[0] = *bptr++; + ((u8_t*)sec_dns_addr)[1] = *bptr++; + ((u8_t*)sec_dns_addr)[2] = *bptr++; + ((u8_t*)sec_dns_addr)[3] = *bptr++; + break; +#endif + default: + DEBUG1(("IPCP CONFIG_ACK problem 2\n")); + } + } + ppp_id++; + printip(pppif.ipaddr); +#ifdef IPCP_GET_PRI_DNS + printip(pri_dns_addr); +#endif +#ifdef IPCP_GET_PRI_DNS + printip(sec_dns_addr); +#endif + DEBUG1(("\n")); + /* expire the timer to make things happen after a state change */ + TIMER_expire(); + break; + case CONF_REJ: /* Config Reject */ + DEBUG1(("CONF REJ\n")); + /* Remove the offending options*/ + ppp_id++; + /* dump the ID */ + bptr++; + /* get the length */ + len = (*bptr++ << 8); + len |= *bptr++; + + /* Parse ACK and set data */ + while(bptr < buffer + len) { + switch(*bptr++) { + case IPCP_IPADDRESS: + ipcp_state |= IPCP_IP_BIT; + bptr += 5; + break; +#ifdef IPCP_GET_PRI_DNS + case IPCP_PRIMARY_DNS: + ipcp_state |= IPCP_PRI_DNS_BIT; + bptr += 5; + break; +#endif +#ifdef IPCP_GET_PRI_DNS + case IPCP_SECONDARY_DNS: + ipcp_state |= IPCP_SEC_DNS_BIT; + bptr += 5; + break; +#endif + default: + DEBUG1(("IPCP this shoudln't happen 3\n")); + } + } + /* expire the timer to make things happen after a state change */ + /*timer_expire(); */ + break; + default: + DEBUG1(("-Unknown 4\n")); + } +} + +/*---------------------------------------------------------------------------*/ +void +ipcp_task(u8_t *buffer) +{ + u8_t *bptr; + u16_t t; + IPCPPKT *pkt; + + /* IPCP tx not up and hasn't timed out then lets see if we need to + send a request */ + if(!(ipcp_state & IPCP_TX_UP) && !(ipcp_state & IPCP_TX_TIMEOUT)) { + /* Check if we have a request pending */ + /*t=get_seconds()-ipcp_tx_time;*/ +#if 0 + if(TIMER_timeout(IPCP_TIMEOUT)) { +#else + if((clock_seconds() - prev_ipcp_seconds) > IPCP_TIMEOUT) { + prev_ipcp_seconds = clock_seconds(); +#endif + + /* + * No pending request, lets build one + */ + pkt=(IPCPPKT *)buffer; + + /* Configure-Request only here, write id */ + pkt->code = CONF_REQ; + pkt->id = ppp_id; + + bptr = pkt->data; + + /* + * Write options, we want IP address, and DNS addresses if set. + */ + + /* Write zeros for IP address the first time */ + *bptr++ = IPCP_IPADDRESS; + *bptr++ = 0x6; + *bptr++ = ((u8_t*)pppif.ipaddr)[0]; + *bptr++ = ((u8_t*)pppif.ipaddr)[1]; + *bptr++ = ((u8_t*)pppif.ipaddr)[2]; + *bptr++ = ((u8_t*)pppif.ipaddr)[3]; + +#ifdef IPCP_GET_PRI_DNS + if(!(ipcp_state & IPCP_PRI_DNS_BIT)) { + /* Write zeros for IP address the first time */ + *bptr++ = IPCP_PRIMARY_DNS; + *bptr++ = 0x6; + *bptr++ = ((u8_t*)pri_dns_addr)[0]; + *bptr++ = ((u8_t*)pri_dns_addr)[1]; + *bptr++ = ((u8_t*)pri_dns_addr)[2]; + *bptr++ = ((u8_t*)pri_dns_addr)[3]; + } +#endif +#ifdef IPCP_GET_SEC_DNS + if(!(ipcp_state & IPCP_SEC_DNS_BIT)) { + /* Write zeros for IP address the first time */ + *bptr++ = IPCP_SECONDARY_DNS; + *bptr++ = 0x6; + *bptr++ = ((u8_t*)sec_dns_addr)[0]; + *bptr++ = ((u8_t*)sec_dns_addr)[1]; + *bptr++ = ((u8_t*)sec_dns_addr)[2]; + *bptr++ = ((u8_t*)sec_dns_addr)[3]; + } +#endif + /* Write length */ + t = bptr - buffer; + /* length here - code and ID + */ + pkt->len = htons(t); + + DEBUG1(("\n**Sending IPCP Request packet\n")); + + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + ahdlc_tx(IPCP, 0, buffer, 0, t); + + /* Set timer */ + /*ipcp_tx_time=get_seconds();*/ + TIMER_set(); + /* Inc retry */ + /*ipcp_retry++;*/ + ppp_retry++; + /* + * Have we timed out? (combide the timers?) + */ + if(ppp_retry > IPCP_RETRY_COUNT) + ipcp_state &= IPCP_TX_TIMEOUT; + } + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ipcp.h b/core/net/ipcp.h new file mode 100644 index 000000000..70d99815d --- /dev/null +++ b/core/net/ipcp.h @@ -0,0 +1,95 @@ +#ifndef __IPCP_H__ +#define __IPCP_H__ +/* www.mycal.com + --------------------------------------------------------------------------- + IPCP.h - Internet Protocol Control Protocol header file + --------------------------------------------------------------------------- + Version + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: ipcp.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ +#include "net/uip.h" +#include "contiki-conf.h" + +/* Config options (move to pppconfig) + #define IPCP_RETRY_COUNT 5 + #define IPCP_TIMEOUT 5 +*/ + +/* IPCP Option Types */ +#define IPCP_IPADDRESS 0x03 +#define IPCP_PRIMARY_DNS 0x81 +#define IPCP_SECONDARY_DNS 0x83 + +/* IPCP state machine flags */ +#define IPCP_TX_UP 0x01 +#define IPCP_RX_UP 0x02 +#define IPCP_IP_BIT 0x04 +#define IPCP_TX_TIMEOUT 0x08 +#define IPCP_PRI_DNS_BIT 0x08 +#define IPCP_SEC_DNS_BIT 0x10 + +typedef struct _ipcp +{ + u8_t code; + u8_t id; + u16_t len; + u8_t data[0]; +} IPCPPKT; + +/* + * Export IP addresses. + */ +#if 0 /* moved to mip.c */ +extern IPAddr our_ipaddr; +extern IPAddr peer_ip_addr; +extern IPAddr pri_dns_addr; +extern IPAddr sec_dns_addr; +#endif + +extern u8_t ipcp_state; + +void ipcp_init(void); +void ipcp_task(u8_t *buffer); +void ipcp_rx(u8_t *, u16_t); + +#endif /* __IPCP_H__ */ + diff --git a/core/net/lcp.c b/core/net/lcp.c new file mode 100644 index 000000000..8818d628d --- /dev/null +++ b/core/net/lcp.c @@ -0,0 +1,463 @@ +/* www.mycal.com + *--------------------------------------------------------------------------- + *lcp.c - Link Configuration Protocol Handler. - - + *--------------------------------------------------------------------------- + *Version - 0.1 Original Version June 3, 2000 - + * + *--------------------------------------------------------------------------- + *- Copyright (C) 2000, Mycal Labs www.mycal.com - - + *--------------------------------------------------------------------------- + * + * +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: lcp.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#include "contiki-conf.h" + +/*#include "time.h"*/ +#include "ppp.h" +#include "ahdlc.h" +#include "lcp.h" + +#if 0 +#define DEBUG1(x) +#define DEBUG2(x) +#else +#include +#define DEBUG1(x) debug_printf x +#define DEBUG2(x) debug_printf x +#endif + +#define TIMER_expire() +#define TIMER_set() +#define TIMER_timeout(x) 1 +static unsigned long prev_lcp_seconds = 0; + + +/*u8_t tflag; +u8_t *lcp_buffer; +u16_t lcp_tx_time; +u8_t lcp_retry; +u16_t lcp_timeout=5;*/ + +u8_t lcp_state; +u16_t ppp_tx_mru = 0; + +/* We need this when we neg our direction. + u8_t lcp_tx_options; */ + +/* + * Define the supported paramets for this module here. + */ +u8_t lcplist[] = { + LPC_MAGICNUMBER, + LPC_PFC, + LPC_ACFC, + LPC_AUTH, + LPC_ACCM, + LPC_MRU, + 0}; + + +/*---------------------------------------------------------------------------*/ +/* lcp_init() - Initialize the LCP engine to startup values */ +/*---------------------------------------------------------------------------*/ +void +lcp_init(void) +{ + lcp_state = 0; + ppp_retry = 0; + TIMER_expire(); +} +/*---------------------------------------------------------------------------*/ +/* lcp_rx() - Receive an LCP packet and process it. + * This routine receives a LCP packet in buffer of length count. + * Process it here, support for CONF_REQ, CONF_ACK, CONF_NACK, CONF_REJ or + * TERM_REQ. + */ +/*---------------------------------------------------------------------------*/ +void +lcp_rx(u8_t *buffer, u16_t count) +{ + u8_t *bptr = buffer, *tptr; + u8_t error = 0; + u8_t id; + u16_t len, j; + + switch(*bptr++) { + case CONF_REQ: /* config request */ + /* parce request and see if we can ACK it */ + id = *bptr++; + len = (*bptr++ << 8); + len |= *bptr++; + /*len -= 2;*/ + DEBUG1(("received [LCP Config Request id %u\n",id)); + if(scan_packet((u16_t)LCP, lcplist, buffer, bptr, (u16_t)(len-4))) { + /* must do the -4 here, !scan packet */ + + DEBUG1((" options were rejected\n")); + } else { + /* lets try to implement what peer wants */ + tptr = bptr = buffer; + bptr += 4; /* skip code, id, len */ + error = 0; + /* first scan for unknown values */ + while(bptr < buffer+len) { + switch(*bptr++) { + case LPC_MRU: /* mru */ + j = *bptr++; + j -= 2; + if(j == 2) { + ppp_tx_mru = ((int)*bptr++) << 8; + ppp_tx_mru |= *bptr++; + DEBUG1((" ",ppp_tx_mru)); + } else { + DEBUG1((" ")); + } + break; + case LPC_ACCM: /* */ + bptr++; /* skip length */ + j = *bptr++; + j += *bptr++; + j += *bptr++; + j += *bptr++; + if(j==0) { + // ok + DEBUG1(("",j)); + //ahdlc_flags |= PPP_TX_ASYNC_MAP; + } else if(j!=0) { + // ok + DEBUG1((", assume 0xffffffff",j)); + } else { + /* + * fail we only support default or all zeros + */ + DEBUG1(("We only support default or all zeros for ACCM ")); + error = 1; + *tptr++ = LPC_ACCM; + *tptr++ = 0x6; + *tptr++ = 0; + *tptr++ = 0; + *tptr++ = 0; + *tptr++ = 0; + } + break; + case LPC_AUTH: + bptr++; + if((*bptr++ == 0xc0) && (*bptr++ == 0x23)) { + /* negotiate PAP */ + if (strlen(pap_username) > 0) { + DEBUG1((" ")); + lcp_state |= LCP_RX_AUTH; + } else { + DEBUG1((" ")); + + *tptr++ = CONF_REJ; + *tptr++; // Keep ID + *tptr++ = 0; + *tptr++ = 8; + *tptr++ = LPC_AUTH; + *tptr++ = 0x4; + *tptr++ = 0xc0; + *tptr++ = 0x23; + ahdlc_tx(LCP, 0, buffer, 0, (u16_t)(tptr-buffer)); + return; + } + } else { + /* we only support PAP */ + DEBUG1(("")); + error = 1; + *tptr++ = LPC_AUTH; + *tptr++ = 0x4; + *tptr++ = 0xc0; + *tptr++ = 0x23; + } + break; + case LPC_MAGICNUMBER: + DEBUG1((" ")); + /* + * Compair incoming number to our number (not implemented) + */ + bptr++; /* for now just dump */ + bptr++; + bptr++; + bptr++; + bptr++; + break; + case LPC_PFC: + bptr++; + DEBUG1((" ")); + /*tflag|=PPP_PFC;*/ + break; + case LPC_ACFC: + bptr++; + DEBUG1((" ")); + /*tflag|=PPP_ACFC;*/ + break; + + } + } + /* Error? if we we need to send a config Reject ++++ this is good for a subroutine */ + if(error) { + /* write the config NAK packet we've built above, take on the header */ + bptr = buffer; + *bptr++ = CONF_NAK; /* Write Conf_rej */ + *bptr++;/*tptr++;*/ /* skip over ID */ + + /* Write new length */ + *bptr++ = 0; + *bptr = tptr - buffer; + + /* write the reject frame */ + DEBUG1(("\nWriting NAK frame \n")); + // Send packet ahdlc_txz(procol,header,data,headerlen,datalen); + ahdlc_tx(LCP, 0, buffer, 0, (u16_t)(tptr-buffer)); + DEBUG1(("- end NAK Write frame\n")); + + } else { + /* + * If we get here then we are OK, lets send an ACK and tell the rest + * of our modules our negotiated config. + */ + DEBUG1(("\nSend ACK!\n")); + bptr = buffer; + *bptr++ = CONF_ACK; /* Write Conf_ACK */ + bptr++; /* Skip ID (send same one) */ + /* + * Set stuff + */ + /*ppp_flags|=tflag;*/ + /* DEBUG2("SET- stuff -- are we up? c=%d dif=%d \n", count, (u16_t)(bptr-buffer)); */ + + /* write the ACK frame */ + DEBUG2(("Writing ACK frame \n")); + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + ahdlc_tx(LCP, 0, buffer, 0, count /*bptr-buffer*/); + DEBUG2(("- end ACK Write frame\n")); + lcp_state |= LCP_RX_UP; + + /* expire the timer to make things happen after a state change */ + /*timer_expire();*/ + + } + } + break; + case CONF_ACK: /* config Ack Anytime we do an ack reset the timer to force send. */ + DEBUG1(("LCP-ACK - ")); + /* check that ID matches one sent */ + if(*bptr++ == ppp_id) { + /* Change state to PPP up. */ + DEBUG1((">>>>>>>> good ACK id up! %d\n",ppp_id)); + /* copy negotiated values over */ + + lcp_state |= LCP_TX_UP; + + /* expire the timer to make things happen after a state change */ + TIMER_expire(); + } + else + DEBUG1(("*************++++++++++ bad id %d\n",ppp_id)); + break; + case CONF_NAK: /* Config Nack */ + DEBUG1(("LCP-CONF NAK\n")); + ppp_id++; + break; + case CONF_REJ: /* Config Reject */ + DEBUG1(("LCP-CONF REJ\n")); + ppp_id++; + break; + case TERM_REQ: /* Terminate Request */ + DEBUG1(("LCP-TERM-REQ -")); + bptr = buffer; + *bptr++ = TERM_ACK; /* Write TERM_ACK */ + /* write the reject frame */ + DEBUG1(("Writing TERM_ACK frame \n")); + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + ahdlc_tx(LCP, 0, buffer, 0, count); + lcp_state &= ~LCP_TX_UP; + lcp_state |= LCP_TERM_PEER; + break; + case TERM_ACK: + DEBUG1(("LCP-TERM ACK\n")); + break; + default: + break; + } +} + + +void lcp_disconnect(u8_t id) { + u8_t buffer[4]; + u8_t *bptr = buffer; + *bptr++ = TERM_REQ; + *bptr++ = id; + *bptr++ = 0; + *bptr++ = 4; + ahdlc_tx(LCP, 0, buffer, 0, bptr - buffer); +} + +/*---------------------------------------------------------------------------*/ +/* lcp_task(buffer) - This routine see if a lcp request needs to be sent + * out. It uses the passed buffer to form the packet. This formed LCP + * request is what we negotiate for sending options on the link. + * + * Currently we negotiate : Magic Number Only, but this will change. + */ +/*---------------------------------------------------------------------------*/ +void +lcp_task(u8_t *buffer) +{ + u8_t *bptr; + u16_t t; + LCPPKT *pkt; + + /* lcp tx not up and hasn't timed out then lets see if we need to send a request */ + if(!(lcp_state & LCP_TX_UP) && !(lcp_state & LCP_TX_TIMEOUT)) { + /* Check if we have a request pending */ + /*t=get_seconds()-lcp_tx_time;*/ +#if 0 + if(1 == TIMER_timeout(LCP_TX_TIMEOUT)) { +#else + if((clock_seconds() - prev_lcp_seconds) > LCP_TIMEOUT) { + prev_lcp_seconds = clock_seconds(); +#endif + DEBUG1(("\nSending LCP request packet - ")); + /* + * No pending request, lets build one + */ + pkt = (LCPPKT *)buffer; + + /* Configure-Request only here, write id */ + pkt->code = CONF_REQ; + pkt->id = ppp_id; + + bptr = pkt->data; + + /* Write options */ + + /* ACCM */ + //if((lcp_tx_options & LCP_OPT_ACCM) & 0) { + *bptr++ = LPC_ACCM; + *bptr++ = 0x6; + *bptr++ = 0xff; + *bptr++ = 0xff; + *bptr++ = 0xff; + *bptr++ = 0xff; + //} + +#if 0 + /* Write magic number */ + DEBUG1(("LPC_MAGICNUMBER -")); + *bptr++ = LPC_MAGICNUMBER; + *bptr++ = 0x6; + /* + *bptr++ = random_rand() & 0xff; + *bptr++ = random_rand() & 0xff; + *bptr++ = random_rand() & 0xff; + *bptr++ = random_rand() & 0xff; + */ + *bptr++ = 0x11; + *bptr++ = 0x11; + *bptr++ = 0x11; + *bptr++ = 0x11; +#endif + +#if 0 + /* + * Authentication protocol + */ + if((lcp_tx_options & LCP_OPT_AUTH) && 0) { + /* + * If turned on, we only negotiate PAP + */ + *bptr++ = LPC_AUTH; + *bptr++ = 0x4; + *bptr++ = 0xc0; + *bptr++ = 0x23; + } + /* + * PFC + */ + if((lcp_tx_options & LCP_OPT_PFC) && 0) { + /* + * If turned on, we only negotiate PAP + */ + *bptr++ = LPC_PFC; + *bptr++ = 0x2; + } + /* + * ACFC + */ + if((lcp_tx_options & LCP_OPT_ACFC) && 0) { + /* + * If turned on, we only negotiate PAP + */ + *bptr++ = LPC_ACFC; + *bptr++ = 0x2; + } +#endif + /* Write length */ + t = bptr - buffer; + pkt->len = htons(t); /* length here - code and ID + */ + + DEBUG1((" len %d\n",t)); + + /* Send packet */ + /* Send packet ahdlc_txz(procol,header,data,headerlen,datalen); */ + ahdlc_tx(LCP, 0, buffer, 0, t); + + /* Set timer */ + TIMER_set(); + /*lcp_tx_time=get_seconds();*/ + /* Inc retry */ + ppp_retry++; + /* + * Have we timed out? + */ + if(ppp_retry > LCP_RETRY_COUNT) { + lcp_state &= LCP_TX_TIMEOUT; + } + } + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/lcp.h b/core/net/lcp.h new file mode 100644 index 000000000..a362b861b --- /dev/null +++ b/core/net/lcp.h @@ -0,0 +1,96 @@ +#ifndef __LCP_H__ +#define __LCP_H__ +/* www.mycal.com + --------------------------------------------------------------------------- + LCP.h - LCP header file + --------------------------------------------------------------------------- + Version - + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: lcp.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +#include "net/uip.h" +#include "contiki-conf.h" + +/* LCP Option Types */ +#define LPC_VENDERX 0x0 +#define LPC_MRU 0x1 +#define LPC_ACCM 0x2 +#define LPC_AUTH 0x3 +#define LPC_QUALITY 0x4 +#define LPC_MAGICNUMBER 0x5 +#define LPC_PFC 0x7 +#define LPC_ACFC 0x8 + +/* LCP Negotiated options flag equates */ +#define LCP_OPT_ACCM 0x1 +#define LCP_OPT_AUTH 0x2 +#define LCP_OPT_PFC 0x4 +#define LCP_OPT_ACFC 0x4 + +/* LCP state machine flags */ +#define LCP_TX_UP 0x1 +#define LCP_RX_UP 0x2 + +#define LCP_RX_AUTH 0x10 +/* LCP request for auth */ +#define LCP_TERM_PEER 0x20 +/* LCP Terminated by peer */ +#define LCP_RX_TIMEOUT 0x40 +#define LCP_TX_TIMEOUT 0x80 + +typedef struct _lcppkt +{ + u8_t code; + u8_t id; + u16_t len; + u8_t data[0]; +} LCPPKT; + +/* Exported Vars */ +extern u8_t lcp_state; + +void lcp_init(void); +void lcp_rx(u8_t *, u16_t); +void lcp_task(u8_t *buffer); +void lcp_disconnect(u8_t id); + +#endif /* __LCP_H__ */ diff --git a/core/net/packet-service.h b/core/net/packet-service.h new file mode 100644 index 000000000..64ef57c88 --- /dev/null +++ b/core/net/packet-service.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: packet-service.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __PACKET_SERVICE_H__ +#define __PACKET_SERVICE_H__ + +#include "contiki.h" + +#define packet_service_name "Packet driver" + +SERVICE_INTERFACE(packet_service, { + u8_t (* output)(void); +}); + +#endif /* __PACKET_SERVICE_H__ */ diff --git a/core/net/pap.c b/core/net/pap.c new file mode 100644 index 000000000..edf5c93d4 --- /dev/null +++ b/core/net/pap.c @@ -0,0 +1,195 @@ +/*www.mycal.net + *--------------------------------------------------------------------------- + *pap.c - PAP processor for the PPP module - - + *--------------------------------------------------------------------------- + *Version - 0.1 Original Version Jun 3, 2000 - - + *--------------------------------------------------------------------------- + *- Copyright (C) 2000, Mycal Labs www.mycal.com - - + *--------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: pap.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + +#include +#include "ppp.h" +#include "pap.h" +#include "lcp.h" + +#if 0 +#define DEBUG1(x) +#else +#include +#define DEBUG1(x) debug_printf x +#endif + +/*#include "time.h"*/ +/*#include "utils.h" */ +#define TIMER_expire() +#define TIMER_set() +#define TIMER_timeout(x) 1 + + +u8_t pap_state; + +#ifdef PAP_USERNAME +u8_t pap_username[] = PAP_USERNAME; +#else +u8_t pap_username[PAP_USERNAME_SIZE]; +#endif + +#ifdef PAP_PASSWORD +u8_t pap_password[] = PAP_PASSWORD; +#else +u8_t pap_password[PAP_PASSWORD_SIZE]; +#endif + +/*u16_t pap_tx_time; + u8_t pap_timeout;*/ + +/*---------------------------------------------------------------------------*/ +void +pap_init(void) +{ + ppp_retry = 0; /* We reuse ppp_retry */ + pap_state = 0; +} +/*---------------------------------------------------------------------------*/ +/* pap_rx() - PAP RX protocol Handler */ +/*---------------------------------------------------------------------------*/ +void +pap_rx(u8_t *buffer, u16_t count) +{ + u8_t *bptr=buffer; + u8_t len; + + switch(*bptr++) { + case CONF_REQ: + DEBUG1(("CONF ACK - only for server, no support\n")); + break; + case CONF_ACK: /* config Ack */ + DEBUG1(("CONF ACK - PAP good - ")); + /* Display message if debug */ + len = *bptr++; + *(bptr + len) = 0; + DEBUG1((" %s \n",bptr)); + pap_state |= PAP_TX_UP; + /* expire the timer to make things happen after a state change */ + TIMER_expire(); + break; + case CONF_NAK: + DEBUG1(("CONF NAK - Failed Auth - ")); + pap_state |= PAP_TX_AUTH_FAIL; + /* display message if debug */ + len = *bptr++; + *(bptr + len)=0; + DEBUG1((" %s \n",bptr)); + break; + } +} +/*---------------------------------------------------------------------------*/ +/* pap_task() - This task needs to be called every so often during the PAP + * negotiation phase. This task sends PAP REQ packets. + */ +/*---------------------------------------------------------------------------*/ +void +pap_task(u8_t *buffer) +{ + u8_t *bptr; + u16_t t; + PAPPKT *pkt; + + /* If LCP is up and PAP negotiated, try to bring up PAP */ + if(!(pap_state & PAP_TX_UP) && !(pap_state & PAP_TX_TIMEOUT)) { + /* Do we need to send a PAP auth packet? + Check if we have a request pending*/ + if(1 == TIMER_timeout(PAP_TIMEOUT)) { + /* Check if we have a request pending */ + /* t=get_seconds()-pap_tx_time; + if( t > pap_timeout) + { + */ + /* We need to send a PAP authentication request */ + DEBUG1(("\nSending PAP Request packet - ")); + + /* Build a PAP request packet */ + pkt = (PAPPKT *)buffer; + + /* Configure-Request only here, write id */ + pkt->code = CONF_REQ; + pkt->id = ppp_id; + bptr = pkt->data; + + /* Write options */ + t = strlen(pap_username); + /* Write peer length */ + *bptr++ = (u8_t)t; + bptr = memcpy(bptr, pap_username, t); + + t = strlen(pap_password); + *bptr++ = (u8_t)t; + bptr = memcpy(bptr, pap_password, t); + + /* Write length */ + t = bptr - buffer; + /* length here - code and ID + */ + pkt->len = htons(t); + + DEBUG1((" Len %d\n",t)); + + /* Send packet */ + ahdlc_tx(PAP, buffer, 0, t, 0); + + /* Set timer */ + TIMER_set(); + + ppp_retry++; + + /* Have we failed? */ + if(ppp_retry > 3) { + DEBUG1(("PAP - timout\n")); + pap_state &= PAP_TX_TIMEOUT; + + } + } + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/pap.h b/core/net/pap.h new file mode 100644 index 000000000..a37bb01e2 --- /dev/null +++ b/core/net/pap.h @@ -0,0 +1,83 @@ +#ifndef __PAP_H__ +#define __PAP_H__ +/* + www.mycal.com + --------------------------------------------------------------------------- + pap.h - pap header file + --------------------------------------------------------------------------- + Version + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- +*/ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: pap.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +#include "net/uip.h" + +/* PAP state machine flags */ +/* client only */ +#define PAP_TX_UP 0x01 +/* server only */ +#define PAP_RX_UP 0x02 + +#define PAP_RX_AUTH_FAIL 0x10 +#define PAP_TX_AUTH_FAIL 0x20 +#define PAP_RX_TIMEOUT 0x80 +#define PAP_TX_TIMEOUT 0x80 + +typedef struct _pappkt { + u8_t code; + u8_t id; + u16_t len; + u8_t data[0]; +} PAPPKT; + +/* Export pap_state */ +extern u8_t pap_state; + +extern u8_t pap_username[]; +extern u8_t pap_password[]; + +/* Function prototypes */ +void pap_init(void); +void pap_rx(u8_t *, u16_t); +void pap_task(u8_t *buffer); + +#endif /* __PAP_H__ */ + diff --git a/core/net/ppp-service.c b/core/net/ppp-service.c new file mode 100644 index 000000000..9acba222e --- /dev/null +++ b/core/net/ppp-service.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: ppp-service.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#if 0 +#include "net/packet-service.h" +#include "ppp.h" + +static void output(u8_t *hdr, u16_t hdrlen, u8_t *data, u16_t datalen); + +static const struct packet_service_state state = + { + PACKET_SERVICE_VERSION, + output + }; + +EK_EVENTHANDLER(eventhandler, ev, data); +EK_POLLHANDLER(pollhandler); +EK_PROCESS(proc, PACKET_SERVICE_NAME, EK_PRIO_NORMAL, + eventhandler, pollhandler, (void *)&state); + +/*---------------------------------------------------------------------------*/ +EK_PROCESS_INIT(ppp_service_init, arg) +{ + ek_service_start(PACKET_SERVICE_NAME, &proc); +} +/*---------------------------------------------------------------------------*/ +static void +output(u8_t *hdr, u16_t hdrlen, u8_t *data, u16_t datalen) +{ + ppp_send(); +} +/*---------------------------------------------------------------------------*/ +EK_EVENTHANDLER(eventhandler, ev, data) +{ + switch(ev) { + case EK_EVENT_INIT: + case EK_EVENT_REPLACE: +// ppp_init(); + break; + case EK_EVENT_REQUEST_REPLACE: + ek_replace((struct ek_proc *)data, NULL); + LOADER_UNLOAD(); + break; + case EK_EVENT_REQUEST_EXIT: + ek_exit(); + LOADER_UNLOAD(); + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +EK_POLLHANDLER(pollhandler) +{ + ppp_poll(); + if(uip_len > 0) { + tcpip_input(); + } +} +/*---------------------------------------------------------------------------*/ +#endif diff --git a/core/net/ppp.c b/core/net/ppp.c new file mode 100644 index 000000000..bdb68d91c --- /dev/null +++ b/core/net/ppp.c @@ -0,0 +1,440 @@ +/* + *--------------------------------------------------------------------------- + * ppp.c - PPP Processor/Handler - + * - + *--------------------------------------------------------------------------- + * + * Version - + * 0.1 Original Version Jun 3, 2000 - + * - + *--------------------------------------------------------------------------- + */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: ppp.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* */ +/* include files */ +/* */ + + +#include "lcp.h" +#include "pap.h" +#include "ipcp.h" +/*#include "time.h"*/ +/*#include "mip.h"*/ + +#if 0 +#define DEBUG1(x) +#else +#include +#define DEBUG1(x) debug_printf x +#endif + +/* + Set the debug message level +*/ +#define PACKET_RX_DEBUG 1 + +/* + Include stuff +*/ +/*#include "mTypes.h"*/ +#include "ppp.h" +#include "ahdlc.h" +#include "ipcp.h" +#include "lcp.h" + +extern int ppp_arch_getchar(u8_t *p); + + +/* + Buffers that this layer needs (this can be optimized out) +*/ +u8_t ppp_rx_buffer[PPP_RX_BUFFER_SIZE]; +/*u8_t ppp_tx_buffer[PPP_TX_BUFFER_SIZE];*/ + +/* + * Other state storage (this can be placed in a struct and this could could + * support multiple PPP connections, would have to embedded the other ppp + * module state also) + */ +u8_t ppp_flags; +u8_t ppp_id; +u8_t ppp_retry; + +#if PACKET_RX_DEBUG +u16_t ppp_rx_frame_count=0; +u16_t ppp_rx_tobig_error; +u8_t done; /* temporary variable */ +#endif + +/*---------------------------------------------------------------------------*/ +static u8_t +check_ppp_errors(void) +{ + u8_t ret = 0; + + /* Check Errors */ + if(lcp_state & LCP_TX_TIMEOUT) { + ret = 1; + } + if(lcp_state & LCP_RX_TIMEOUT) { + ret = 2; + } + + if(pap_state & PAP_TX_AUTH_FAIL) { + ret = 3; + } + if(pap_state & PAP_RX_AUTH_FAIL) { + ret = 4; + } + + if(pap_state & PAP_TX_TIMEOUT) { + ret = 5; + } + if(pap_state & PAP_RX_TIMEOUT) { + ret = 6; + } + + if(ipcp_state & IPCP_TX_TIMEOUT) { + ret = 7; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +/* + * Unknown Protocol Handler, sends reject + */ +static void +ppp_reject_protocol(u16_t protocol, u8_t *buffer, u16_t count) +{ + u16_t i; + u8_t *dptr, *sptr; + LCPPKT *pkt; + + /* first copy rejected packet back, start from end and work forward, + +++ Pay attention to buffer managment when updated. Assumes fixed + PPP blocks. */ + DEBUG1(("Rejecting Protocol\n")); + if((count + 6) > PPP_RX_BUFFER_SIZE) { + /* This is a fatal error +++ do somthing about it. */ + DEBUG1(("Cannot Reject Protocol, PKT to big\n")); + return; + } + dptr = buffer + count + 6; + sptr = buffer + count; + for(i = 0; i < count; ++i) { + *dptr-- = *sptr--; + } + + pkt = (LCPPKT *)buffer; + pkt->code = PROT_REJ; /* Write Conf_rej */ + /*pkt->id = tid++;*/ /* write tid */ + pkt->len = htons(count + 6); + *((u16_t *)(&pkt->data[0])) = htons(protocol); + + ahdlc_tx(LCP, buffer, 0, (u16_t)(count + 6), 0); +} +/*---------------------------------------------------------------------------*/ +#if PACKET_RX_DEBUG +void +dump_ppp_packet(u8_t *buffer, u16_t len) +{ + int i; + + DEBUG1(("\n")); + for(i = 0;i < len; ++i) { + if((i & 0x1f) == 0x10) { + DEBUG1(("\n")); + } + DEBUG1(("0x%02x ",buffer[i])); + } + DEBUG1(("\n\n")); +} +#endif +/*---------------------------------------------------------------------------*/ +/* Initialize and start PPP engine. This just sets things up to + * starting values. This can stay a private method. + */ +/*---------------------------------------------------------------------------*/ +void +ppp_init() +{ +#if PACKET_RX_DEBUG + ppp_rx_frame_count = 0; + done = 0; +#endif + ppp_flags = 0; + pap_init(); + ipcp_init(); + lcp_init(); + ppp_flags = 0; + + ahdlc_init(ppp_rx_buffer, PPP_RX_BUFFER_SIZE); + ahdlc_rx_ready(); +} +/*---------------------------------------------------------------------------*/ +/* raise_ppp() - This routine will try to bring up a PPP connection, + * It is blocking. In the future we probably want to pass a + * structure with all the options on bringing up a PPP link, like + * server/client, DSN server, username password for PAP... +++ for + * now just use config and bit defines + */ +/*---------------------------------------------------------------------------*/ +#if 0 +u16_t +ppp_raise(u8_t config, u8_t *username, u8_t *password) +{ + u16_t status = 0; + + /* Initialize PPP engine */ + /* init_ppp(); */ + pap_init(); + ipcp_init(); + lcp_init(); + + /* Enable PPP */ + ppp_flags = PPP_RX_READY; + + /* Try to bring up the layers */ + while(status == 0) { +#ifdef SYSTEM_POLLER + /* If the the serial interrupt is not hooked to ahdlc_rx, or the + system needs to handle other stuff while were blocking, call + the system poller.*/ + system_poller(); +#endif + + /* call the lcp task to bring up the LCP layer */ + lcp_task(ppp_tx_buffer); + + /* If LCP is up, neg next layer */ + if(lcp_state & LCP_TX_UP) { + /* If LCP wants PAP, try to authenticate, else bring up IPCP */ + if((lcp_state & LCP_RX_AUTH) && (!(pap_state & PAP_TX_UP))) { + pap_task(ppp_tx_buffer,username,password); + } else { + ipcp_task(ppp_tx_buffer); + } + } + + + /* If IPCP came up then our link should be up. */ + if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) { + break; + } + + status = check_ppp_errors(); + } + + return status; +} +#endif +/*---------------------------------------------------------------------------*/ +void +ppp_connect(void) +{ + /* Initialize PPP engine */ + /* init_ppp(); */ + pap_init(); + ipcp_init(); + lcp_init(); + + /* Enable PPP */ + ppp_flags = PPP_RX_READY; +} +/*---------------------------------------------------------------------------*/ +void +ppp_send(void) +{ + /* If IPCP came up then our link should be up. */ + if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) { + ahdlc_tx(IPV4, &uip_buf[ UIP_LLH_LEN ], uip_appdata, + UIP_TCPIP_HLEN, uip_len - UIP_TCPIP_HLEN); + } +} +/*---------------------------------------------------------------------------*/ +void +ppp_poll(void) +{ + u8_t c; + + uip_len = 0; + + if(!(ppp_flags & PPP_RX_READY)) { + return; + } + + while(uip_len == 0 && ppp_arch_getchar(&c)) { + ahdlc_rx(c); + } + + /* If IPCP came up then our link should be up. */ + if((ipcp_state & IPCP_TX_UP) && (ipcp_state & IPCP_RX_UP)) { + return; + } + + /* call the lcp task to bring up the LCP layer */ + lcp_task( &uip_buf[ UIP_LLH_LEN ]); + + /* If LCP is up, neg next layer */ + if((lcp_state & LCP_TX_UP) && (lcp_state & LCP_RX_UP)) { + /* If LCP wants PAP, try to authenticate, else bring up IPCP */ + if((lcp_state & LCP_RX_AUTH) && (!(pap_state & PAP_TX_UP))) { + pap_task( &uip_buf[ UIP_LLH_LEN ]); + } else { + ipcp_task( &uip_buf[ UIP_LLH_LEN ]); + } + } +} +/*---------------------------------------------------------------------------*/ +/* ppp_upcall() - this is where valid PPP frames from the ahdlc layer are + * sent to be processed and demuxed. + */ +/*---------------------------------------------------------------------------*/ +void +ppp_upcall(u16_t protocol, u8_t *buffer, u16_t len) +{ +#if PACKET_RX_DEBUG + ++ppp_rx_frame_count; + dump_ppp_packet(buffer, len); + if(ppp_rx_frame_count > 18) { + done = 1; + } +#endif + + /* check to see if we have a packet waiting to be processed */ + if(ppp_flags & PPP_RX_READY) { + /* demux on protocol field */ + switch(protocol) { + case LCP: /* We must support some level of LCP */ + DEBUG1(("LCP Packet - ")); + lcp_rx(buffer, len); + DEBUG1(("\n")); + break; + case PAP: /* PAP should be compile in optional */ + DEBUG1(("PAP Packet - ")); + pap_rx(buffer, len); + DEBUG1(("\n")); + break; + case IPCP: /* IPCP should be compile in optional. */ + DEBUG1(("IPCP Packet - ")); + ipcp_rx(buffer, len); + DEBUG1(("\n")); + break; + case IPV4: /* We must support IPV4 */ + DEBUG1(("IPV4 Packet---\n")); + memcpy( &uip_buf[ UIP_LLH_LEN ], buffer, len); + uip_len = len; + DEBUG1(("\n")); + break; + default: + DEBUG1(("Unknown PPP Packet Type 0x%04x - ",protocol)); + ppp_reject_protocol(protocol, buffer, len); + DEBUG1(("\n")); + break; + } + } +} +/*---------------------------------------------------------------------------*/ +/* scan_packet(list,buffer,len) + * + * list = list of supported ID's + * *buffer pointer to the first code in the packet + * length of the codespace + */ +u16_t +scan_packet(u16_t protocol, u8_t *list, u8_t *buffer, u8_t *options, u16_t len) +{ + u8_t *tlist, *bptr; + u8_t *tptr; + u8_t bad = 0; + u8_t i, j, good; + + bptr = tptr = options; + /* scan through the packet and see if it has any unsupported codes */ + while(bptr < options + len) { + /* get code and see if it matches somwhere in the list, if not + we don't support it */ + i = *bptr++; + + /* DEBUG2("%x - ",i);*/ + tlist = list; + good = 0; + while(*tlist) { + /* DEBUG2("%x ",*tlist);*/ + if(i == *tlist++) { + good = 1; + break; + } + } + if(!good) { + /* we don't understand it, write it back */ + DEBUG1(("We don't understand option 0x%02x\n",i)); + bad = 1; + *tptr++ = i; + j = *tptr++ = *bptr++; + for(i = 0; i < j - 2; ++i) { + *tptr++ = *bptr++; + } + } else { + /* advance over to next option */ + bptr += *bptr - 1; + } + } + + /* Bad? if we we need to send a config Reject */ + if(bad) { + /* write the config Rej packet we've built above, take on the header */ + bptr = buffer; + *bptr++ = CONF_REJ; /* Write Conf_rej */ + bptr++; /* skip over ID */ + *bptr++ = 0; + *bptr = tptr - buffer; + /* length right here? */ + + /* write the reject frame */ + DEBUG1(("Writing Reject frame --\n")); + ahdlc_tx(protocol, buffer, 0, (u16_t)(tptr - buffer), 0); + DEBUG1(("\nEnd writing reject \n")); + + } + return bad; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ppp.h b/core/net/ppp.h new file mode 100644 index 000000000..a44d126f0 --- /dev/null +++ b/core/net/ppp.h @@ -0,0 +1,132 @@ +#ifndef __PPP_H__ +#define __PPP_H__ +/* www.mycal.net +--------------------------------------------------------------------------- + ppp.h - ppp header file +--------------------------------------------------------------------------- + Version + 0.1 Original Version June 3, 2000 + (c)2000 Mycal Labs, All Rights Reserved + --------------------------------------------------------------------------- */ +/* + * Copyright (c) 2003, Mike Johnson, Mycal Labs, www.mycal.net + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mike Johnson/Mycal Labs + * www.mycal.net. + * 4. 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 Mycal Modified uIP TCP/IP stack. + * + * $Id: ppp.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ +#include "net/uip.h" +#include "net/uip-fw.h" +#include "contiki-conf.h" +#include "ahdlc.h" +#include "lcp.h" +#include "ipcp.h" +#include "pap.h" +#include "ppp_arch.h" +#include "ppp_process.h" +/*#include "mip.h"*/ + +/* moved to pppconfig.h +#define PPP_RX_BUFFER_SIZE 1024 +#define PPP_TX_BUFFER_SIZE 64*/ + +#define CRC_GOOD_VALUE 0xf0b8 + +/* ppp_rx_status values */ +#define PPP_RX_IDLE 0 +#define PPP_READY 1 + +/* ppp flags */ +#define PPP_ESCAPED 0x1 +#define PPP_RX_READY 0x2 +#define PPP_RX_ASYNC_MAP 0x8 +#define PPP_TX_ASYNC_MAP 0x8 +#define PPP_PFC 0x10 +#define PPP_ACFC 0x20 + +/* Supported PPP Protocols */ +#define LCP 0xc021 +#define PAP 0xc023 +#define IPCP 0x8021 +#define IPV4 0x0021 + +/* LCP codes packet types */ +#define CONF_REQ 0x1 +#define CONF_ACK 0x2 +#define CONF_NAK 0x3 +#define CONF_REJ 0x4 +#define TERM_REQ 0x5 +#define TERM_ACK 0x6 +#define PROT_REJ 0x8 + +/* Raise PPP config bits */ +#define USE_PAP 0x1 +#define USE_NOACCMBUG 0x2 +#define USE_GETDNS 0x4 + +#define ppp_setusername(un) strncpy(pap_username, (un), PAP_USERNAME_SIZE) +#define ppp_setpassword(pw) strncpy(pap_password, (pw), PAP_PASSWORD_SIZE) + +/* + * Export Variables + */ +/*extern u8_t ppp_tx_buffer[PPP_TX_BUFFER_SIZE];*/ +extern u8_t ppp_rx_buffer[]; +extern u8_t ppp_rx_count; + +extern struct uip_fw_netif pppif; + +/*extern u16_t ppp_crc_error;*/ + +extern u8_t ppp_flags; +extern u8_t ppp_status; +/*extern u16_t ppp_rx_crc; */ +extern u16_t ppp_rx_tobig_error; +extern u8_t ppp_lcp_state; + +extern u8_t ppp_id; +extern u8_t ppp_retry; + +/* + * Function Prototypes + */ +void ppp_init(void); +void ppp_connect(void); + +void ppp_send(void); +void ppp_poll(void); + +void ppp_upcall(u16_t, u8_t *, u16_t); +u16_t scan_packet(u16_t, u8_t *list, u8_t *buffer, u8_t *options, u16_t len); + +#endif /* __PPP_H__ */ diff --git a/core/net/ppp_process.c b/core/net/ppp_process.c new file mode 100644 index 000000000..e941b87fe --- /dev/null +++ b/core/net/ppp_process.c @@ -0,0 +1,234 @@ +/* + * $Id: ppp_process.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include "contiki.h" +#include "contiki-net.h" +#include "net/ppp/ppp.h" + +PROCESS(ppp_process, "PPP"); + +//----------------------------------------------------------------------------- +// Note, that the UART RX-FIFO must be polled often enough so we don't get an +// overrun at the used baudrate. +//----------------------------------------------------------------------------- +#define PPP_POLL_INTERVAL (CLOCK_SECOND / 256) +#define AT_TIMEOUT (2 * CLOCK_SECOND / PPP_POLL_INTERVAL) +#define AT_RX_BUF 64 + +enum { + AT_CONNECT_DIRECT, + AT_CONNECT_AUTO, + AT_CONNECT_MANUAL +} At_connect; + +enum { + AT_IDLE, + AT_CONNECT, + AT_CONNECT1, + AT_CONNECT2, + AT_CONNECTED, + AT_RESET, + AT_RESET1, + AT_RESET2, + AT_RESET3, + AT_RESET4, + AT_RESET5 +}; + +static struct etimer pppTimer; +static u8_t at_state; +static u8_t at_connect_mode = AT_CONNECT_MODE; +static int at_timeout = -1; +static u8_t at_rxBuf[ AT_RX_BUF ]; + + +static void +at_puts(char *s) { + while(*s) { + ppp_arch_putchar(*s); + s++; + } +} + + +static u8_t +*at_gets() { + static u8_t consumed; + int len; + int i; + + if (consumed) { + consumed = 0; + at_rxBuf[0] = 0; + } + len = strlen(at_rxBuf); + + for (i=len; i reset the buf + at_rxBuf[0] = 0; + return NULL; +} + + +static void +at_poll() { + + static u8_t loopCnt = 0; + u8_t *s; + + if (at_timeout > 0) { + at_timeout--; + } + + if (at_state == AT_CONNECTED) { + ppp_poll(); + if(uip_len > 0) { + tcpip_input(); + } + + if (loopCnt++ > 16) { + int i; + loopCnt = 0; + for (i=0; i 0) { + tcpip_output(); + } + } + } + } else { + + switch (at_state) { + + case AT_IDLE: + switch (at_connect_mode) { + + case AT_CONNECT_DIRECT: + at_state = AT_CONNECTED; + ppp_connect(); + break; + + case AT_CONNECT_AUTO: + at_state = AT_CONNECT; + break; + } + break; + + case AT_CONNECT: + at_gets(); // make the input buffer empty + at_puts("ATE1\r\n"); + at_state = AT_CONNECT1; + at_timeout = AT_TIMEOUT; + break; + + case AT_CONNECT1: + if (at_timeout == 0) { + at_state = AT_RESET; + } else if ((s=at_gets())) { + if (strcmp(s,"OK\r\n") == 0) { + at_puts("AT+CGDCONT=1,\"IP\",\"online.telia.se\",\"\",0,0\r\n"); + at_timeout = AT_TIMEOUT; + at_state = AT_CONNECT2; + } + } + break; + + case AT_CONNECT2: + if (at_timeout == 0) { + at_state = AT_RESET; + } else if ((s=at_gets())) { + if (strcmp(s,"OK\r\n") == 0) { + at_puts("ATD*99***1#\r\n"); + at_state = AT_CONNECTED; + ppp_connect(); + } + } + break; + + case AT_RESET: +//printf("AT_RESET\n"); + at_timeout = AT_TIMEOUT; + at_state = AT_RESET1; + break; + + case AT_RESET1: + if (at_timeout == 0) { + lcp_disconnect(random_rand() & 0xff); + at_timeout = AT_TIMEOUT; + at_state = AT_RESET2; + } + break; + + case AT_RESET2: + if (at_timeout == 0) { + lcp_disconnect(random_rand() & 0xff); + at_timeout = AT_TIMEOUT; + at_state = AT_RESET3; + } + break; + + case AT_RESET3: + if (at_timeout == 0) { + at_puts("+++"); + at_timeout = AT_TIMEOUT; + at_state = AT_RESET4; + } + break; + + case AT_RESET4: + if (at_timeout == 0) { + at_puts("ATZ\r\n"); + at_timeout = AT_TIMEOUT; + at_state = AT_RESET5; + } + break; + + case AT_RESET5: + at_gets(); // make the input buffer empty + if (at_timeout == 0) { + at_state = AT_IDLE; + } + break; + } + } +} + +void ppp_reconnect() { + at_state = AT_RESET; + uip_fw_unregister(&pppif); +} + + +PROCESS_THREAD(ppp_process, ev, data) +{ + PROCESS_BEGIN(); + + at_state = AT_IDLE; + at_rxBuf[0] = 0; + + ppp_init(); + etimer_set(&pppTimer, PPP_POLL_INTERVAL); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); + + if(etimer_expired(&pppTimer)) { + etimer_set(&pppTimer, PPP_POLL_INTERVAL); + at_poll(); + } + } + + PROCESS_END(); +} diff --git a/core/net/ppp_process.h b/core/net/ppp_process.h new file mode 100644 index 000000000..57d1b45a9 --- /dev/null +++ b/core/net/ppp_process.h @@ -0,0 +1,3 @@ +#include "contiki.h" + +PROCESS_NAME(ppp_process); diff --git a/core/net/psock.c b/core/net/psock.c new file mode 100644 index 000000000..27257f8ef --- /dev/null +++ b/core/net/psock.c @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: psock.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include +#include + +#include "net/psock.h" + +#define STATE_NONE 0 +#define STATE_ACKED 1 +#define STATE_READ 2 +#define STATE_BLOCKED_NEWDATA 3 +#define STATE_BLOCKED_CLOSE 4 +#define STATE_BLOCKED_SEND 5 +#define STATE_DATA_SENT 6 + +/* + * Return value of the buffering functions that indicates that a + * buffer was not filled by incoming data. + * + */ +#define BUF_NOT_FULL 0 +#define BUF_NOT_FOUND 0 + +/* + * Return value of the buffering functions that indicates that a + * buffer was completely filled by incoming data. + * + */ +#define BUF_FULL 1 + +/* + * Return value of the buffering functions that indicates that an + * end-marker byte was found. + * + */ +#define BUF_FOUND 2 + +/*---------------------------------------------------------------------------*/ +static void +buf_setup(struct psock_buf *buf, + u8_t *bufptr, u16_t bufsize) +{ + buf->ptr = bufptr; + buf->left = bufsize; +} +/*---------------------------------------------------------------------------*/ +static u8_t +buf_bufdata(struct psock_buf *buf, u16_t len, + u8_t **dataptr, u16_t *datalen) +{ + if(*datalen < buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left -= *datalen; + *dataptr += *datalen; + *datalen = 0; + return BUF_NOT_FULL; + } else if(*datalen == buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left = 0; + *dataptr += *datalen; + *datalen = 0; + return BUF_FULL; + } else { + memcpy(buf->ptr, *dataptr, buf->left); + buf->ptr += buf->left; + *datalen -= buf->left; + *dataptr += buf->left; + buf->left = 0; + return BUF_FULL; + } +} +/*---------------------------------------------------------------------------*/ +static u8_t +buf_bufto(register struct psock_buf *buf, u8_t endmarker, + register u8_t **dataptr, register u16_t *datalen) +{ + u8_t c; + while(buf->left > 0 && *datalen > 0) { + c = *buf->ptr = **dataptr; + ++*dataptr; + ++buf->ptr; + --*datalen; + --buf->left; + + if(c == endmarker) { + return BUF_FOUND; + } + } + + if(*datalen == 0) { + return BUF_NOT_FOUND; + } + + while(*datalen > 0) { + c = **dataptr; + --*datalen; + ++*dataptr; + + if(c == endmarker) { + return BUF_FOUND | BUF_FULL; + } + } + + return BUF_FULL; +} +/*---------------------------------------------------------------------------*/ +static char +send_data(register struct psock *s) +{ + if(s->state != STATE_DATA_SENT || uip_rexmit()) { + if(s->sendlen > uip_mss()) { + uip_send(s->sendptr, uip_mss()); + } else { + uip_send(s->sendptr, s->sendlen); + } + s->state = STATE_DATA_SENT; + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static char +data_acked(register struct psock *s) +{ + if(s->state == STATE_DATA_SENT && uip_acked()) { + if(s->sendlen > uip_mss()) { + s->sendlen -= uip_mss(); + s->sendptr += uip_mss(); + } else { + s->sendptr += s->sendlen; + s->sendlen = 0; + } + s->state = STATE_ACKED; + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_send(register struct psock *s, const char *buf, + unsigned int len)) +{ + PT_BEGIN(&s->psockpt); + + /* If there is no data to send, we exit immediately. */ + if(len == 0) { + PT_EXIT(&s->psockpt); + } + + /* Save the length of and a pointer to the data that is to be + sent. */ + s->sendptr = buf; + s->sendlen = len; + + s->state = STATE_NONE; + + /* We loop here until all data is sent. The s->sendlen variable is + updated by the data_sent() function. */ + while(s->sendlen > 0) { + + /* + * The condition for this PT_WAIT_UNTIL is a little tricky: the + * protothread will wait here until all data has been acknowledged + * (data_acked() returns true) and until all data has been sent + * (send_data() returns true). The two functions data_acked() and + * send_data() must be called in succession to ensure that all + * data is sent. Therefore the & operator is used instead of the + * && operator, which would cause only the data_acked() function + * to be called when it returns false. + */ + PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); + } + + s->state = STATE_NONE; + + PT_END(&s->psockpt); +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_generator_send(register struct psock *s, + unsigned short (*generate)(void *), void *arg)) +{ + PT_BEGIN(&s->psockpt); + + /* Ensure that there is a generator function to call. */ + if(generate == NULL) { + PT_EXIT(&s->psockpt); + } + + /* Call the generator function to generate the data in the + uip_appdata buffer. */ + s->sendlen = generate(arg); + s->sendptr = uip_appdata; + + s->state = STATE_NONE; + do { + /* Call the generator function again if we are called to perform a + retransmission. */ + if(uip_rexmit()) { + generate(arg); + } + /* Wait until all data is sent and acknowledged. */ + PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s)); + } while(s->sendlen > 0); + + s->state = STATE_NONE; + + PT_END(&s->psockpt); +} +/*---------------------------------------------------------------------------*/ +u16_t +psock_datalen(struct psock *psock) +{ + return psock->bufsize - psock->buf.left; +} +/*---------------------------------------------------------------------------*/ +char +psock_newdata(struct psock *s) +{ + if(s->readlen > 0) { + /* There is data in the uip_appdata buffer that has not yet been + read with the PSOCK_READ functions. */ + return 1; + } else if(s->state == STATE_READ) { + /* All data in uip_appdata buffer already consumed. */ + s->state = STATE_BLOCKED_NEWDATA; + return 0; + } else if(uip_newdata()) { + /* There is new data that has not been consumed. */ + return 1; + } else { + /* There is no new data. */ + return 0; + } +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_readto(register struct psock *psock, unsigned char c)) +{ + PT_BEGIN(&psock->psockpt); + + buf_setup(&psock->buf, psock->bufptr, psock->bufsize); + + /* XXX: Should add buf_checkmarker() before do{} loop, if + incoming data has been handled while waiting for a write. */ + + do { + if(psock->readlen == 0) { + PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); + psock->state = STATE_READ; + psock->readptr = (u8_t *)uip_appdata; + psock->readlen = uip_datalen(); + } + } while((buf_bufto(&psock->buf, c, + &psock->readptr, + &psock->readlen) & BUF_FOUND) == 0); + + if(psock_datalen(psock) == 0) { + psock->state = STATE_NONE; + PT_RESTART(&psock->psockpt); + } + PT_END(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ +PT_THREAD(psock_readbuf(register struct psock *psock)) +{ + PT_BEGIN(&psock->psockpt); + + buf_setup(&psock->buf, psock->bufptr, psock->bufsize); + + /* XXX: Should add buf_checkmarker() before do{} loop, if + incoming data has been handled while waiting for a write. */ + + do { + if(psock->readlen == 0) { + PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock)); + printf("Waited for newdata\n"); + psock->state = STATE_READ; + psock->readptr = (u8_t *)uip_appdata; + psock->readlen = uip_datalen(); + } + } while(buf_bufdata(&psock->buf, psock->bufsize, + &psock->readptr, + &psock->readlen) != BUF_FULL); + + if(psock_datalen(psock) == 0) { + psock->state = STATE_NONE; + PT_RESTART(&psock->psockpt); + } + PT_END(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ +void +psock_init(register struct psock *psock, char *buffer, unsigned int buffersize) +{ + psock->state = STATE_NONE; + psock->readlen = 0; + psock->bufptr = buffer; + psock->bufsize = buffersize; + buf_setup(&psock->buf, buffer, buffersize); + PT_INIT(&psock->pt); + PT_INIT(&psock->psockpt); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/psock.h b/core/net/psock.h new file mode 100644 index 000000000..97572aabd --- /dev/null +++ b/core/net/psock.h @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: psock.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +/** + * \addtogroup net + * @{ + */ + +/** + * \defgroup psock Protosockets library + * @{ + * + * The protosocket library provides an interface to the uIP stack that is + * similar to the traditional BSD socket interface. Unlike programs + * written for the ordinary uIP event-driven interface, programs + * written with the protosocket library are executed in a sequential + * fashion and does not have to be implemented as explicit state + * machines. + * + * Protosockets only work with TCP connections. + * + * The protosocket library uses \ref pt protothreads to provide + * sequential control flow. This makes the protosockets lightweight in + * terms of memory, but also means that protosockets inherits the + * functional limitations of protothreads. Each protosocket lives only + * within a single function block. Automatic variables (stack + * variables) are not necessarily retained across a protosocket + * library function call. + * + * \note Because the protosocket library uses protothreads, local variables + * will not always be saved across a call to a protosocket library + * function. It is therefore advised that local variables are used + * with extreme care. + * + * The protosocket library provides functions for sending data without + * having to deal with retransmissions and acknowledgements, as well + * as functions for reading data without having to deal with data + * being split across more than one TCP segment. + * + * Because each protosocket runs as a protothread, the protosocket has to be + * started with a call to PSOCK_BEGIN() at the start of the function + * in which the protosocket is used. Similarly, the protosocket protothread can + * be terminated by a call to PSOCK_EXIT(). + * + */ + +/** + * \file + * Protosocket library header file + * \author + * Adam Dunkels + * + */ + +#ifndef __PSOCK_H__ +#define __PSOCK_H__ + +#include "contiki.h" +#include "contiki-lib.h" +#include "contiki-net.h" + + /* + * The structure that holds the state of a buffer. + * + * This structure holds the state of a uIP buffer. The structure has + * no user-visible elements, but is used through the functions + * provided by the library. + * + */ +struct psock_buf { + u8_t *ptr; + unsigned short left; +}; + +/** + * The representation of a protosocket. + * + * The protosocket structrure is an opaque structure with no user-visible + * elements. + */ +struct psock { + struct pt pt, psockpt; /* Protothreads - one that's using the psock + functions, and one that runs inside the + psock functions. */ + const u8_t *sendptr; /* Pointer to the next data to be sent. */ + u8_t *readptr; /* Pointer to the next data to be read. */ + + char *bufptr; /* Pointer to the buffer used for buffering + incoming data. */ + + u16_t sendlen; /* The number of bytes left to be sent. */ + u16_t readlen; /* The number of bytes left to be read. */ + + struct psock_buf buf; /* The structure holding the state of the + input buffer. */ + unsigned int bufsize; /* The size of the input buffer. */ + + unsigned char state; /* The state of the protosocket. */ +}; + +void psock_init(struct psock *psock, char *buffer, unsigned int buffersize); +/** + * Initialize a protosocket. + * + * This macro initializes a protosocket and must be called before the + * protosocket is used. The initialization also specifies the input buffer + * for the protosocket. + * + * \param psock (struct psock *) A pointer to the protosocket to be + * initialized + * + * \param buffer (char *) A pointer to the input buffer for the + * protosocket. + * + * \param buffersize (unsigned int) The size of the input buffer. + * + * \hideinitializer + */ +#define PSOCK_INIT(psock, buffer, buffersize) \ + psock_init(psock, buffer, buffersize) + +/** + * Start the protosocket protothread in a function. + * + * This macro starts the protothread associated with the protosocket and + * must come before other protosocket calls in the function it is used. + * + * \param psock (struct psock *) A pointer to the protosocket to be + * started. + * + * \hideinitializer + */ +#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt)) + +PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len)); +/** + * Send data. + * + * This macro sends data over a protosocket. The protosocket protothread blocks + * until all data has been sent and is known to have been received by + * the remote end of the TCP connection. + * + * \param psock (struct psock *) A pointer to the protosocket over which + * data is to be sent. + * + * \param data (char *) A pointer to the data that is to be sent. + * + * \param datalen (unsigned int) The length of the data that is to be + * sent. + * + * \hideinitializer + */ +#define PSOCK_SEND(psock, data, datalen) \ + PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen)) + +/** + * \brief Send a null-terminated string. + * \param psock Pointer to the protosocket. + * \param str The string to be sent. + * + * This function sends a null-terminated string over the + * protosocket. + * + * \hideinitializer + */ +#define PSOCK_SEND_STR(psock, str) \ + PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str))) + +PT_THREAD(psock_generator_send(struct psock *psock, + unsigned short (*f)(void *), void *arg)); + +/** + * \brief Generate data with a function and send it + * \param psock Pointer to the protosocket. + * \param generator Pointer to the generator function + * \param arg Argument to the generator function + * + * This function generates data and sends it over the + * protosocket. This can be used to dynamically generate + * data for a transmission, instead of generating the data + * in a buffer beforehand. This function reduces the need for + * buffer memory. The generator function is implemented by + * the application, and a pointer to the function is given + * as an argument with the call to PSOCK_GENERATOR_SEND(). + * + * The generator function should place the generated data + * directly in the uip_appdata buffer, and return the + * length of the generated data. The generator function is + * called by the protosocket layer when the data first is + * sent, and once for every retransmission that is needed. + * + * \hideinitializer + */ +#define PSOCK_GENERATOR_SEND(psock, generator, arg) \ + PT_WAIT_THREAD(&((psock)->pt), \ + psock_generator_send(psock, generator, arg)) + + +/** + * Close a protosocket. + * + * This macro closes a protosocket and can only be called from within the + * protothread in which the protosocket lives. + * + * \param psock (struct psock *) A pointer to the protosocket that is to + * be closed. + * + * \hideinitializer + */ +#define PSOCK_CLOSE(psock) uip_close() + +PT_THREAD(psock_readbuf(struct psock *psock)); +/** + * Read data until the buffer is full. + * + * This macro will block waiting for data and read the data into the + * input buffer specified with the call to PSOCK_INIT(). Data is read + * until the buffer is full.. + * + * \param psock (struct psock *) A pointer to the protosocket from which + * data should be read. + * + * \hideinitializer + */ +#define PSOCK_READBUF(psock) \ + PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock)) + +PT_THREAD(psock_readto(struct psock *psock, unsigned char c)); +/** + * Read data up to a specified character. + * + * This macro will block waiting for data and read the data into the + * input buffer specified with the call to PSOCK_INIT(). Data is only + * read until the specifieed character appears in the data stream. + * + * \param psock (struct psock *) A pointer to the protosocket from which + * data should be read. + * + * \param c (char) The character at which to stop reading. + * + * \hideinitializer + */ +#define PSOCK_READTO(psock, c) \ + PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c)) + +/** + * The length of the data that was previously read. + * + * This macro returns the length of the data that was previously read + * using PSOCK_READTO() or PSOCK_READ(). + * + * \param psock (struct psock *) A pointer to the protosocket holding the data. + * + * \hideinitializer + */ +#define PSOCK_DATALEN(psock) psock_datalen(psock) + +u16_t psock_datalen(struct psock *psock); + +/** + * Exit the protosocket's protothread. + * + * This macro terminates the protothread of the protosocket and should + * almost always be used in conjunction with PSOCK_CLOSE(). + * + * \sa PSOCK_CLOSE_EXIT() + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt)) + +/** + * Close a protosocket and exit the protosocket's protothread. + * + * This macro closes a protosocket and exits the protosocket's protothread. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_CLOSE_EXIT(psock) \ + do { \ + PSOCK_CLOSE(psock); \ + PSOCK_EXIT(psock); \ + } while(0) + +/** + * Declare the end of a protosocket's protothread. + * + * This macro is used for declaring that the protosocket's protothread + * ends. It must always be used together with a matching PSOCK_BEGIN() + * macro. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_END(psock) PT_END(&((psock)->pt)) + +char psock_newdata(struct psock *s); + +/** + * Check if new data has arrived on a protosocket. + * + * This macro is used in conjunction with the PSOCK_WAIT_UNTIL() + * macro to check if data has arrived on a protosocket. + * + * \param psock (struct psock *) A pointer to the protosocket. + * + * \hideinitializer + */ +#define PSOCK_NEWDATA(psock) psock_newdata(psock) + +/** + * Wait until a condition is true. + * + * This macro blocks the protothread until the specified condition is + * true. The macro PSOCK_NEWDATA() can be used to check if new data + * arrives when the protosocket is waiting. + * + * Typically, this macro is used as follows: + * + \code + PT_THREAD(thread(struct psock *s, struct timer *t)) + { + PSOCK_BEGIN(s); + + PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); + + if(PSOCK_NEWDATA(s)) { + PSOCK_READTO(s, '\n'); + } else { + handle_timed_out(s); + } + + PSOCK_END(s); + } + \endcode + * + * \param psock (struct psock *) A pointer to the protosocket. + * \param condition The condition to wait for. + * + * \hideinitializer + */ +#define PSOCK_WAIT_UNTIL(psock, condition) \ + PT_WAIT_UNTIL(&((psock)->pt), (condition)); + +#define PSOCK_WAIT_THREAD(psock, condition) \ + PT_WAIT_THREAD(&((psock)->pt), (condition)) + +#endif /* __PSOCK_H__ */ + +/** @} */ +/** @} */ diff --git a/core/net/resolv.c b/core/net/resolv.c new file mode 100644 index 000000000..645da29cd --- /dev/null +++ b/core/net/resolv.c @@ -0,0 +1,499 @@ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipdns uIP hostname resolver functions + * @{ + * + * The uIP DNS resolver functions are used to lookup a hostname and + * map it to a numerical IP address. It maintains a list of resolved + * hostnames that can be queried with the resolv_lookup() + * function. New hostnames can be resolved using the resolv_query() + * function. + * + * The event resolv_event_found is posted when a hostname has been + * resolved. It is up to the receiving process to determine if the + * correct hostname has been found by calling the resolv_lookup() + * function with the hostname. + */ + +/** + * \file + * DNS host name to IP address resolver. + * \author Adam Dunkels + * + * This file implements a DNS host name to IP address resolver. + */ + +/* + * Copyright (c) 2002-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 uIP TCP/IP stack. + * + * $Id: resolv.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +#include "net/tcpip.h" +#include "net/resolv.h" + +#include + +#ifndef NULL +#define NULL (void *)0 +#endif /* NULL */ + +/** \internal The maximum number of retries when asking for a name. */ +#define MAX_RETRIES 8 + +/** \internal The DNS message header. */ +struct dns_hdr { + u16_t id; + u8_t flags1, flags2; +#define DNS_FLAG1_RESPONSE 0x80 +#define DNS_FLAG1_OPCODE_STATUS 0x10 +#define DNS_FLAG1_OPCODE_INVERSE 0x08 +#define DNS_FLAG1_OPCODE_STANDARD 0x00 +#define DNS_FLAG1_AUTHORATIVE 0x04 +#define DNS_FLAG1_TRUNC 0x02 +#define DNS_FLAG1_RD 0x01 +#define DNS_FLAG2_RA 0x80 +#define DNS_FLAG2_ERR_MASK 0x0f +#define DNS_FLAG2_ERR_NONE 0x00 +#define DNS_FLAG2_ERR_NAME 0x03 + u16_t numquestions; + u16_t numanswers; + u16_t numauthrr; + u16_t numextrarr; +}; + +/** \internal The DNS answer message structure. */ +struct dns_answer { + /* DNS answer record starts with either a domain name or a pointer + to a name already present somewhere in the packet. */ + u16_t type; + u16_t class; + u16_t ttl[2]; + u16_t len; + u16_t ipaddr[2]; +}; + +struct namemap { +#define STATE_UNUSED 0 +#define STATE_NEW 1 +#define STATE_ASKING 2 +#define STATE_DONE 3 +#define STATE_ERROR 4 + u8_t state; + u8_t tmr; + u8_t retries; + u8_t seqno; + u8_t err; + char name[32]; + u16_t ipaddr[2]; +}; + +#ifndef UIP_CONF_RESOLV_ENTRIES +#define RESOLV_ENTRIES 4 +#else /* UIP_CONF_RESOLV_ENTRIES */ +#define RESOLV_ENTRIES UIP_CONF_RESOLV_ENTRIES +#endif /* UIP_CONF_RESOLV_ENTRIES */ + + +static struct namemap names[RESOLV_ENTRIES]; + +static u8_t seqno; + +static struct uip_udp_conn *resolv_conn = NULL; + +process_event_t resolv_event_found; + +PROCESS(resolv_process, "DNS resolver"); + +enum { + EVENT_NEW_SERVER=0 +}; + +/*-----------------------------------------------------------------------------------*/ +/** \internal + * Walk through a compact encoded DNS name and return the end of it. + * + * \return The end of the name. + */ +/*-----------------------------------------------------------------------------------*/ +static unsigned char * +parse_name(unsigned char *query) +{ + unsigned char n; + + do { + n = *query++; + + while(n > 0) { + /* printf("%c", *query);*/ + ++query; + --n; + }; + /* printf(".");*/ + } while(*query != 0); + /* printf("\n");*/ + return query + 1; +} +/*-----------------------------------------------------------------------------------*/ +/** \internal + * Runs through the list of names to see if there are any that have + * not yet been queried and, if so, sends out a query. + */ +/*-----------------------------------------------------------------------------------*/ +static void +check_entries(void) +{ + register struct dns_hdr *hdr; + char *query, *nptr, *nameptr; + static u8_t i; + static u8_t n; + register struct namemap *namemapptr; + + for(i = 0; i < RESOLV_ENTRIES; ++i) { + namemapptr = &names[i]; + if(namemapptr->state == STATE_NEW || + namemapptr->state == STATE_ASKING) { + if(namemapptr->state == STATE_ASKING) { + if(--namemapptr->tmr == 0) { + if(++namemapptr->retries == MAX_RETRIES) { + namemapptr->state = STATE_ERROR; + resolv_found(namemapptr->name, NULL); + continue; + } + namemapptr->tmr = namemapptr->retries; + } else { + /* printf("Timer %d\n", namemapptr->tmr);*/ + /* Its timer has not run out, so we move on to next + entry. */ + continue; + } + } else { + namemapptr->state = STATE_ASKING; + namemapptr->tmr = 1; + namemapptr->retries = 0; + } + hdr = (struct dns_hdr *)uip_appdata; + memset(hdr, 0, sizeof(struct dns_hdr)); + hdr->id = htons(i); + hdr->flags1 = DNS_FLAG1_RD; + hdr->numquestions = HTONS(1); + query = (char *)uip_appdata + 12; + nameptr = namemapptr->name; + --nameptr; + /* Convert hostname into suitable query format. */ + do { + ++nameptr; + nptr = query; + ++query; + for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) { + *query = *nameptr; + ++query; + ++n; + } + *nptr = n; + } while(*nameptr != 0); + { + static unsigned char endquery[] = + {0,0,1,0,1}; + memcpy(query, endquery, 5); + } + uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata)); + break; + } + } +} +/*-----------------------------------------------------------------------------------*/ +/** \internal + * Called when new UDP data arrives. + */ +/*-----------------------------------------------------------------------------------*/ +static void +newdata(void) +{ + char *nameptr; + struct dns_answer *ans; + struct dns_hdr *hdr; + static u8_t nquestions, nanswers; + static u8_t i; + register struct namemap *namemapptr; + + hdr = (struct dns_hdr *)uip_appdata; + /* printf("ID %d\n", htons(hdr->id)); + printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE); + printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK); + printf("Num questions %d, answers %d, authrr %d, extrarr %d\n", + htons(hdr->numquestions), + htons(hdr->numanswers), + htons(hdr->numauthrr), + htons(hdr->numextrarr)); + */ + + /* The ID in the DNS header should be our entry into the name + table. */ + i = htons(hdr->id); + namemapptr = &names[i]; + if(i < RESOLV_ENTRIES && + namemapptr->state == STATE_ASKING) { + + /* This entry is now finished. */ + namemapptr->state = STATE_DONE; + namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; + + /* Check for error. If so, call callback to inform. */ + if(namemapptr->err != 0) { + namemapptr->state = STATE_ERROR; + resolv_found(namemapptr->name, NULL); + return; + } + + /* We only care about the question(s) and the answers. The authrr + and the extrarr are simply discarded. */ + nquestions = htons(hdr->numquestions); + nanswers = htons(hdr->numanswers); + + /* Skip the name in the question. XXX: This should really be + checked agains the name in the question, to be sure that they + match. */ + nameptr = parse_name((char *)uip_appdata + 12) + 4; + + while(nanswers > 0) { + /* The first byte in the answer resource record determines if it + is a compressed record or a normal one. */ + if(*nameptr & 0xc0) { + /* Compressed name. */ + nameptr +=2; + /* printf("Compressed anwser\n");*/ + } else { + /* Not compressed name. */ + nameptr = parse_name((char *)nameptr); + } + + ans = (struct dns_answer *)nameptr; + /* printf("Answer: type %x, class %x, ttl %x, length %x\n", + htons(ans->type), htons(ans->class), (htons(ans->ttl[0]) + << 16) | htons(ans->ttl[1]), htons(ans->len));*/ + + /* Check for IP address type and Internet class. Others are + discarded. */ + if(ans->type == HTONS(1) && + ans->class == HTONS(1) && + ans->len == HTONS(4)) { + /* printf("IP address %d.%d.%d.%d\n", + htons(ans->ipaddr[0]) >> 8, + htons(ans->ipaddr[0]) & 0xff, + htons(ans->ipaddr[1]) >> 8, + htons(ans->ipaddr[1]) & 0xff);*/ + /* XXX: we should really check that this IP address is the one + we want. */ + namemapptr->ipaddr[0] = ans->ipaddr[0]; + namemapptr->ipaddr[1] = ans->ipaddr[1]; + + resolv_found(namemapptr->name, namemapptr->ipaddr); + return; + } else { + nameptr = nameptr + 10 + htons(ans->len); + } + --nanswers; + } + } + +} +/*-----------------------------------------------------------------------------------*/ +/** \internal + * The main UDP function. + */ +/*-----------------------------------------------------------------------------------*/ +PROCESS_THREAD(resolv_process, ev, data) +{ + int i; + + PROCESS_BEGIN(); + + for(i = 0; i < RESOLV_ENTRIES; ++i) { + names[i].state = STATE_UNUSED; + } + resolv_conn = NULL; + resolv_event_found = process_alloc_event(); + + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == EVENT_NEW_SERVER) { + if(resolv_conn != NULL) { + uip_udp_remove(resolv_conn); + } + + resolv_conn = udp_new((u16_t *)data, HTONS(53), NULL); + + } else if(ev == tcpip_event) { + if(uip_udp_conn->rport == HTONS(53)) { + if(uip_poll()) { + check_entries(); + } + if(uip_newdata()) { + newdata(); + } + } + } + } + + PROCESS_END(); +} +/*-----------------------------------------------------------------------------------*/ +/** + * Queues a name so that a question for the name will be sent out. + * + * \param name The hostname that is to be queried. + */ +/*-----------------------------------------------------------------------------------*/ +void +resolv_query(char *name) +{ + static u8_t i; + static u8_t lseq, lseqi; + register struct namemap *nameptr; + + lseq = lseqi = 0; + + for(i = 0; i < RESOLV_ENTRIES; ++i) { + nameptr = &names[i]; + if(nameptr->state == STATE_UNUSED) { + break; + } + if(seqno - nameptr->seqno > lseq) { + lseq = seqno - nameptr->seqno; + lseqi = i; + } + } + + if(i == RESOLV_ENTRIES) { + i = lseqi; + nameptr = &names[i]; + } + + strncpy(nameptr->name, name, sizeof(nameptr->name)); + nameptr->state = STATE_NEW; + nameptr->seqno = seqno; + ++seqno; + + if(resolv_conn != NULL) { + tcpip_poll_udp(resolv_conn); + } +} +/*-----------------------------------------------------------------------------------*/ +/** + * Look up a hostname in the array of known hostnames. + * + * \note This function only looks in the internal array of known + * hostnames, it does not send out a query for the hostname if none + * was found. The function resolv_query() can be used to send a query + * for a hostname. + * + * \return A pointer to a 4-byte representation of the hostname's IP + * address, or NULL if the hostname was not found in the array of + * hostnames. + */ +/*-----------------------------------------------------------------------------------*/ +u16_t * +resolv_lookup(char *name) +{ + static u8_t i; + struct namemap *nameptr; + + /* Walk through the list to see if the name is in there. If it is + not, we return NULL. */ + for(i = 0; i < RESOLV_ENTRIES; ++i) { + nameptr = &names[i]; + if(nameptr->state == STATE_DONE && + strcmp(name, nameptr->name) == 0) { + return nameptr->ipaddr; + } + } + return NULL; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Obtain the currently configured DNS server. + * + * \return A pointer to a 4-byte representation of the IP address of + * the currently configured DNS server or NULL if no DNS server has + * been configured. + */ +/*-----------------------------------------------------------------------------------*/ +u16_t * +resolv_getserver(void) +{ + if(resolv_conn == NULL) { + return NULL; + } + return resolv_conn->ripaddr; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Configure a DNS server. + * + * \param dnsserver A pointer to a 4-byte representation of the IP + * address of the DNS server to be configured. + */ +/*-----------------------------------------------------------------------------------*/ +void +resolv_conf(u16_t *dnsserver) +{ + static u16_t server[2]; + uip_ipaddr_copy(server, dnsserver); + process_post(&resolv_process, EVENT_NEW_SERVER, server); + + /* if(resolv_conn != NULL) { + uip_udp_remove(resolv_conn); + } + + resolv_conn = udp_new(dnsserver, 53, NULL);*/ +} +/*-----------------------------------------------------------------------------------*/ +/** \internal + * Callback function which is called when a hostname is found. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +resolv_found(char *name, u16_t *ipaddr) +{ + process_post(PROCESS_BROADCAST, resolv_event_found, name); +} +/*-----------------------------------------------------------------------------------*/ + +/** @} */ +/** @} */ diff --git a/core/net/resolv.h b/core/net/resolv.h new file mode 100644 index 000000000..25c529b32 --- /dev/null +++ b/core/net/resolv.h @@ -0,0 +1,62 @@ +/** + * \file + * uIP DNS resolver code header file. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2002-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 uIP TCP/IP stack. + * + * $Id: resolv.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ +#ifndef __RESOLV_H__ +#define __RESOLV_H__ + +#include "contiki.h" + +/** + * Event that is broadcasted when a DNS name has been resolved. + */ +extern process_event_t resolv_event_found; + +/* Callbacks. */ +void resolv_found(char *name, u16_t *ipaddr); + +/* Functions. */ +void resolv_conf(u16_t *dnsserver); +u16_t *resolv_getserver(void); +void resolv_init(char *arg); +u16_t *resolv_lookup(char *name); +void resolv_query(char *name); + +PROCESS_NAME(resolv_process); + +#endif /* __RESOLV_H__ */ diff --git a/core/net/slipdev.c b/core/net/slipdev.c new file mode 100644 index 000000000..ba20b065b --- /dev/null +++ b/core/net/slipdev.c @@ -0,0 +1,208 @@ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup slip Serial Line IP (SLIP) protocol + * @{ + * + * The SLIP protocol is a very simple way to transmit IP packets over + * a serial line. It does not provide any framing or error control, + * and is therefore not very widely used today. + * + * This SLIP implementation requires two functions for accessing the + * serial device: slipdev_char_poll() and slipdev_char_put(). These + * must be implemented specifically for the system on which the SLIP + * protocol is to be run. + */ + +/** + * \file + * SLIP protocol implementation + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2001, 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: slipdev.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +/* + * This is a generic implementation of the SLIP protocol over an RS232 + * (serial) device. + * + * Huge thanks to Ullrich von Bassewitz of cc65 fame for + * and endless supply of bugfixes, insightsful comments and + * suggestions, and improvements to this code! + */ + +#include "uip.h" +#include "uip-fw.h" +#include "slipdev.h" +#include /* For memcpy() */ + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + +static u8_t slip_buf[UIP_BUFSIZE]; + +static u16_t len, tmplen; +static u8_t lastc; + +/*-----------------------------------------------------------------------------------*/ +/** + * Send the packet in the uip_buf and uip_appdata buffers using the + * SLIP protocol. + * + * The first 40 bytes of the packet (the IP and TCP headers) are read + * from the uip_buf buffer, and the following bytes (the application + * data) are read from the uip_appdata buffer. + * + * \return This function will always return UIP_FW_OK. + */ +/*-----------------------------------------------------------------------------------*/ +u8_t +slipdev_send(void) +{ + u16_t i; + u8_t *ptr; + u8_t c; + + slipdev_char_put(SLIP_END); + + ptr = &uip_buf[UIP_LLH_LEN]; + for(i = 0; i < uip_len; ++i) { + if(i == UIP_TCPIP_HLEN) { + ptr = (char *)uip_appdata; + } + c = *ptr++; + switch(c) { + case SLIP_END: + slipdev_char_put(SLIP_ESC); + slipdev_char_put(SLIP_ESC_END); + break; + case SLIP_ESC: + slipdev_char_put(SLIP_ESC); + slipdev_char_put(SLIP_ESC_ESC); + break; + default: + slipdev_char_put(c); + break; + } + } + slipdev_char_put(SLIP_END); + + return UIP_FW_OK; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Poll the SLIP device for an available packet. + * + * This function will poll the SLIP device to see if a packet is + * available. It uses a buffer in which all avaliable bytes from the + * RS232 interface are read into. When a full packet has been read + * into the buffer, the packet is copied into the uip_buf buffer and + * the length of the packet is returned. + * + * \return The length of the packet placed in the uip_buf buffer, or + * zero if no packet is available. + */ +/*-----------------------------------------------------------------------------------*/ +u16_t +slipdev_poll(void) +{ + u8_t c; + + while(slipdev_char_poll(&c)) { + switch(c) { + case SLIP_ESC: + lastc = c; + break; + + case SLIP_END: + lastc = c; + /* End marker found, we copy our input buffer to the uip_buf + buffer and return the size of the packet we copied. */ + memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len); + tmplen = len; + len = 0; + return tmplen; + + default: + if(lastc == SLIP_ESC) { + lastc = c; + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + } else { + lastc = c; + } + + slip_buf[len] = c; + ++len; + + if(len > UIP_BUFSIZE) { + len = 0; + } + + break; + } + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Initialize the SLIP module. + * + * This function does not initialize the underlying RS232 device, but + * only the SLIP part. + */ +/*-----------------------------------------------------------------------------------*/ +void +slipdev_init(void) +{ + lastc = len = 0; +} +/*-----------------------------------------------------------------------------------*/ + +/** @} */ +/** @} */ diff --git a/core/net/slipdev.h b/core/net/slipdev.h new file mode 100644 index 000000000..f41699c2c --- /dev/null +++ b/core/net/slipdev.h @@ -0,0 +1,88 @@ +/** + * \addtogroup slip + * @{ + */ + +/** + * \file + * SLIP header file. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2001, 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: slipdev.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + * + */ + +#ifndef __SLIPDEV_H__ +#define __SLIPDEV_H__ + +#include "uip.h" + +/** + * Put a character on the serial device. + * + * This function is used by the SLIP implementation to put a character + * on the serial device. It must be implemented specifically for the + * system on which the SLIP implementation is to be run. + * + * \param c The character to be put on the serial device. + */ +void slipdev_char_put(u8_t c); + +/** + * Poll the serial device for a character. + * + * This function is used by the SLIP implementation to poll the serial + * device for a character. It must be implemented specifically for the + * system on which the SLIP implementation is to be run. + * + * The function should return immediately regardless if a character is + * available or not. If a character is available it should be placed + * at the memory location pointed to by the pointer supplied by the + * arguement c. + * + * \param c A pointer to a byte that is filled in by the function with + * the received character, if available. + * + * \retval 0 If no character is available. + * \retval Non-zero If a character is available. + */ +u8_t slipdev_char_poll(u8_t *c); + +void slipdev_init(void); +u8_t slipdev_send(void); +u16_t slipdev_poll(void); + +#endif /* __SLIPDEV_H__ */ + +/** @} */ diff --git a/core/net/tcpdump.c b/core/net/tcpdump.c new file mode 100644 index 000000000..459216f2e --- /dev/null +++ b/core/net/tcpdump.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: tcpdump.c,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ + +#include "contiki-net.h" + +#include +#include + + struct ip_hdr { + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u8_t srcipaddr[4], + destipaddr[4]; + }; + +#define TCP_FIN 0x01 +#define TCP_SYN 0x02 +#define TCP_RST 0x04 +#define TCP_PSH 0x08 +#define TCP_ACK 0x10 +#define TCP_URG 0x20 +#define TCP_CTL 0x3f + +struct tcpip_hdr { + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u8_t srcipaddr[4], + destipaddr[4]; + /* TCP header. */ + u16_t srcport, + destport; + u8_t seqno[4], + ackno[4], + tcpoffset, + flags, + wnd[2]; + u16_t tcpchksum; + u8_t urgp[2]; + u8_t optdata[4]; +}; + +#define ICMP_ECHO_REPLY 0 +#define ICMP_ECHO 8 + +struct icmpip_hdr { + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u8_t srcipaddr[4], + destipaddr[4]; + /* The ICMP and IP headers. */ + /* ICMP (echo) header. */ + u8_t type, icode; + u16_t icmpchksum; + u16_t id, seqno; +}; + + +/* The UDP and IP headers. */ +struct udpip_hdr { + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u8_t srcipaddr[4], + destipaddr[4]; + + /* UDP header. */ + u16_t srcport, + destport; + u16_t udplen; + u16_t udpchksum; +}; + +#define ETHBUF ((struct eth_hdr *)&uip_buf[0]) +#define IPBUF ((struct ip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UDPBUF ((struct udpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define TCPBUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + + +/*---------------------------------------------------------------------------*/ +static void +tcpflags(unsigned char flags, char *flagsstr) +{ + if(flags & TCP_FIN) { + *flagsstr++ = 'F'; + } + if(flags & TCP_SYN) { + *flagsstr++ = 'S'; + } + if(flags & TCP_RST) { + *flagsstr++ = 'R'; + } + if(flags & TCP_ACK) { + *flagsstr++ = 'A'; + } + if(flags & TCP_URG) { + *flagsstr++ = 'U'; + } + + *flagsstr = 0; +} +/*---------------------------------------------------------------------------*/ +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 char * CC_FASTCALL +d(char *ptr) +{ + *ptr = '.'; + return ptr + 1; +} +/*---------------------------------------------------------------------------*/ +static char * CC_FASTCALL +s(char *str, char *ptr) +{ + strcpy(ptr, str); + return ptr + strlen(str); +} +/*---------------------------------------------------------------------------*/ +int +tcpdump_print(char *buf, u16_t buflen) +{ + char flags[8]; + if(IPBUF->proto == UIP_PROTO_ICMP) { + if(ICMPBUF->type == ICMP_ECHO) { + return s(" ping", + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf)))))))))))))))) - buf; + + /* return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d ping", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/ + } else if(ICMPBUF->type == ICMP_ECHO_REPLY) { + return s(" pong", + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf)))))))))))))))) - buf; + /* return sprintf(buf, "%d.%d.%d.%d %d.%d.%d.%d pong", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3]);*/ + } + } else if(IPBUF->proto == UIP_PROTO_UDP) { + return s(" UDP", + n(htons(UDPBUF->destport), d( + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(htons(UDPBUF->srcport), d( + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf)))))))))))))))))))) - buf; + /* return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d UDP", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + htons(UDPBUF->srcport), + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3], + htons(UDPBUF->destport));*/ + } else if(IPBUF->proto == UIP_PROTO_TCP) { + tcpflags(TCPBUF->flags, flags); + return s(flags, + s(" ", + n(htons(TCPBUF->destport), d( + n(IPBUF->destipaddr[3], d( + n(IPBUF->destipaddr[2], d( + n(IPBUF->destipaddr[1], d( + n(IPBUF->destipaddr[0], + s(" ", + n(htons(TCPBUF->srcport), d( + n(IPBUF->srcipaddr[3], d( + n(IPBUF->srcipaddr[2], d( + n(IPBUF->srcipaddr[1], d( + n(IPBUF->srcipaddr[0], + buf))))))))))))))))))))) - buf; + /* return sprintf(buf, "%d.%d.%d.%d.%d %d.%d.%d.%d.%d %s", + IPBUF->srcipaddr[0], IPBUF->srcipaddr[1], + IPBUF->srcipaddr[2], IPBUF->srcipaddr[3], + htons(TCPBUF->srcport), + IPBUF->destipaddr[0], IPBUF->destipaddr[1], + IPBUF->destipaddr[2], IPBUF->destipaddr[3], + htons(TCPBUF->destport), + flags); */ + } + + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/tcpdump.h b/core/net/tcpdump.h new file mode 100644 index 000000000..9c8e1e5f2 --- /dev/null +++ b/core/net/tcpdump.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: tcpdump.h,v 1.1 2006/06/17 22:41:18 adamdunkels Exp $ + */ +#ifndef __TCPDUMP_H__ +#define __TCPDUMP_H__ + +#include "uip.h" + +int tcpdump_print(char *buf, u16_t buflen); + +#endif /* __TCPDUMP_H__ */ diff --git a/core/net/tcpip.c b/core/net/tcpip.c new file mode 100644 index 000000000..51fe28e1e --- /dev/null +++ b/core/net/tcpip.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: tcpip.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +#include "contiki-conf.h" +#include "contiki-net.h" + +#include "net/packet-service.h" +#include "net/uip-split.h" + +#include + +process_event_t tcpip_event; + +/** + * \internal Structure for holding a TCP port and a process ID. + */ +struct listenport { + u16_t port; + struct process *p; +}; + +/*static struct tcpip_event_args ev_args;*/ + +static struct etimer periodic; + +static struct internal_state { + struct listenport listenports[UIP_LISTENPORTS]; + struct process *p; +} s; + +enum { + TCP_POLL, + UDP_POLL, + PACKET_INPUT +}; + +static unsigned char forwarding = 0; + +PROCESS(tcpip_process, "TCP/IP stack"); + +/*---------------------------------------------------------------------------*/ +void +tcpip_set_forwarding(unsigned char f) +{ + forwarding = f; +} +/*---------------------------------------------------------------------------*/ +static void +packet_input(void) +{ + if(uip_len > 0) { + if(forwarding) { + if(uip_fw_forward() == 0) { + uip_input(); + if(uip_len > 0) { +#if UIP_CONF_TCP_SPLIT + uip_split_output(); +#else + tcpip_output(); +#endif + } + } + } else { + uip_input(); + if(uip_len > 0) { +#if UIP_CONF_TCP_SPLIT + uip_split_output(); +#else + tcpip_output(); +#endif + } + } + } +} +/*---------------------------------------------------------------------------*/ +void +tcpip_output(void) +{ + SERVICE_CALL(packet_service, output()); +} +/*---------------------------------------------------------------------------*/ +struct uip_conn * +tcp_connect(u16_t *ripaddr, u16_t port, void *appstate) +{ + struct uip_conn *c; + + c = uip_connect((uip_ipaddr_t *)ripaddr, port); + if(c == NULL) { + return NULL; + } + + c->appstate.p = PROCESS_CURRENT(); + c->appstate.state = appstate; + + tcpip_poll_tcp(c); + + return c; +} +/*---------------------------------------------------------------------------*/ +void +tcp_unlisten(u16_t port) +{ + static unsigned char i; + struct listenport *l; + + l = s.listenports; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->port == port && + l->p == PROCESS_CURRENT()) { + l->port = 0; + uip_unlisten(port); + break; + } + ++l; + } +} +/*---------------------------------------------------------------------------*/ +void +tcp_listen(u16_t port) +{ + static unsigned char i; + struct listenport *l; + + l = s.listenports; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->port == 0) { + l->port = port; + l->p = PROCESS_CURRENT(); + uip_listen(port); + break; + } + ++l; + } +} +/*---------------------------------------------------------------------------*/ +void +tcp_attach(struct uip_conn *conn, + void *appstate) +{ + register uip_tcp_appstate_t *s; + + s = &conn->appstate; + s->p = PROCESS_CURRENT(); + s->state = appstate; +} +/*---------------------------------------------------------------------------*/ +void +udp_attach(struct uip_udp_conn *conn, + void *appstate) +{ + register uip_udp_appstate_t *s; + + s = &conn->appstate; + s->p = PROCESS_CURRENT(); + s->state = appstate; +} +/*---------------------------------------------------------------------------*/ +struct uip_udp_conn * +udp_new(u16_t *ripaddr, u16_t port, void *appstate) +{ + struct uip_udp_conn *c; + uip_udp_appstate_t *s; + + c = uip_udp_new((uip_ipaddr_t *)ripaddr, port); + if(c == NULL) { + return NULL; + } + + s = &c->appstate; + s->p = PROCESS_CURRENT(); + s->state = appstate; + + return c; +} +/*---------------------------------------------------------------------------*/ +struct uip_udp_conn * +udp_broadcast_new(u16_t port, void *appstate) +{ + uip_ipaddr_t addr; + struct uip_udp_conn *conn; + + uip_ipaddr(addr, 255,255,255,255); + conn = udp_new(addr, port, appstate); + if(conn != NULL) { + udp_bind(conn, port); + } + return conn; +} +/*---------------------------------------------------------------------------*/ +static void +eventhandler(process_event_t ev, process_data_t data) +{ + static unsigned char i; + register struct listenport *l; + struct process *p; + + switch(ev) { + case PROCESS_EVENT_EXITED: + /* This is the event we get if a process has exited. We go through + the TCP/IP tables to see if this process had any open + connections or listening TCP ports. If so, we'll close those + connections. */ + p = (struct process *)data; + l = s.listenports; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->p == p) { + uip_unlisten(l->port); + l->port = 0; + l->p = PROCESS_NONE; + } + ++l; + } + + { + register struct uip_conn *cptr; + + for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) { + if(cptr->appstate.p == p) { + cptr->appstate.p = PROCESS_NONE; + cptr->tcpstateflags = UIP_CLOSED; + } + + } + + } +#if UIP_UDP + { + register struct uip_udp_conn *cptr; + for(cptr = &uip_udp_conns[0]; + cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) { + if(cptr->appstate.p == p) { + cptr->lport = 0; + } + } + + } +#endif /* UIP_UDP */ + break; + + case PROCESS_EVENT_TIMER: + /* We get this event if one of our timers have expired. */ + { + static unsigned char i; + + /* Check the clock so see if we should call the periodic uIP + processing. */ + if(etimer_expired(&periodic)) { + for(i = 0; i < UIP_CONNS; ++i) { + if(uip_conn_active(i)) { + /* Only restart the timer if there are active + connections. */ + etimer_restart(&periodic); + uip_periodic(i); + if(uip_len > 0) { + tcpip_output(); + } + } + } + + /* for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + tcpip_output(); + } + }*/ + uip_fw_periodic(); + } + } + break; + + case TCP_POLL: + if(data != NULL) { + uip_poll_conn(data); + if(uip_len > 0) { + tcpip_output(); + } + + /* Start the periodic polling, if it isn't already active. */ + if(etimer_expired(&periodic)) { + etimer_restart(&periodic); + } + + } + break; + case UDP_POLL: + if(data != NULL) { + uip_udp_periodic_conn(data); + if(uip_len > 0) { + tcpip_output(); + } + } + break; + + case PACKET_INPUT: + packet_input(); + break; + }; +} +/*---------------------------------------------------------------------------*/ +void +tcpip_input(void) +{ + process_post_synch(&tcpip_process, PACKET_INPUT, NULL); + uip_len = 0; +} +/*---------------------------------------------------------------------------*/ +void +tcpip_poll_udp(struct uip_udp_conn *conn) +{ + process_post(&tcpip_process, UDP_POLL, conn); +} +/*---------------------------------------------------------------------------*/ +void +tcpip_poll_tcp(struct uip_conn *conn) +{ + process_post(&tcpip_process, TCP_POLL, conn); +} +/*---------------------------------------------------------------------------*/ +void +tcpip_uipcall(void) +{ + register uip_udp_appstate_t *ts; + static unsigned char i; + register struct listenport *l; + + if(uip_conn != NULL) { + ts = &uip_conn->appstate; + } else { + ts = &uip_udp_conn->appstate; + } + + /* If this is a connection request for a listening port, we must + mark the connection with the right process ID. */ + if(uip_connected()) { + l = &s.listenports[0]; + for(i = 0; i < UIP_LISTENPORTS; ++i) { + if(l->port == uip_conn->lport && + l->p != PROCESS_NONE) { + ts->p = l->p; + ts->state = NULL; + break; + } + ++l; + } + + /* Start the periodic polling, if it isn't already active. */ + if(etimer_expired(&periodic)) { + etimer_restart(&periodic); + } + } + + if(ts->p != NULL) { + process_post_synch(ts->p, tcpip_event, ts->state); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(tcpip_process, ev, data) +{ + int i; + + PROCESS_BEGIN(); + + for(i = 0; i < UIP_LISTENPORTS; ++i) { + s.listenports[i].port = 0; + } + s.p = PROCESS_CURRENT(); + tcpip_event = process_alloc_event(); + etimer_set(&periodic, CLOCK_SECOND/2); + + uip_init(); + + while(1) { + PROCESS_YIELD(); + + eventhandler(ev, data); + } + + PROCESS_END(); +} diff --git a/core/net/tcpip.h b/core/net/tcpip.h new file mode 100644 index 000000000..f5f6cb51f --- /dev/null +++ b/core/net/tcpip.h @@ -0,0 +1,309 @@ +/** + * \addtogroup net + * @{ + */ + +/** + * \defgroup tcpip The Contiki/uIP interface + * @{ + * + * TCP/IP support in Contiki is implemented using the uIP TCP/IP + * stack. For sending and receiving data, Contiki uses the functions + * provided by the uIP module, but Contiki adds a set of functions for + * connection management. The connection management functions make + * sure that the uIP TCP/IP connections are connected to the correct + * process. + * + * Contiki also includes an optional protosocket library that provides + * an API similar to the BSD socket API. + * + * \sa \ref uip "The uIP TCP/IP stack" + * \sa \ref psock "Protosockets library" + * + */ + +/** + * \file + * Header for the Contiki/uIP interface. + * \author + * Adam Dunkels + */ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: tcpip.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ +#ifndef __TCPIP_H__ +#define __TCPIP_H__ + +#include "contiki.h" + +struct uip_conn; + +struct tcpip_uipstate { + struct process *p; + void *state; +}; + +#define UIP_APPCALL tcpip_uipcall +#define UIP_UDP_APPCALL tcpip_uipcall +/*#define UIP_APPSTATE_SIZE sizeof(struct tcpip_uipstate)*/ + +typedef struct tcpip_uipstate uip_udp_appstate_t; +typedef struct tcpip_uipstate uip_tcp_appstate_t; + +#include "net/uip.h" + +void tcpip_uipcall(void); + +/** + * \name TCP functions + * @{ + */ + +/** + * Attach a TCP connection to the current process + * + * This function attaches the current process to a TCP + * connection. Each TCP connection must be attached to a process in + * order for the process to be able to receive and send + * data. Additionally, this function can add a pointer with connection + * state to the connection. + * + * \param conn A pointer to the TCP connection. + * + * \param appstate An opaque pointer that will be passed to the + * process whenever an event occurs on the connection. + * + */ +void tcp_attach(struct uip_conn *conn, + void *appstate); +#define tcp_markconn(conn, appstate) tcp_attach(conn, appstate) + +/** + * Open a TCP port. + * + * This function opens a TCP port for listening. When a TCP connection + * request occurs for the port, the process will be sent a tcpip_event + * with the new connection request. + * + * \note Port numbers must always be given in network byte order. The + * functions HTONS() and htons() can be used to convert port numbers + * from host byte order to network byte order. + * + * \param port The port number in network byte order. + * + */ +void tcp_listen(u16_t port); + +/** + * Close a listening TCP port. + * + * This function closes a listening TCP port. + * + * \note Port numbers must always be given in network byte order. The + * functions HTONS() and htons() can be used to convert port numbers + * from host byte order to network byte order. + * + * \param port The port number in network byte order. + * + */ +void tcp_unlisten(u16_t port); + +/** + * Open a TCP connection to the specified IP address and port. + * + * This function opens a TCP connection to the specified port at the + * host specified with an IP address. Additionally, an opaque pointer + * can be attached to the connection. This pointer will be sent + * together with uIP events to the process. + * + * \note The port number must be provided in network byte order so a + * conversion with HTONS() usually is necessary. + * + * \note This function will only create the connection. The connection + * is not opened directly. uIP will try to open the connection the + * next time the uIP stack is scheduled by Contiki. + * + * \param ripaddr Pointer to the IP address of the remote host. + * \param port Port number in network byte order. + * \param appstate Pointer to application defined data. + * + * \return A pointer to the newly created connection, or NULL if + * memory could not be allocated for the connection. + * + */ +struct uip_conn *tcp_connect(u16_t *ripaddr, u16_t port, + void *appstate); + +/** + * Cause a specified TCP connection to be polled. + * + * This function causes uIP to poll the specified TCP connection. The + * function is used when the application has data that is to be sent + * immediately and do not wish to wait for the periodic uIP polling + * mechanism. + * + * \param conn A pointer to the TCP connection that should be polled. + * + */ +void tcpip_poll_tcp(struct uip_conn *conn); + +/** @} */ + +/** + * \name UDP functions + * @{ + */ + +struct uip_udp_conn; +/** + * Attach the current process to a UDP connection + * + * This function attaches the current process to a UDP + * connection. Each UDP connection must have a process attached to it + * in order for the process to be able to receive and send data over + * the connection. Additionally, this function can add a pointer with + * connection state to the connection. + * + * \param conn A pointer to the UDP connection. + * + * \param appstate An opaque pointer that will be passed to the + * process whenever an event occurs on the connection. + * + */ +void udp_attach(struct uip_udp_conn *conn, + void *appstate); +#define udp_markconn(conn, appstate) udp_attach(conn, appstate) + +/** + * Create a new UDP connection. + * + * This function creates a new UDP connection with the specified + * remote endpoint. + * + * \note The port number must be provided in network byte order so a + * conversion with HTONS() usually is necessary. + * + * \sa udp_bind() + * + * \param ripaddr Pointer to the IP address of the remote host. + * \param port Port number in network byte order. + * \param appstate Pointer to application defined data. + * + * \return A pointer to the newly created connection, or NULL if + * memory could not be allocated for the connection. + */ +struct uip_udp_conn *udp_new(u16_t *ripaddr, u16_t port, + void *appstate); + +/** + * Create a new UDP broadcast connection. + * + * This function creates a new (link-local) broadcast UDP connection + * to a specified port. + * + * \param port Port number in network byte order. + * \param appstate Pointer to application defined data. + * + * \return A pointer to the newly created connection, or NULL if + * memory could not be allocated for the connection. + */ +struct uip_udp_conn *udp_broadcast_new(u16_t port, void *appstate); + +/** + * Bind a UDP connection to a local port. + * + * This function binds a UDP conncetion to a specified local port. + * + * When a connction is created with udp_new(), it gets a local port + * number assigned automatically. If the application needs to bind the + * connection to a specified local port, this function should be used. + * + * \note The port number must be provided in network byte order so a + * conversion with HTONS() usually is necessary. + * + * \param conn A pointer to the UDP connection that is to be bound. + * \param port The port number in network byte order to which to bind + * the connection. + */ +#define udp_bind(conn, port) uip_udp_bind(conn, port) + +/** + * Cause a specified UDP connection to be polled. + * + * This function causes uIP to poll the specified UDP connection. The + * function is used when the application has data that is to be sent + * immediately and do not wish to wait for the periodic uIP polling + * mechanism. + * + * \param conn A pointer to the UDP connection that should be polled. + * + */ +void tcpip_poll_udp(struct uip_udp_conn *conn); + +/** @} */ + +/** + * The uIP event. + * + * This event is posted to a process whenever a uIP event has occured. + */ +extern process_event_t tcpip_event; + +/** + * \name TCP/IP packet processing + * @{ + */ + +/** + * \brief Deliver an incoming packet to the TCP/IP stack + * + * This function is called by network device drivers to + * deliver an incoming packet to the TCP/IP stack. The + * incoming packet must be present in the uip_buf buffer, + * and the length of the packet must be in the global + * uip_len variable. + */ +void tcpip_input(void); + +void tcpip_output(void); +void tcpip_set_forwarding(unsigned char f); + +/** @} */ + +PROCESS_NAME(tcpip_process); + +#endif /* __TCPIP_H__ */ + +/** @} */ +/** @} */ diff --git a/core/net/uaodv-def.h b/core/net/uaodv-def.h new file mode 100644 index 000000000..76abb7f38 --- /dev/null +++ b/core/net/uaodv-def.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uaodv-def.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Definitions for the micro implementation of the AODV ad hoc routing protocol + * \author + * Adam Dunkels + */ + +#ifndef __UAODV_DEF_H__ +#define __UAODV_DEF_H__ + +#include "net/uip.h" + +#define NUM_PRECURSORS 4 + + +#define UAODV_UDPPORT 654 + +/* AODV routing table entry */ +struct uaodv_rtentry { + uip_ipaddr_t dest_addr; + uip_ipaddr_t next_hop; + uip_ipaddr_t precursors[NUM_PRECURSORS]; + u32_t dest_seqno; + u16_t lifetime; + u8_t dest_seqno_flag; + u8_t route_flags; + u8_t hop_count; +}; + +/* Generic AODV message */ +struct uaodv_msg { + u8_t type; +}; + +/* AODV RREQ message */ +#define UAODV_RREQ_TYPE 1 +#define UAODV_RREQ_JOIN (1 << 7) +#define UAODV_RREQ_REPAIR (1 << 6) +#define UAODV_RREQ_GRATIOUS (1 << 5) +#define UAODV_RREQ_DESTONLY (1 << 4) +#define UAODV_RREQ_UNKSEQNO (1 << 3) + +struct uaodv_msg_rreq { + u8_t type; + u8_t flags; + u8_t reserved; + u8_t hop_count; + u32_t rreq_id; + uip_ipaddr_t dest_addr; + u32_t dest_seqno; + uip_ipaddr_t src_addr; + u32_t src_seqno; +}; + +/* AODV RREP message */ +#define UAODV_RREP_TYPE 2 +#define UAODV_RREP_REPAIR (1 << 7) +#define UAODV_RREP_ACK (1 << 6) + +struct uaodv_msg_rrep { + u8_t type; + u8_t flags; + u8_t reserved; + u8_t hop_count; + uip_ipaddr_t dest_addr; + u32_t dest_seqno; + uip_ipaddr_t src_addr; + u32_t lifetime; +}; + +/* AODV RERR message */ +#define UAODV_RERR_TYPE 3 +#define UAODV_RERR_NODELETE (1 << 7) + +struct uaodv_msg_rerr { + u8_t type; + u8_t flags; + u8_t reserved; + u8_t dest_count; + struct { + uip_ipaddr_t addr; + u32_t seqno; + } unreach[1]; +}; + +/* AODV RREP-ACK message */ +#define UAODV_RREP_ACK_TYPE 4 + +struct uaodv_msg_rrep_ack { + u8_t type; + u8_t reserved; +}; + +#endif /* __UAODV_DEF_H__ */ diff --git a/core/net/uaodv-rt.c b/core/net/uaodv-rt.c new file mode 100644 index 000000000..99ab04157 --- /dev/null +++ b/core/net/uaodv-rt.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uaodv-rt.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Routing tables for the micro implementation of the AODV ad hoc routing protocol + * \author + * Adam Dunkels + */ + + +#include "net/uaodv-rt.h" +#include "contiki-net.h" + +#define NUM_RT_ENTRIES 8 + +/* + * LRU (with respect to insertion time) list of route entries. + */ +LIST(route_table); +MEMB(route_mem, struct uaodv_rt_entry, NUM_RT_ENTRIES); + +/*---------------------------------------------------------------------------*/ +void +uaodv_rt_init(void) +{ + list_init(route_table); + memb_init(&route_mem); +} +/*---------------------------------------------------------------------------*/ +int +uaodv_rt_add(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, + u16_t hop_count, u32_t seqno) +{ + struct uaodv_rt_entry *e; + + /* Avoid inserting duplicate entries. */ + e = uaodv_rt_lookup(dest); + if(e != NULL) { + list_remove(route_table, e); + } else { + /* Allocate a new entry or reuse the oldest. */ + e = memb_alloc(&route_mem); + if(e == NULL) { + e = list_chop(route_table); /* Remove oldest entry. */ + } + } + + uip_ipaddr_copy(e->dest, dest); + uip_ipaddr_copy(e->nexthop, nexthop); + e->hop_count = hop_count; + e->seqno = seqno; + + /* New entry goes first. */ + list_push(route_table, e); + + return 0; +} +/*---------------------------------------------------------------------------*/ +struct uaodv_rt_entry * +uaodv_rt_lookup(uip_ipaddr_t *dest) +{ + struct uaodv_rt_entry *e; + + for(e = list_head(route_table); e != NULL; e = e->next) { + /* printf("uaodv_rt_lookup: comparing %d.%d.%d.%d with %d.%d.%d.%d\n", + uip_ipaddr1(dest), + uip_ipaddr2(dest), + uip_ipaddr3(dest), + uip_ipaddr4(dest), + uip_ipaddr1(&e->dest), + uip_ipaddr2(&e->dest), + uip_ipaddr3(&e->dest), + uip_ipaddr4(&e->dest));*/ + + if(uip_ipaddr_cmp(dest, &e->dest)) { + return e; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +uaodv_rt_remove(struct uaodv_rt_entry *e) +{ + list_remove(route_table, e); + memb_free(&route_mem, e); +} +/*---------------------------------------------------------------------------*/ +void +uaodv_rt_flush_all(void) +{ + struct uaodv_rt_entry *e; + + while (1) { + e = list_pop(route_table); + if(e != NULL) + memb_free(&route_mem, e); + else + break; + } +} diff --git a/core/net/uaodv-rt.h b/core/net/uaodv-rt.h new file mode 100644 index 000000000..c1729874f --- /dev/null +++ b/core/net/uaodv-rt.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uaodv-rt.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Routing tables for the micro implementation of the AODV ad hoc routing protocol + * \author + * Adam Dunkels + */ + +#ifndef __UAODV_RT_H__ +#define __UAODV_RT_H__ + +#include "contiki-net.h" + +struct uaodv_rt_entry { + struct uaodv_rt_entry *next; + uip_ipaddr_t dest; + uip_ipaddr_t nexthop; + u32_t seqno; + u16_t hop_count; +}; + +int uaodv_rt_add(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, + u16_t hop_count, u32_t seqno); +struct uaodv_rt_entry *uaodv_rt_lookup(uip_ipaddr_t *dest); +void uaodv_rt_remove(struct uaodv_rt_entry *e); +void uaodv_rt_flush_all(void); + +#endif /* __UAODV_RT_H__ */ diff --git a/core/net/uaodv.c b/core/net/uaodv.c new file mode 100644 index 000000000..e77cdcab0 --- /dev/null +++ b/core/net/uaodv.c @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uaodv.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Micro implementation of the AODV ad hoc routing protocol + * \author + * Adam Dunkels + */ + + +#include +#include + +#include "contiki.h" +#include "net/uaodv-def.h" +#include "net/uaodv-rt.h" + +#ifdef TMOTE_SKY +#include "dev/cc2420.h" +#endif + +#define MY_ROUTE_TIMEOUT 0 + +PROCESS(uaodv_process, "uAODV"); + +static struct uip_udp_conn *aodvconn, *unicastconn; + +static u32_t rreq_id, rreq_seqno; + +static uip_ipaddr_t last_rreq_originator; +static u32_t last_rreq_id; + + +#define ip2quad(p) uip_ipaddr1(p),uip_ipaddr2(p),uip_ipaddr3(p),uip_ipaddr4(p) + +#if 1 +#define print_debug(...) do{}while(0) +#else +static void +print_debug(const char *fmt, ...) +{ +#if 1 + va_list ap; + + va_start(ap, fmt); + printf("%d.%d.%d.%d: ", ip2quad(&uip_hostaddr)); + vprintf(fmt, ap); + va_end(ap); +#endif + return; +} +#endif + +#define uip_udp_sender() ((uip_ipaddr_t *)(((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcipaddr)) + +uip_ipaddr_t inaddr_broadcast = { 0xffff, 0xffff }; + +/*---------------------------------------------------------------------------*/ +static void +sendto(uip_ipaddr_t *dest, char *buf, int len) +{ + /* XXX: this is a HACK! We're updating the uIP UDP connection + "unicastconn" so that the destination address is the next-hop, + and we're patching the "uip_udp_conn" variable so that it points + the this connection instead. THIS IS NOT A NICE WAY TO DO THIS, + but it is currently nicer than the alternative (requesting a new + poll, and remembering the state, etc.). */ + + uip_ipaddr_copy(&unicastconn->ripaddr, dest); + uip_udp_conn = unicastconn; + uip_send(buf, len); +} +/*---------------------------------------------------------------------------*/ +static void +send_rreq(uip_ipaddr_t *addr) +{ + struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata; + + rm->type = UAODV_RREQ_TYPE; + rm->flags = UAODV_RREQ_UNKSEQNO; + rm->reserved = 0; + rm->hop_count = 0; + rm->rreq_id = rreq_id; + uip_ipaddr_copy(&rm->dest_addr, addr); + rm->dest_seqno = 0; + uip_gethostaddr(&rm->src_addr); + rm->src_seqno = rreq_seqno; + uip_send((char *)rm, sizeof(struct uaodv_msg_rreq)); + + ++rreq_seqno; + ++rreq_id; + + uip_ipaddr_copy(&last_rreq_originator, &rm->src_addr); + last_rreq_id = rm->rreq_id; +} +/*---------------------------------------------------------------------------*/ +static void +send_rrep(uip_ipaddr_t *dst, uip_ipaddr_t *nexthop, uip_ipaddr_t *src, u32_t seqno) +{ + struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata; + + rm->type = UAODV_RREP_TYPE; + rm->flags = 0; + rm->reserved = 0; + rm->hop_count = 0; + uip_ipaddr_copy(&rm->src_addr, src); + rm->dest_seqno = seqno; + uip_ipaddr_copy(&rm->dest_addr, dst); + rm->lifetime = MY_ROUTE_TIMEOUT; + sendto(nexthop, (char *)rm, sizeof(struct uaodv_msg_rrep)); + + print_debug("Sending RREP to %d.%d.%d.%d\n", + uip_ipaddr1(nexthop), + uip_ipaddr2(nexthop), + uip_ipaddr3(nexthop), + uip_ipaddr4(nexthop)); + + +} +/*---------------------------------------------------------------------------*/ +#ifdef UAODV_BAD_ROUTE +static void +send_rerr(uip_ipaddr_t *addr, u32_t seqno) +{ + struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata; + + rm->type = UAODV_RERR_TYPE; + rm->flags = 0; + rm->reserved = 0; + rm->dest_count = 1; + uip_ipaddr_copy(&rm->unreach[0].addr, addr); + rm->unreach[0].seqno = seqno; + + sendto(&inaddr_broadcast, (char *)rm, sizeof(struct uaodv_msg_rerr)); + + print_debug("Broadcasting initial RERR for %d.%d.%d.%d\n", ip2quad(addr)); +} +#endif +/*---------------------------------------------------------------------------*/ +static void +handle_incoming_rreq(void) +{ + struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata; + uip_ipaddr_t dest_addr, src_addr; + struct uaodv_rt_entry *rt; + +#ifdef TMOTE_SKY + if(cc2420_last_rssi <= -38 || cc2420_last_correlation < 100) { + printf("RREQ drop from %d.%d.%d.%d %d %d \n", + uip_ipaddr1(uip_udp_sender()), + uip_ipaddr2(uip_udp_sender()), + uip_ipaddr3(uip_udp_sender()), + uip_ipaddr4(uip_udp_sender()), + cc2420_last_rssi, + cc2420_last_correlation); + return; + } +#endif + + /* Check if it is for our address. */ + if(uip_ipaddr_cmp(&rm->dest_addr, uip_hostaddr)) { + print_debug("RREQ for our address!\n"); + rt = uaodv_rt_lookup(&rm->src_addr); + if(rt == NULL || rm->hop_count <= rt->hop_count) { + /* Insert originator into routing table. */ + print_debug("Inserting1 %d.%d.%d.%d into routing table, next hop %d.%d.%d.%d., hop_count %d\n", + uip_ipaddr1(&rm->src_addr), + uip_ipaddr2(&rm->src_addr), + uip_ipaddr3(&rm->src_addr), + uip_ipaddr4(&rm->src_addr), + uip_ipaddr1(uip_udp_sender()), + uip_ipaddr2(uip_udp_sender()), + uip_ipaddr3(uip_udp_sender()), + uip_ipaddr4(uip_udp_sender()), + rm->hop_count); + uaodv_rt_add(&rm->src_addr, uip_udp_sender(), rm->hop_count, 0); + } + + /* Send an RREP back to the source of the RREQ. */ + uip_ipaddr_copy( &dest_addr, &rm->dest_addr ); + uip_ipaddr_copy( &src_addr, &rm->src_addr ); + send_rrep(&dest_addr, uip_udp_sender(), &src_addr, rm->src_seqno); + } else if(!uip_ipaddr_cmp(&last_rreq_originator, &rm->src_addr) || + last_rreq_id != rm->rreq_id) { + print_debug("RREQ for %d.%d.%d.%d!\n", + uip_ipaddr1(&rm->dest_addr), + uip_ipaddr2(&rm->dest_addr), + uip_ipaddr3(&rm->dest_addr), + uip_ipaddr4(&rm->dest_addr)); + rt = uaodv_rt_lookup(&rm->src_addr); + if(rt == NULL || rm->hop_count <= rt->hop_count) { + /* Insert originator into routing table. */ + print_debug("Inserting2 %d.%d.%d.%d into routing table, next hop %d.%d.%d.%d., hop_count %d\n", + uip_ipaddr1(&rm->src_addr), + uip_ipaddr2(&rm->src_addr), + uip_ipaddr3(&rm->src_addr), + uip_ipaddr4(&rm->src_addr), + uip_ipaddr1(uip_udp_sender()), + uip_ipaddr2(uip_udp_sender()), + uip_ipaddr3(uip_udp_sender()), + uip_ipaddr4(uip_udp_sender()), + rm->hop_count); + uaodv_rt_add(&rm->src_addr, uip_udp_sender(), rm->hop_count, 0); + } + + /* Forward RREQ. XXX to be compliant, we should check the TTL + of the incoming packet and forward only if TTL > 1. We + should also set the TTL in our outgoing IP header too, but + there currently is no way of doing this in Contiki so we + don't do it at the moment. */ + + print_debug("Forwarding RREQ to %d.%d.%d.%d ttl=%d\n", + uip_ipaddr1(&rm->src_addr), + uip_ipaddr2(&rm->src_addr), + uip_ipaddr3(&rm->src_addr), + uip_ipaddr4(&rm->src_addr), + uip_udp_conn->ttl); + + uip_ipaddr_copy(&last_rreq_originator, &rm->src_addr); + last_rreq_id = rm->rreq_id; + rm->hop_count++; + uip_send((char *)rm, sizeof(struct uaodv_msg_rreq)); + } else { + print_debug("Not forwarding rreq last_rreq_originator %d.%d.%d.%d src_addr %d.%d.%d.%d, last_rreq_id %d rreq_id %d\n", + uip_ipaddr1(&last_rreq_originator), + uip_ipaddr2(&last_rreq_originator), + uip_ipaddr3(&last_rreq_originator), + uip_ipaddr4(&last_rreq_originator), + uip_ipaddr1(&rm->src_addr), + uip_ipaddr2(&rm->src_addr), + uip_ipaddr3(&rm->src_addr), + uip_ipaddr4(&rm->src_addr), + last_rreq_id, rm->rreq_id); + } +} +/*---------------------------------------------------------------------------*/ +static void +handle_incoming_rrep(void) +{ + struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata; + struct uaodv_rt_entry *rt; + + print_debug("RREP received\n"); + + /* Check if we have another route to this destination. If so, we'll + use the new one if the hop count is lower, and if the sequence + number say we should. */ + rt = uaodv_rt_lookup(&rm->dest_addr); + if(rt == NULL || + (rt->hop_count > rm->hop_count /* && seqno < seqno */)) { + + /* Insert originator into routing table. */ + print_debug("Inserting3 %d.%d.%d.%d into routing table, next hop %d.%d.%d.%d, hop_count %d.\n", + uip_ipaddr1(&rm->dest_addr), + uip_ipaddr2(&rm->dest_addr), + uip_ipaddr3(&rm->dest_addr), + uip_ipaddr4(&rm->dest_addr), + uip_ipaddr1(uip_udp_sender()), + uip_ipaddr2(uip_udp_sender()), + uip_ipaddr3(uip_udp_sender()), + uip_ipaddr4(uip_udp_sender()), rm->hop_count + ); + uaodv_rt_add(&rm->dest_addr, uip_udp_sender(), rm->hop_count, 0); +#ifdef TMOTE_SKY + /* This link is ok since he is unicasting back to us! */ + cc2420_recv_ok(uip_udp_sender()); + printf("RREP recv ok from %d.%d.%d.%d %d %d \n", + uip_ipaddr1(uip_udp_sender()), + uip_ipaddr2(uip_udp_sender()), + uip_ipaddr3(uip_udp_sender()), + uip_ipaddr4(uip_udp_sender()), + cc2420_last_rssi, + cc2420_last_correlation); +#endif + + } else { + print_debug("Not inserting %d.%d.%d.%d into routing table, next hop %d.%d.%d.%d, hop_count %d.\n", + uip_ipaddr1(&rm->dest_addr), + uip_ipaddr2(&rm->dest_addr), + uip_ipaddr3(&rm->dest_addr), + uip_ipaddr4(&rm->dest_addr), + uip_ipaddr1(uip_udp_sender()), + uip_ipaddr2(uip_udp_sender()), + uip_ipaddr3(uip_udp_sender()), + uip_ipaddr4(uip_udp_sender()), rm->hop_count + ); + + } + if(uip_ipaddr_cmp(&rm->src_addr, uip_hostaddr)) { + print_debug("------- COMPLETE ROUTE FOUND\n"); + } else { + + /* print_debug("Sending back to originator\n"); + + print_debug("Route lookup for %d.%d.%d.%d\n", + uip_ipaddr1(&rm->src_addr), + uip_ipaddr2(&rm->src_addr), + uip_ipaddr3(&rm->src_addr), + uip_ipaddr4(&rm->src_addr));*/ + + rt = uaodv_rt_lookup(&rm->src_addr); + + if(rt == NULL) { + print_debug("RREP received, but no route back to originator... :-( \n"); + return; + } + + rm->hop_count++; + + print_debug("Sending RREP to %d.%d.%d.%d\n", + uip_ipaddr1(&rt->nexthop), + uip_ipaddr2(&rt->nexthop), + uip_ipaddr3(&rt->nexthop), + uip_ipaddr4(&rt->nexthop)); + + sendto(&rt->nexthop, (char *)rm, sizeof(struct uaodv_msg_rrep)); + + /* print_debug("RREP forwarded\n");*/ + } +} +/*---------------------------------------------------------------------------*/ +#ifdef UAODV_BAD_ROUTE +static void +handle_incoming_rerr(void) +{ + struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata; + struct uaodv_rt_entry *rt; + + print_debug("RERR received from %d.%d.%d.%d route to %d.%d.%d.%d seq=%d\n", + ip2quad(uip_udp_sender()), + ip2quad(&rm->unreach[0].addr), rm->unreach[0].seqno); + + rt = uaodv_rt_lookup(&rm->unreach[0].addr); + if(rt != NULL && uip_ipaddr_cmp(&rt->nexthop, uip_udp_sender())) { + uaodv_rt_remove(rt); + print_debug("RERR rebroadcast\n"); + sendto(&inaddr_broadcast, (char *)rm, sizeof(struct uaodv_msg_rerr)); + } +} +#endif +/*---------------------------------------------------------------------------*/ +static void +handle_incoming_packet(void) +{ + struct uaodv_msg *m = (struct uaodv_msg *)uip_appdata; + + /* print_debug("New UDP data, AODV packet type %d\n", m->type);*/ + switch(m->type) { + case UAODV_RREQ_TYPE: + handle_incoming_rreq(); + break; + + case UAODV_RREP_TYPE: + handle_incoming_rrep(); + break; + +#ifdef UAODV_BAD_ROUTE + case UAODV_RERR_TYPE: + handle_incoming_rerr(); + break; +#endif + } + +} +/*---------------------------------------------------------------------------*/ +static enum { + COMMAND_NONE, + COMMAND_SEND_RREQ, + COMMAND_SEND_RERR, +} command; + +#ifdef UAODV_BAD_ROUTE +static uip_ipaddr_t bad_nexthop; +u32_t bad_seqno; + +void +uaodv_bad_route(struct uaodv_rt_entry *rt) +{ + uip_ipaddr_copy(&bad_nexthop, &rt->nexthop); + bad_seqno = rt->seqno; + command = COMMAND_SEND_RERR; + process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL); +} +#endif + +static uip_ipaddr_t rreq_addr; +static struct timer next_time; + +struct uaodv_rt_entry * +uaodv_request_route_to(uip_ipaddr_t *host) +{ + struct uaodv_rt_entry *route = uaodv_rt_lookup(host); + + if(route != NULL) { + return route; + } + + /* + * Broadcast protocols must be rate-limited! + */ + if(!timer_expired(&next_time)) { + return NULL; + } + + if(command != COMMAND_NONE) { + return NULL; + } + + uip_ipaddr_copy(&rreq_addr, host); + command = COMMAND_SEND_RREQ; + process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL); + timer_set(&next_time, CLOCK_SECOND/4); /* Max 10/s per RFC3561. */ + return NULL; +} + +PROCESS_THREAD(uaodv_process, ev, data) +{ + PROCESS_EXITHANDLER(goto exit); + + PROCESS_BEGIN(); + + printf("uaodv_process starting\n"); + + aodvconn = udp_broadcast_new(HTONS(UAODV_UDPPORT), NULL); + aodvconn->ttl = 1; + unicastconn = udp_broadcast_new(HTONS(UAODV_UDPPORT), NULL); + unicastconn->ttl = 1; + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == tcpip_event) { + if(uip_newdata()) { + handle_incoming_packet(); + continue; + } + if(uip_poll()) { + if(command == COMMAND_SEND_RREQ) + send_rreq(&rreq_addr); +#ifdef UAODV_BAD_ROUTE + else if (command == COMMAND_SEND_RERR) + send_rerr(&bad_nexthop, bad_seqno); +#endif + command = COMMAND_NONE; + continue; + } + } + + if(ev == PROCESS_EVENT_MSG) { + tcpip_poll_udp(aodvconn); + } + } + + exit: + command = COMMAND_NONE; + uaodv_rt_flush_all(); + uip_udp_remove(aodvconn); + aodvconn = NULL; + uip_udp_remove(unicastconn); + unicastconn = NULL; + printf("uaodv_process exiting\n"); + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/uaodv.h b/core/net/uaodv.h new file mode 100644 index 000000000..8c71915e5 --- /dev/null +++ b/core/net/uaodv.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uaodv.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __UAODV_H__ +#define __UAODV_H__ + +#include "contiki.h" + +PROCESS_NAME(uaodv_process); + +struct uaodv_rt_entry * uaodv_request_route_to(uip_ipaddr_t *host); +void uaodv_bad_route(struct uaodv_rt_entry *rt); + +#endif /* __UAODV_H__ */ diff --git a/core/net/uip-fw-service.c b/core/net/uip-fw-service.c new file mode 100644 index 000000000..3062fa8d9 --- /dev/null +++ b/core/net/uip-fw-service.c @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uip-fw-service.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +#include "net/packet-service.h" + +#include "net/uip-fw.h" + +SERVICE(uip_fw_service, packet_service, { uip_fw_output }); + +/*---------------------------------------------------------------------------*/ + +PROCESS(uip_fw_process, "IP forwarding"); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(uip_fw_process, ev, data) +{ + PROCESS_BEGIN(); + + PROCESS_SET_FLAGS(PROCESS_NO_BROADCAST); + + SERVICE_REGISTER(uip_fw_service); + + PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT || + ev == PROCESS_EVENT_SERVICE_REMOVED); + + SERVICE_REMOVE(uip_fw_service); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/uip-fw-service.h b/core/net/uip-fw-service.h new file mode 100644 index 000000000..f4b87f13e --- /dev/null +++ b/core/net/uip-fw-service.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uip-fw-service.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ +#ifndef __UIP_FW_SERVICE_H__ +#define __UIP_FW_SERVICE_H__ + +#include "contiki.h" +#include "net/uip-fw.h" + +PROCESS_NAME(uip_fw_process); + +#endif /* __UIP_FW_SERVICE_H__ */ diff --git a/core/net/uip-fw.c b/core/net/uip-fw.c new file mode 100644 index 000000000..739ca1ea8 --- /dev/null +++ b/core/net/uip-fw.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uip-fw.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipfw uIP packet forwarding + * @{ + * + */ + +/** + * \file + * uIP packet forwarding. + * \author Adam Dunkels + * + * This file implements a number of simple functions which do packet + * forwarding over multiple network interfaces with uIP. + * + */ + +#include "net/uip.h" +#include "net/uip_arch.h" +#include "net/uip-fw.h" +#include "contiki-conf.h" + +#include /* for memcpy() */ + +/* + * The list of registered network interfaces. + */ +static struct uip_fw_netif *netifs = NULL; + +/* + * A pointer to the default network interface. + */ +static struct uip_fw_netif *defaultnetif = NULL; + +struct tcpip_hdr { + /* IP header. */ + u8_t vhl, + tos; + u16_t len, + ipid, + ipoffset; + u8_t ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; + + /* TCP header. */ + u16_t srcport, + destport; + u8_t seqno[4], + ackno[4], + tcpoffset, + flags, + wnd[2]; + u16_t tcpchksum; + u8_t urgp[2]; + u8_t optdata[4]; +}; + +struct icmpip_hdr { + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; + /* ICMP (echo) header. */ + u8_t type, icode; + u16_t icmpchksum; + u16_t id, seqno; + u8_t payload[1]; +}; + +/* ICMP ECHO. */ +#define ICMP_ECHO 8 + +/* ICMP TIME-EXCEEDED. */ +#define ICMP_TE 11 + +/* + * Pointer to the TCP/IP headers of the packet in the uip_buf buffer. + */ +#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/* + * Pointer to the ICMP/IP headers of the packet in the uip_buf buffer. + */ +#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/* + * Certain fields of an IP packet that are used for identifying + * duplicate packets. + */ +struct fwcache_entry { + u16_t timer; + + u16_t srcipaddr[2]; + u16_t destipaddr[2]; + u16_t ipid; + u8_t proto; + u8_t unused; + +#if notdef + u16_t payload[2]; +#endif + +#if UIP_REASSEMBLY > 0 + u16_t len, offset; +#endif +}; + +/* + * The number of packets to remember when looking for duplicates. + */ +#ifdef UIP_CONF_FWCACHE_SIZE +#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE +#else +#define FWCACHE_SIZE 2 +#endif + + +/* + * A cache of packet header fields which are used for + * identifying duplicate packets. + */ +static struct fwcache_entry fwcache[FWCACHE_SIZE]; + +/** + * \internal + * The time that a packet cache is active. + */ +#define FW_TIME 20 + +/*------------------------------------------------------------------------------*/ +/** + * Initialize the uIP packet forwarding module. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_init(void) +{ + struct uip_fw_netif *t; + defaultnetif = NULL; + while(netifs != NULL) { + t = netifs; + netifs = netifs->next; + t->next = NULL; + } +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Check if an IP address is within the network defined by an IP + * address and a netmask. + * + * \param ipaddr The IP address to be checked. + * \param netipaddr The IP address of the network. + * \param netmask The netmask of the network. + * + * \return Non-zero if IP address is in network, zero otherwise. + */ +/*------------------------------------------------------------------------------*/ +static unsigned char +ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask) +{ + return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) && + (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]); +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Send out an ICMP TIME-EXCEEDED message. + * + * This function replaces the packet in the uip_buf buffer with the + * ICMP packet. + */ +/*------------------------------------------------------------------------------*/ +static void +time_exceeded(void) +{ + u16_t tmp16; + + /* We don't send out ICMP errors for ICMP messages. */ + if(ICMPBUF->proto == UIP_PROTO_ICMP) { + uip_len = 0; + return; + } + /* Copy fields from packet header into payload of this ICMP packet. */ + memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28); + + /* Set the ICMP type and code. */ + ICMPBUF->type = ICMP_TE; + ICMPBUF->icode = 0; + + /* Calculate the ICMP checksum. */ + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36); + + /* Set the IP destination address to be the source address of the + original packet. */ + tmp16= BUF->destipaddr[0]; + BUF->destipaddr[0] = BUF->srcipaddr[0]; + BUF->srcipaddr[0] = tmp16; + tmp16 = BUF->destipaddr[1]; + BUF->destipaddr[1] = BUF->srcipaddr[1]; + BUF->srcipaddr[1] = tmp16; + + /* Set our IP address as the source address. */ + BUF->srcipaddr[0] = uip_hostaddr[0]; + BUF->srcipaddr[1] = uip_hostaddr[1]; + + /* The size of the ICMP time exceeded packet is 36 + the size of the + IP header (20) = 56. */ + uip_len = 56; + ICMPBUF->len[0] = 0; + ICMPBUF->len[1] = uip_len; + + /* Fill in the other fields in the IP header. */ + ICMPBUF->vhl = 0x45; + ICMPBUF->tos = 0; + ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0; + ICMPBUF->ttl = UIP_TTL; + ICMPBUF->proto = UIP_PROTO_ICMP; + + /* Calculate IP checksum. */ + ICMPBUF->ipchksum = 0; + ICMPBUF->ipchksum = ~(uip_ipchksum()); + + +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Register a packet in the forwarding cache so that it won't be + * forwarded again. + */ +/*------------------------------------------------------------------------------*/ +static void +fwcache_register(void) +{ + struct fwcache_entry *fw; + int i, oldest; + + oldest = FW_TIME; + fw = NULL; + + /* Find the oldest entry in the cache. */ + for(i = 0; i < FWCACHE_SIZE; ++i) { + if(fwcache[i].timer == 0) { + fw = &fwcache[i]; + break; + } else if(fwcache[i].timer <= oldest) { + fw = &fwcache[i]; + oldest = fwcache[i].timer; + } + } + + fw->timer = FW_TIME; + fw->ipid = BUF->ipid; + fw->srcipaddr[0] = BUF->srcipaddr[0]; + fw->srcipaddr[1] = BUF->srcipaddr[1]; + fw->destipaddr[0] = BUF->destipaddr[0]; + fw->destipaddr[1] = BUF->destipaddr[1]; + fw->proto = BUF->proto; +#if notdef + fw->payload[0] = BUF->srcport; + fw->payload[1] = BUF->destport; +#endif +#if UIP_REASSEMBLY > 0 + fw->len = BUF->len; + fw->offset = BUF->ipoffset; +#endif +} +/*------------------------------------------------------------------------------*/ +/** + * \internal + * Find a network interface for the IP packet in uip_buf. + */ +/*------------------------------------------------------------------------------*/ +static struct uip_fw_netif * +find_netif(void) +{ + struct uip_fw_netif *netif; + + /* Walk through every network interface to check for a match. */ + for(netif = netifs; netif != NULL; netif = netif->next) { + if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr, + netif->netmask)) { + /* If there was a match, we break the loop. */ + return netif; + } + } + + /* If no matching netif was found, we use default netif. */ + return defaultnetif; +} +/*------------------------------------------------------------------------------*/ +/** + * Output an IP packet on the correct network interface. + * + * The IP packet should be present in the uip_buf buffer and its + * length in the global uip_len variable. + * + * \retval UIP_FW_ZEROLEN Indicates that a zero-length packet + * transmission was attempted and that no packet was sent. + * + * \retval UIP_FW_NOROUTE No suitable network interface could be found + * for the outbound packet, and the packet was not sent. + * + * \return The return value from the actual network interface output + * function is passed unmodified as a return value. + */ +/*------------------------------------------------------------------------------*/ +u8_t +uip_fw_output(void) +{ + struct uip_fw_netif *netif; + + if(uip_len == 0) { + return UIP_FW_ZEROLEN; + } + + fwcache_register(); + +#if UIP_BROADCAST + /* Link local broadcasts go out on all interfaces. */ + if(/*BUF->proto == UIP_PROTO_UDP &&*/ + BUF->destipaddr[0] == 0xffff && + BUF->destipaddr[1] == 0xffff) { + if(defaultnetif != NULL) { + defaultnetif->output(); + } + for(netif = netifs; netif != NULL; netif = netif->next) { + netif->output(); + } + return UIP_FW_OK; + } +#endif /* UIP_BROADCAST */ + + netif = find_netif(); + /* printf("uip_fw_output: netif %p ->output %p len %d\n", netif, + netif->output, + uip_len);*/ + + if(netif == NULL) { + return UIP_FW_NOROUTE; + } + /* If we now have found a suitable network interface, we call its + output function to send out the packet. */ + return netif->output(); +} +/*------------------------------------------------------------------------------*/ +/** + * Forward an IP packet in the uip_buf buffer. + * + * + * + * \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if + * the packet should be processed locally. + */ +/*------------------------------------------------------------------------------*/ +u8_t +uip_fw_forward(void) +{ + struct fwcache_entry *fw; + + /* First check if the packet is destined for ourselves and return 0 + to indicate that the packet should be processed locally. */ + if(BUF->destipaddr[0] == uip_hostaddr[0] && + BUF->destipaddr[1] == uip_hostaddr[1]) { + return UIP_FW_LOCAL; + } + + /* If we use ping IP address configuration, and our IP address is + not yet configured, we should intercept all ICMP echo packets. */ +#if UIP_PINGADDRCONF + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 && + BUF->proto == UIP_PROTO_ICMP && + ICMPBUF->type == ICMP_ECHO) { + return UIP_FW_LOCAL; + } +#endif /* UIP_PINGADDRCONF */ + + /* Check if the packet is in the forwarding cache already, and if so + we drop it. */ + + for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { + if(fw->timer != 0 && +#if UIP_REASSEMBLY > 0 + fw->len == BUF->len && + fw->offset == BUF->ipoffset && +#endif + fw->ipid == BUF->ipid && + fw->srcipaddr[0] == BUF->srcipaddr[0] && + fw->srcipaddr[1] == BUF->srcipaddr[1] && + fw->destipaddr[0] == BUF->destipaddr[0] && + fw->destipaddr[1] == BUF->destipaddr[1] && +#if notdef + fw->payload[0] == BUF->srcport && + fw->payload[1] == BUF->destport && +#endif + fw->proto == BUF->proto) { + /* Drop packet. */ + return UIP_FW_FORWARDED; + } + } + + /* If the TTL reaches zero we produce an ICMP time exceeded message + in the uip_buf buffer and forward that packet back to the sender + of the packet. */ + if(BUF->ttl <= 1) { + /* No time exceeded for broadcasts and multicasts! */ + if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { + return UIP_FW_LOCAL; + } + time_exceeded(); + } + + /* Decrement the TTL (time-to-live) value in the IP header */ + BUF->ttl = BUF->ttl - 1; + + /* Update the IP checksum. */ + if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1; + } else { + BUF->ipchksum = BUF->ipchksum + HTONS(0x0100); + } + + if(uip_len > 0) { + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]; + uip_fw_output(); + } + +#if UIP_BROADCAST + if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) { + return UIP_FW_LOCAL; + } +#endif /* UIP_BROADCAST */ + + /* Return non-zero to indicate that the packet was forwarded and that no + other processing should be made. */ + return UIP_FW_FORWARDED; +} +/*------------------------------------------------------------------------------*/ +/** + * Register a network interface with the forwarding module. + * + * \param netif A pointer to the network interface that is to be + * registered. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_register(struct uip_fw_netif *netif) +{ + netif->next = netifs; + netifs = netif; +} +/*------------------------------------------------------------------------------*/ +/** + * Register a default network interface. + * + * All packets that don't go out on any of the other interfaces will + * be routed to the default interface. + * + * \param netif A pointer to the network interface that is to be + * registered. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_default(struct uip_fw_netif *netif) +{ + defaultnetif = netif; +} +/*------------------------------------------------------------------------------*/ +/** + * Perform periodic processing. + */ +/*------------------------------------------------------------------------------*/ +void +uip_fw_periodic(void) +{ + struct fwcache_entry *fw; + for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) { + if(fw->timer > 0) { + --fw->timer; + } + } +} +/*------------------------------------------------------------------------------*/ +/** @} */ +/** @} */ diff --git a/core/net/uip-fw.h b/core/net/uip-fw.h new file mode 100644 index 000000000..43c432d49 --- /dev/null +++ b/core/net/uip-fw.h @@ -0,0 +1,176 @@ +/** + * \addtogroup uipfw + * @{ + */ + +/** + * \file + * uIP packet forwarding header file. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uip-fw.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ +#ifndef __UIP_FW_H__ +#define __UIP_FW_H__ + +#include "net/uip.h" + +/** + * Representation of a uIP network interface. + */ +struct uip_fw_netif { + struct uip_fw_netif *next; /**< Pointer to the next interface when + linked in a list. */ + u16_t ipaddr[2]; /**< The IP address of this interface. */ + u16_t netmask[2]; /**< The netmask of the interface. */ + u8_t (* output)(void); + /**< A pointer to the function that + sends a packet. */ +}; + +/** + * Intantiating macro for a uIP network interface. + * + * Example: + \code + struct uip_fw_netif slipnetif = + {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)}; + \endcode + * \param ip1,ip2,ip3,ip4 The IP address of the network interface. + * + * \param nm1,nm2,nm3,nm4 The netmask of the network interface. + * + * \param outputfunc A pointer to the output function of the network interface. + * + * \hideinitializer + */ +#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \ + NULL, \ + {HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \ + {HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \ + outputfunc + +/** + * Set the IP address of a network interface. + * + * \param netif A pointer to the uip_fw_netif structure for the network interface. + * + * \param addr A pointer to an IP address. + * + * \hideinitializer + */ +#define uip_fw_setipaddr(netif, addr) \ + do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \ + (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0) +/** + * Set the netmask of a network interface. + * + * \param netif A pointer to the uip_fw_netif structure for the network interface. + * + * \param addr A pointer to an IP address representing the netmask. + * + * \hideinitializer + */ +#define uip_fw_setnetmask(netif, addr) \ + do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \ + (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0) + +void uip_fw_init(void); +u8_t uip_fw_forward(void); +u8_t uip_fw_output(void); +void uip_fw_register(struct uip_fw_netif *netif); +void uip_fw_default(struct uip_fw_netif *netif); +void uip_fw_periodic(void); + + +/** + * A non-error message that indicates that a packet should be + * processed locally. + * + * \hideinitializer + */ +#define UIP_FW_LOCAL 0 + +/** + * A non-error message that indicates that something went OK. + * + * \hideinitializer + */ +#define UIP_FW_OK 0 + +/** + * A non-error message that indicates that a packet was forwarded. + * + * \hideinitializer + */ +#define UIP_FW_FORWARDED 1 + +/** + * A non-error message that indicates that a zero-length packet + * transmission was attempted, and that no packet was sent. + * + * \hideinitializer + */ +#define UIP_FW_ZEROLEN 2 + +/** + * An error message that indicates that a packet that was too large + * for the outbound network interface was detected. + * + * \hideinitializer + */ +#define UIP_FW_TOOLARGE 3 + +/** + * An error message that indicates that no suitable interface could be + * found for an outbound packet. + * + * \hideinitializer + */ +#define UIP_FW_NOROUTE 4 + +/** + * An error message that indicates that a packet that should be + * forwarded or output was dropped. + * + * \hideinitializer + */ +#define UIP_FW_DROPPED 5 + + +#endif /* __UIP_FW_H__ */ + +/** @} */ diff --git a/core/net/uip-neighbor.c b/core/net/uip-neighbor.c new file mode 100644 index 000000000..5e5f63295 --- /dev/null +++ b/core/net/uip-neighbor.c @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uip-neighbor.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Database of link-local neighbors, used by IPv6 code and + * to be used by a future ARP code rewrite. + * \author + * Adam Dunkels + */ + +#include "net/uip-neighbor.h" + +#include + +#define MAX_TIME 128 + +#ifdef UIP_NEIGHBOR_CONF_ENTRIES +#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES +#else /* UIP_NEIGHBOR_CONF_ENTRIES */ +#define ENTRIES 8 +#endif /* UIP_NEIGHBOR_CONF_ENTRIES */ + +struct neighbor_entry { + uip_ipaddr_t ipaddr; + struct uip_neighbor_addr addr; + u8_t time; +}; +static struct neighbor_entry entries[ENTRIES]; + +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_init(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + entries[i].time = MAX_TIME; + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_periodic(void) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time < MAX_TIME) { + entries[i].time++; + } + } +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr) +{ + int i, oldest; + u8_t oldest_time; + + printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3], + addr->addr.addr[4], addr->addr.addr[5]); + + /* Find the first unused entry or the oldest used entry. */ + oldest_time = 0; + oldest = 0; + for(i = 0; i < ENTRIES; ++i) { + if(entries[i].time == MAX_TIME) { + oldest = i; + break; + } + if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) { + oldest = i; + break; + } + if(entries[i].time > oldest_time) { + oldest = i; + oldest_time = entries[i].time; + } + } + + /* Use the oldest or first free entry (either pointed to by the + "oldest" variable). */ + entries[oldest].time = 0; + uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr); + memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr)); +} +/*---------------------------------------------------------------------------*/ +static struct neighbor_entry * +find_entry(uip_ipaddr_t ipaddr) +{ + int i; + + for(i = 0; i < ENTRIES; ++i) { + if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) { + return &entries[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +uip_neighbor_update(uip_ipaddr_t ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + e->time = 0; + } +} +/*---------------------------------------------------------------------------*/ +struct uip_neighbor_addr * +uip_neighbor_lookup(uip_ipaddr_t ipaddr) +{ + struct neighbor_entry *e; + + e = find_entry(ipaddr); + if(e != NULL) { + /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n", + e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3], + e->addr.addr.addr[4], e->addr.addr.addr[5]);*/ + + return &e->addr; + } + return NULL; +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/uip-neighbor.h b/core/net/uip-neighbor.h new file mode 100644 index 000000000..3b9cfb88e --- /dev/null +++ b/core/net/uip-neighbor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: uip-neighbor.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Header file for database of link-local neighbors, used by + * IPv6 code and to be used by future ARP code. + * \author + * Adam Dunkels + */ + +#ifndef __UIP_NEIGHBOR_H__ +#define __UIP_NEIGHBOR_H__ + +#include "net/uip.h" + +struct uip_neighbor_addr { +#if UIP_NEIGHBOR_CONF_ADDRTYPE + UIP_NEIGHBOR_CONF_ADDRTYPE addr; +#else + struct uip_eth_addr addr; +#endif +}; + +void uip_neighbor_init(void); +void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr); +void uip_neighbor_update(uip_ipaddr_t ipaddr); +struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr); +void uip_neighbor_periodic(void); + +#endif /* __UIP-NEIGHBOR_H__ */ diff --git a/core/net/uip-split.c b/core/net/uip-split.c new file mode 100644 index 000000000..993a6be03 --- /dev/null +++ b/core/net/uip-split.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uip-split.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +#include + +#include "net/uip-split.h" +#include "net/uip.h" +#include "net/uip-fw.h" +#include "net/uip_arch.h" + +#include "net/tcpip.h" + +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +/*-----------------------------------------------------------------------------*/ +void +uip_split_output(void) +{ + u16_t tcplen, len1, len2; + + /* We only try to split maximum sized TCP segments. */ + if(BUF->proto == UIP_PROTO_TCP && + uip_len == UIP_BUFSIZE - UIP_LLH_LEN) { + + tcplen = uip_len - UIP_TCPIP_HLEN; + /* Split the segment in two. If the original packet length was + odd, we make the second packet one byte larger. */ + len1 = len2 = tcplen / 2; + if(len1 + len2 < tcplen) { + ++len2; + } + + /* Create the first packet. This is done by altering the length + field of the IP header and updating the checksums. */ + uip_len = len1 + UIP_TCPIP_HLEN; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = uip_len >> 8; + BUF->len[1] = uip_len & 0xff; +#endif /* UIP_CONF_IPV6 */ + + /* Recalculate the TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + +#if !UIP_CONF_IPV6 + /* Recalculate the IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + /* Transmit the first packet. */ + /* uip_fw_output();*/ + tcpip_output(); + + /* Now, create the second packet. To do this, it is not enough to + just alter the length field, but we must also update the TCP + sequence number and point the uip_appdata to a new place in + memory. This place is detemined by the length of the first + packet (len1). */ + uip_len = len2 + UIP_TCPIP_HLEN; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = uip_len >> 8; + BUF->len[1] = uip_len & 0xff; +#endif /* UIP_CONF_IPV6 */ + + /* uip_appdata += len1;*/ + memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2); + + uip_add32(BUF->seqno, len1); + BUF->seqno[0] = uip_acc32[0]; + BUF->seqno[1] = uip_acc32[1]; + BUF->seqno[2] = uip_acc32[2]; + BUF->seqno[3] = uip_acc32[3]; + + /* Recalculate the TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + +#if !UIP_CONF_IPV6 + /* Recalculate the IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + /* Transmit the second packet. */ + /* uip_fw_output();*/ + tcpip_output(); + } else { + /* uip_fw_output();*/ + tcpip_output(); + } + +} +/*-----------------------------------------------------------------------------*/ diff --git a/core/net/uip-split.h b/core/net/uip-split.h new file mode 100644 index 000000000..a8d4e9d89 --- /dev/null +++ b/core/net/uip-split.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uip-split.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uipsplit uIP TCP throughput booster hack + * @{ + * + * The basic uIP TCP implementation only allows each TCP connection to + * have a single TCP segment in flight at any given time. Because of + * the delayed ACK algorithm employed by most TCP receivers, uIP's + * limit on the amount of in-flight TCP segments seriously reduces the + * maximum achievable throughput for sending data from uIP. + * + * The uip-split module is a hack which tries to remedy this + * situation. By splitting maximum sized outgoing TCP segments into + * two, the delayed ACK algorithm is not invoked at TCP + * receivers. This improves the throughput when sending data from uIP + * by orders of magnitude. + * + * The uip-split module uses the uip-fw module (uIP IP packet + * forwarding) for sending packets. Therefore, the uip-fw module must + * be set up with the appropriate network interfaces for this module + * to work. + */ + + +/** + * \file + * Module for splitting outbound TCP segments in two to avoid the + * delayed ACK throughput degradation. + * \author + * Adam Dunkels + * + */ + +#ifndef __UIP_SPLIT_H__ +#define __UIP_SPLIT_H__ + +/** + * Handle outgoing packets. + * + * This function inspects an outgoing packet in the uip_buf buffer and + * sends it out using the uip_fw_output() function. If the packet is a + * full-sized TCP segment it will be split into two segments and + * transmitted separately. This function should be called instead of + * the actual device driver output function, or the uip_fw_output() + * function. + * + * The headers of the outgoing packet is assumed to be in the uip_buf + * buffer and the payload is assumed to be wherever uip_appdata + * points. The length of the outgoing packet is assumed to be in the + * uip_len variable. + * + */ +void uip_split_output(void); + +#endif /* __UIP_SPLIT_H__ */ + +/** @} */ +/** @} */ diff --git a/core/net/uip.c b/core/net/uip.c new file mode 100644 index 000000000..8a5a7c059 --- /dev/null +++ b/core/net/uip.c @@ -0,0 +1,1889 @@ +#define DEBUG_PRINTF(...) /*printf(__VA_ARGS__)*/ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \file + * The uIP TCP/IP stack code. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: uip.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + +/* + * uIP is a small implementation of the IP, UDP and TCP protocols (as + * well as some basic ICMP stuff). The implementation couples the IP, + * UDP, TCP and the application layers very tightly. To keep the size + * of the compiled code down, this code frequently uses the goto + * statement. While it would be possible to break the uip_process() + * function into many smaller functions, this would increase the code + * size because of the overhead of parameter passing and the fact that + * the optimier would not be as efficient. + * + * The principle is that we have a small buffer, called the uip_buf, + * in which the device driver puts an incoming packet. The TCP/IP + * stack parses the headers in the packet, and calls the + * application. If the remote host has sent data to the application, + * this data is present in the uip_buf and the application read the + * data from there. It is up to the application to put this data into + * a byte stream if needed. The application will not be fed with data + * that is out of sequence. + * + * If the application whishes to send data to the peer, it should put + * its data into the uip_buf. The uip_appdata pointer points to the + * first available byte. The TCP/IP stack will calculate the + * checksums, and fill in the necessary header fields and finally send + * the packet back to the peer. +*/ + +#include "net/uip.h" +#include "net/uipopt.h" +#include "net/uip_arch.h" + +#if UIP_CONF_IPV6 +#include "net/uip-neighbor.h" +#endif /* UIP_CONF_IPV6 */ + +#include + +/*---------------------------------------------------------------------------*/ +/* Variable definitions. */ + + +/* The IP address of this host. If it is defined to be fixed (by + setting UIP_FIXEDADDR to 1 in uipopt.h), the address is set + here. Otherwise, the address */ +#if UIP_FIXEDADDR > 0 +const uip_ipaddr_t uip_hostaddr = + {HTONS((UIP_IPADDR0 << 8) | UIP_IPADDR1), + HTONS((UIP_IPADDR2 << 8) | UIP_IPADDR3)}; +const uip_ipaddr_t uip_draddr = + {HTONS((UIP_DRIPADDR0 << 8) | UIP_DRIPADDR1), + HTONS((UIP_DRIPADDR2 << 8) | UIP_DRIPADDR3)}; +const uip_ipaddr_t uip_netmask = + {HTONS((UIP_NETMASK0 << 8) | UIP_NETMASK1), + HTONS((UIP_NETMASK2 << 8) | UIP_NETMASK3)}; +#else +uip_ipaddr_t uip_hostaddr, uip_draddr, uip_netmask; +#endif /* UIP_FIXEDADDR */ + +const uip_ipaddr_t uip_broadcast_addr = +#if UIP_CONF_IPV6 + {0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff}; +#else /* UIP_CONF_IPV6 */ + {0xffff,0xffff}; +#endif /* UIP_CONF_IPV6 */ +static const uip_ipaddr_t all_zeroes_addr = +#if UIP_CONF_IPV6 + {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000}; +#else /* UIP_CONF_IPV6 */ + {0x0000,0x0000}; +#endif /* UIP_CONF_IPV6 */ + + +#if UIP_FIXEDETHADDR +const struct uip_eth_addr uip_ethaddr = {{UIP_ETHADDR0, + UIP_ETHADDR1, + UIP_ETHADDR2, + UIP_ETHADDR3, + UIP_ETHADDR4, + UIP_ETHADDR5}}; +#else +struct uip_eth_addr uip_ethaddr = {{0,0,0,0,0,0}}; +#endif + +#ifndef UIP_CONF_EXTERNAL_BUFFER +u8_t uip_buf[UIP_BUFSIZE + 2]; /* The packet buffer that contains + incoming packets. */ +#endif /* UIP_CONF_EXTERNAL_BUFFER */ + +void *uip_appdata; /* The uip_appdata pointer points to + application data. */ +void *uip_sappdata; /* The uip_appdata pointer points to + the application data which is to + be sent. */ +#if UIP_URGDATA > 0 +void *uip_urgdata; /* The uip_urgdata pointer points to + urgent data (out-of-band data), if + present. */ +u16_t uip_urglen, uip_surglen; +#endif /* UIP_URGDATA > 0 */ + +u16_t uip_len, uip_slen; + /* The uip_len is either 8 or 16 bits, + depending on the maximum packet + size. */ + +u8_t uip_flags; /* The uip_flags variable is used for + communication between the TCP/IP stack + and the application program. */ +struct uip_conn *uip_conn; /* uip_conn always points to the current + connection. */ + +struct uip_conn uip_conns[UIP_CONNS]; + /* The uip_conns array holds all TCP + connections. */ +u16_t uip_listenports[UIP_LISTENPORTS]; + /* The uip_listenports list all currently + listning ports. */ +#if UIP_UDP +struct uip_udp_conn *uip_udp_conn; +struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; +#endif /* UIP_UDP */ + +static u16_t ipid; /* Ths ipid variable is an increasing + number that is used for the IP ID + field. */ + +void uip_setipid(u16_t id) { ipid = id; } + +static u8_t iss[4]; /* The iss variable is used for the TCP + initial sequence number. */ + +#if UIP_ACTIVE_OPEN +static u16_t lastport; /* Keeps track of the last port used for + a new connection. */ +#endif /* UIP_ACTIVE_OPEN */ + +/* Temporary variables. */ +u8_t uip_acc32[4]; +static u8_t c, opt; +static u16_t tmp16; + +/* Structures and definitions. */ +#define TCP_FIN 0x01 +#define TCP_SYN 0x02 +#define TCP_RST 0x04 +#define TCP_PSH 0x08 +#define TCP_ACK 0x10 +#define TCP_URG 0x20 +#define TCP_CTL 0x3f + +#define TCP_OPT_END 0 /* End of TCP options list */ +#define TCP_OPT_NOOP 1 /* "No-operation" TCP option */ +#define TCP_OPT_MSS 2 /* Maximum segment size TCP option */ + +#define TCP_OPT_MSS_LEN 4 /* Length of TCP MSS option. */ + +#define ICMP_ECHO_REPLY 0 +#define ICMP_ECHO 8 + +#define ICMP6_ECHO_REPLY 129 +#define ICMP6_ECHO 128 +#define ICMP6_NEIGHBOR_SOLICITATION 135 +#define ICMP6_NEIGHBOR_ADVERTISEMENT 136 + +#define ICMP6_FLAG_S (1 << 6) + +#define ICMP6_OPTION_SOURCE_LINK_ADDRESS 1 +#define ICMP6_OPTION_TARGET_LINK_ADDRESS 2 + + +/* Macros. */ +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0]) +#define ICMPBUF ((struct uip_icmpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define UDPBUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN]) + + +#if UIP_STATISTICS == 1 +struct uip_stats uip_stat; +#define UIP_STAT(s) s +#else +#define UIP_STAT(s) +#endif /* UIP_STATISTICS == 1 */ + +#if UIP_LOGGING == 1 +#include +void uip_log(char *msg); +#define UIP_LOG(m) uip_log(m) +#else +#define UIP_LOG(m) +#endif /* UIP_LOGGING == 1 */ + +#if ! UIP_ARCH_ADD32 +void +uip_add32(u8_t *op32, u16_t op16) +{ + uip_acc32[3] = op32[3] + (op16 & 0xff); + uip_acc32[2] = op32[2] + (op16 >> 8); + uip_acc32[1] = op32[1]; + uip_acc32[0] = op32[0]; + + if(uip_acc32[2] < (op16 >> 8)) { + ++uip_acc32[1]; + if(uip_acc32[1] == 0) { + ++uip_acc32[0]; + } + } + + + if(uip_acc32[3] < (op16 & 0xff)) { + ++uip_acc32[2]; + if(uip_acc32[2] == 0) { + ++uip_acc32[1]; + if(uip_acc32[1] == 0) { + ++uip_acc32[0]; + } + } + } +} + +#endif /* UIP_ARCH_ADD32 */ + +#if ! UIP_ARCH_CHKSUM +/*---------------------------------------------------------------------------*/ +static u16_t +chksum(u16_t sum, const u8_t *data, u16_t len) +{ + u16_t t; + const u8_t *dataptr; + const u8_t *last_byte; + + dataptr = data; + last_byte = data + len - 1; + + while(dataptr < last_byte) { /* At least two more bytes */ + t = (dataptr[0] << 8) + dataptr[1]; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + dataptr += 2; + } + + if(dataptr == last_byte) { + t = (dataptr[0] << 8) + 0; + sum += t; + if(sum < t) { + sum++; /* carry */ + } + } + + /* Return sum in host byte order. */ + return sum; +} +/*---------------------------------------------------------------------------*/ +u16_t +uip_chksum(u16_t *data, u16_t len) +{ + return htons(chksum(0, (u8_t *)data, len)); +} +/*---------------------------------------------------------------------------*/ +#ifndef UIP_ARCH_IPCHKSUM +u16_t +uip_ipchksum(void) +{ + u16_t sum; + + sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN); + DEBUG_PRINTF("uip_ipchksum: sum 0x%04x\n", sum); + return (sum == 0) ? 0xffff : htons(sum); +} +#endif +/*---------------------------------------------------------------------------*/ +static u16_t +upper_layer_chksum(u8_t proto) +{ + u16_t upper_layer_len; + u16_t sum; + +#if UIP_CONF_IPV6 + upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]); +#else /* UIP_CONF_IPV6 */ + upper_layer_len = (((u16_t)(BUF->len[0]) << 8) + BUF->len[1]) - UIP_IPH_LEN; +#endif /* UIP_CONF_IPV6 */ + + /* First sum pseudoheader. */ + + /* IP protocol and length fields. This addition cannot carry. */ + sum = upper_layer_len + proto; + /* Sum IP source and destination addresses. */ + sum = chksum(sum, (u8_t *)&BUF->srcipaddr[0], 2 * sizeof(uip_ipaddr_t)); + + /* Sum TCP header and data. */ + sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], + upper_layer_len); + + return (sum == 0) ? 0xffff : htons(sum); +} +/*---------------------------------------------------------------------------*/ +#if UIP_CONF_IPV6 +u16_t +uip_icmp6chksum(void) +{ + return upper_layer_chksum(UIP_PROTO_ICMP6); + +} +#endif /* UIP_CONF_IPV6 */ +/*---------------------------------------------------------------------------*/ +u16_t +uip_tcpchksum(void) +{ + return upper_layer_chksum(UIP_PROTO_TCP); +} +/*---------------------------------------------------------------------------*/ +#if UIP_UDP_CHECKSUMS +u16_t +uip_udpchksum(void) +{ + return upper_layer_chksum(UIP_PROTO_UDP); +} +#endif /* UIP_UDP_CHECKSUMS */ +#endif /* UIP_ARCH_CHKSUM */ +/*---------------------------------------------------------------------------*/ +void +uip_init(void) +{ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + uip_listenports[c] = 0; + } + for(c = 0; c < UIP_CONNS; ++c) { + uip_conns[c].tcpstateflags = UIP_CLOSED; + } +#if UIP_ACTIVE_OPEN + lastport = 1024; +#endif /* UIP_ACTIVE_OPEN */ + +#if UIP_UDP + for(c = 0; c < UIP_UDP_CONNS; ++c) { + uip_udp_conns[c].lport = 0; + } +#endif /* UIP_UDP */ + + + /* IPv4 initialization. */ +#if UIP_FIXEDADDR == 0 + /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/ +#endif /* UIP_FIXEDADDR */ + +} +/*---------------------------------------------------------------------------*/ +#if UIP_ACTIVE_OPEN +struct uip_conn * +uip_connect(uip_ipaddr_t *ripaddr, u16_t rport) +{ + register struct uip_conn *conn, *cconn; + + /* Find an unused local port. */ + again: + ++lastport; + + if(lastport >= 32000) { + lastport = 4096; + } + + /* Check if this port is already in use, and if so try to find + another one. */ + for(c = 0; c < UIP_CONNS; ++c) { + conn = &uip_conns[c]; + if(conn->tcpstateflags != UIP_CLOSED && + conn->lport == htons(lastport)) { + goto again; + } + } + + conn = 0; + for(c = 0; c < UIP_CONNS; ++c) { + cconn = &uip_conns[c]; + if(cconn->tcpstateflags == UIP_CLOSED) { + conn = cconn; + break; + } + if(cconn->tcpstateflags == UIP_TIME_WAIT) { + if(conn == 0 || + cconn->timer > conn->timer) { + conn = cconn; + } + } + } + + if(conn == 0) { + return 0; + } + + conn->tcpstateflags = UIP_SYN_SENT; + + conn->snd_nxt[0] = iss[0]; + conn->snd_nxt[1] = iss[1]; + conn->snd_nxt[2] = iss[2]; + conn->snd_nxt[3] = iss[3]; + + conn->initialmss = conn->mss = UIP_TCP_MSS; + + conn->len = 1; /* TCP length of the SYN is one. */ + conn->nrtx = 0; + conn->timer = 1; /* Send the SYN next time around. */ + conn->rto = UIP_RTO; + conn->sa = 0; + conn->sv = 16; /* Initial value of the RTT variance. */ + conn->lport = htons(lastport); + conn->rport = rport; + uip_ipaddr_copy(&conn->ripaddr, ripaddr); + + return conn; +} +#endif /* UIP_ACTIVE_OPEN */ +/*---------------------------------------------------------------------------*/ +#if UIP_UDP +struct uip_udp_conn * +uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport) +{ + register struct uip_udp_conn *conn; + + /* Find an unused local port. */ + again: + ++lastport; + + if(lastport >= 32000) { + lastport = 4096; + } + + for(c = 0; c < UIP_UDP_CONNS; ++c) { + if(uip_udp_conns[c].lport == htons(lastport)) { + goto again; + } + } + + + conn = 0; + for(c = 0; c < UIP_UDP_CONNS; ++c) { + if(uip_udp_conns[c].lport == 0) { + conn = &uip_udp_conns[c]; + break; + } + } + + if(conn == 0) { + return 0; + } + + conn->lport = HTONS(lastport); + conn->rport = rport; + if(ripaddr == NULL) { + memset(conn->ripaddr, 0, sizeof(uip_ipaddr_t)); + } else { + uip_ipaddr_copy(&conn->ripaddr, ripaddr); + } + conn->ttl = UIP_TTL; + + return conn; +} +#endif /* UIP_UDP */ +/*---------------------------------------------------------------------------*/ +void +uip_unlisten(u16_t port) +{ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + if(uip_listenports[c] == port) { + uip_listenports[c] = 0; + return; + } + } +} +/*---------------------------------------------------------------------------*/ +void +uip_listen(u16_t port) +{ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + if(uip_listenports[c] == 0) { + uip_listenports[c] = port; + return; + } + } +} +/*---------------------------------------------------------------------------*/ +/* XXX: IP fragment reassembly: not well-tested. */ + +#if UIP_REASSEMBLY && !UIP_CONF_IPV6 +#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN) +static u8_t uip_reassbuf[UIP_REASS_BUFSIZE]; +static u8_t uip_reassbitmap[UIP_REASS_BUFSIZE / (8 * 8)]; +static const u8_t bitmap_bits[8] = {0xff, 0x7f, 0x3f, 0x1f, + 0x0f, 0x07, 0x03, 0x01}; +static u16_t uip_reasslen; +static u8_t uip_reassflags; +#define UIP_REASS_FLAG_LASTFRAG 0x01 +static u8_t uip_reasstmr; + +#define IP_MF 0x20 + +static u8_t +uip_reass(void) +{ + u16_t offset, len; + u16_t i; + + /* If ip_reasstmr is zero, no packet is present in the buffer, so we + write the IP header of the fragment into the reassembly + buffer. The timer is updated with the maximum age. */ + if(uip_reasstmr == 0) { + memcpy(uip_reassbuf, &BUF->vhl, UIP_IPH_LEN); + uip_reasstmr = UIP_REASS_MAXAGE; + uip_reassflags = 0; + /* Clear the bitmap. */ + memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap)); + } + + /* Check if the incoming fragment matches the one currently present + in the reasembly buffer. If so, we proceed with copying the + fragment into the buffer. */ + if(BUF->srcipaddr[0] == FBUF->srcipaddr[0] && + BUF->srcipaddr[1] == FBUF->srcipaddr[1] && + BUF->destipaddr[0] == FBUF->destipaddr[0] && + BUF->destipaddr[1] == FBUF->destipaddr[1] && + BUF->ipid[0] == FBUF->ipid[0] && + BUF->ipid[1] == FBUF->ipid[1]) { + + len = (BUF->len[0] << 8) + BUF->len[1] - (BUF->vhl & 0x0f) * 4; + offset = (((BUF->ipoffset[0] & 0x3f) << 8) + BUF->ipoffset[1]) * 8; + + /* If the offset or the offset + fragment length overflows the + reassembly buffer, we discard the entire packet. */ + if(offset > UIP_REASS_BUFSIZE || + offset + len > UIP_REASS_BUFSIZE) { + uip_reasstmr = 0; + goto nullreturn; + } + + /* Copy the fragment into the reassembly buffer, at the right + offset. */ + memcpy(&uip_reassbuf[UIP_IPH_LEN + offset], + (char *)BUF + (int)((BUF->vhl & 0x0f) * 4), + len); + + /* Update the bitmap. */ + if(offset / (8 * 8) == (offset + len) / (8 * 8)) { + /* If the two endpoints are in the same byte, we only update + that byte. */ + + uip_reassbitmap[offset / (8 * 8)] |= + bitmap_bits[(offset / 8 ) & 7] & + ~bitmap_bits[((offset + len) / 8 ) & 7]; + } else { + /* If the two endpoints are in different bytes, we update the + bytes in the endpoints and fill the stuff inbetween with + 0xff. */ + uip_reassbitmap[offset / (8 * 8)] |= + bitmap_bits[(offset / 8 ) & 7]; + for(i = 1 + offset / (8 * 8); i < (offset + len) / (8 * 8); ++i) { + uip_reassbitmap[i] = 0xff; + } + uip_reassbitmap[(offset + len) / (8 * 8)] |= + ~bitmap_bits[((offset + len) / 8 ) & 7]; + } + + /* If this fragment has the More Fragments flag set to zero, we + know that this is the last fragment, so we can calculate the + size of the entire packet. We also set the + IP_REASS_FLAG_LASTFRAG flag to indicate that we have received + the final fragment. */ + + if((BUF->ipoffset[0] & IP_MF) == 0) { + uip_reassflags |= UIP_REASS_FLAG_LASTFRAG; + uip_reasslen = offset + len; + } + + /* Finally, we check if we have a full packet in the buffer. We do + this by checking if we have the last fragment and if all bits + in the bitmap are set. */ + if(uip_reassflags & UIP_REASS_FLAG_LASTFRAG) { + /* Check all bytes up to and including all but the last byte in + the bitmap. */ + for(i = 0; i < uip_reasslen / (8 * 8) - 1; ++i) { + if(uip_reassbitmap[i] != 0xff) { + goto nullreturn; + } + } + /* Check the last byte in the bitmap. It should contain just the + right amount of bits. */ + if(uip_reassbitmap[uip_reasslen / (8 * 8)] != + (u8_t)~bitmap_bits[uip_reasslen / 8 & 7]) { + goto nullreturn; + } + + /* If we have come this far, we have a full packet in the + buffer, so we allocate a pbuf and copy the packet into it. We + also reset the timer. */ + uip_reasstmr = 0; + memcpy(BUF, FBUF, uip_reasslen); + + /* Pretend to be a "normal" (i.e., not fragmented) IP packet + from now on. */ + BUF->ipoffset[0] = BUF->ipoffset[1] = 0; + BUF->len[0] = uip_reasslen >> 8; + BUF->len[1] = uip_reasslen & 0xff; + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); + + return uip_reasslen; + } + } + + nullreturn: + return 0; +} +#endif /* UIP_REASSEMBLY */ +/*---------------------------------------------------------------------------*/ +static void +uip_add_rcv_nxt(u16_t n) +{ + uip_add32(uip_conn->rcv_nxt, n); + uip_conn->rcv_nxt[0] = uip_acc32[0]; + uip_conn->rcv_nxt[1] = uip_acc32[1]; + uip_conn->rcv_nxt[2] = uip_acc32[2]; + uip_conn->rcv_nxt[3] = uip_acc32[3]; +} +/*---------------------------------------------------------------------------*/ +void +uip_process(u8_t flag) +{ + register struct uip_conn *uip_connr = uip_conn; + +#if UIP_UDP + if(flag == UIP_UDP_SEND_CONN) { + goto udp_send; + } +#endif /* UIP_UDP */ + + uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN]; + + /* Check if we were invoked because of a poll request for a + particular connection. */ + if(flag == UIP_POLL_REQUEST) { + if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED && + !uip_outstanding(uip_connr)) { + uip_flags = UIP_POLL; + UIP_APPCALL(); + goto appsend; + } + goto drop; + + /* Check if we were invoked because of the perodic timer fireing. */ + } else if(flag == UIP_TIMER) { +#if UIP_REASSEMBLY + if(uip_reasstmr != 0) { + --uip_reasstmr; + } +#endif /* UIP_REASSEMBLY */ + /* Increase the initial sequence number. */ + if(++iss[3] == 0) { + if(++iss[2] == 0) { + if(++iss[1] == 0) { + ++iss[0]; + } + } + } + + /* Reset the length variables. */ + uip_len = 0; + uip_slen = 0; + + /* Check if the connection is in a state in which we simply wait + for the connection to time out. If so, we increase the + connection's timer and remove the connection if it times + out. */ + if(uip_connr->tcpstateflags == UIP_TIME_WAIT || + uip_connr->tcpstateflags == UIP_FIN_WAIT_2) { + ++(uip_connr->timer); + if(uip_connr->timer == UIP_TIME_WAIT_TIMEOUT) { + uip_connr->tcpstateflags = UIP_CLOSED; + } + } else if(uip_connr->tcpstateflags != UIP_CLOSED) { + /* If the connection has outstanding data, we increase the + connection's timer and see if it has reached the RTO value + in which case we retransmit. */ + if(uip_outstanding(uip_connr)) { + if(uip_connr->timer-- == 0) { + if(uip_connr->nrtx == UIP_MAXRTX || + ((uip_connr->tcpstateflags == UIP_SYN_SENT || + uip_connr->tcpstateflags == UIP_SYN_RCVD) && + uip_connr->nrtx == UIP_MAXSYNRTX)) { + uip_connr->tcpstateflags = UIP_CLOSED; + + /* We call UIP_APPCALL() with uip_flags set to + UIP_TIMEDOUT to inform the application that the + connection has timed out. */ + uip_flags = UIP_TIMEDOUT; + UIP_APPCALL(); + + /* We also send a reset packet to the remote host. */ + BUF->flags = TCP_RST | TCP_ACK; + goto tcp_send_nodata; + } + + /* Exponential backoff. */ + uip_connr->timer = UIP_RTO << (uip_connr->nrtx > 4? + 4: + uip_connr->nrtx); + ++(uip_connr->nrtx); + + /* Ok, so we need to retransmit. We do this differently + depending on which state we are in. In ESTABLISHED, we + call upon the application so that it may prepare the + data for the retransmit. In SYN_RCVD, we resend the + SYNACK that we sent earlier and in LAST_ACK we have to + retransmit our FINACK. */ + UIP_STAT(++uip_stat.tcp.rexmit); + switch(uip_connr->tcpstateflags & UIP_TS_MASK) { + case UIP_SYN_RCVD: + /* In the SYN_RCVD state, we should retransmit our + SYNACK. */ + goto tcp_send_synack; + +#if UIP_ACTIVE_OPEN + case UIP_SYN_SENT: + /* In the SYN_SENT state, we retransmit out SYN. */ + BUF->flags = 0; + goto tcp_send_syn; +#endif /* UIP_ACTIVE_OPEN */ + + case UIP_ESTABLISHED: + /* In the ESTABLISHED state, we call upon the application + to do the actual retransmit after which we jump into + the code for sending out the packet (the apprexmit + label). */ + uip_flags = UIP_REXMIT; + UIP_APPCALL(); + goto apprexmit; + + case UIP_FIN_WAIT_1: + case UIP_CLOSING: + case UIP_LAST_ACK: + /* In all these states we should retransmit a FINACK. */ + goto tcp_send_finack; + + } + } + } else if((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_ESTABLISHED) { + /* If there was no need for a retransmission, we poll the + application for new data. */ + uip_flags = UIP_POLL; + UIP_APPCALL(); + goto appsend; + } + } + goto drop; + } +#if UIP_UDP + if(flag == UIP_UDP_TIMER) { + if(uip_udp_conn->lport != 0) { + uip_conn = NULL; + uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + uip_len = uip_slen = 0; + uip_flags = UIP_POLL; + UIP_UDP_APPCALL(); + goto udp_send; + } else { + goto drop; + } + } +#endif + + /* This is where the input processing starts. */ + UIP_STAT(++uip_stat.ip.recv); + + /* Start of IP input header processing code. */ + +#if UIP_CONF_IPV6 + /* Check validity of the IP header. */ + if((BUF->vtc & 0xf0) != 0x60) { /* IP version and header length. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.vhlerr); + UIP_LOG("ipv6: invalid version."); + goto drop; + } +#else /* UIP_CONF_IPV6 */ + /* Check validity of the IP header. */ + if(BUF->vhl != 0x45) { /* IP version and header length. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.vhlerr); + UIP_LOG("ip: invalid version or header length."); + goto drop; + } +#endif /* UIP_CONF_IPV6 */ + + /* Check the size of the packet. If the size reported to us in + uip_len is smaller the size reported in the IP header, we assume + that the packet has been corrupted in transit. If the size of + uip_len is larger than the size reported in the IP packet header, + the packet has been padded and we set uip_len to the correct + value.. */ + + if((BUF->len[0] << 8) + BUF->len[1] <= uip_len) { + uip_len = (BUF->len[0] << 8) + BUF->len[1]; +#if UIP_CONF_IPV6 + uip_len += 40; /* The length reported in the IPv6 header is the + length of the payload that follows the + header. However, uIP uses the uip_len variable + for holding the size of the entire packet, + including the IP header. For IPv4 this is not a + problem as the length field in the IPv4 header + contains the length of the entire packet. But + for IPv6 we need to add the size of the IPv6 + header (40 bytes). */ +#endif /* UIP_CONF_IPV6 */ + } else { + UIP_LOG("ip: packet shorter than reported in IP header."); + goto drop; + } + +#if !UIP_CONF_IPV6 + /* Check the fragment flag. */ + if((BUF->ipoffset[0] & 0x3f) != 0 || + BUF->ipoffset[1] != 0) { +#if UIP_REASSEMBLY + uip_len = uip_reass(); + if(uip_len == 0) { + goto drop; + } +#else /* UIP_REASSEMBLY */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.fragerr); + UIP_LOG("ip: fragment dropped."); + goto drop; +#endif /* UIP_REASSEMBLY */ + } +#endif /* UIP_CONF_IPV6 */ + + if(uip_ipaddr_cmp(uip_hostaddr, all_zeroes_addr)) { + /* If we are configured to use ping IP address configuration and + hasn't been assigned an IP address yet, we accept all ICMP + packets. */ +#if UIP_PINGADDRCONF && !UIP_CONF_IPV6 + if(BUF->proto == UIP_PROTO_ICMP) { + UIP_LOG("ip: possible ping config packet received."); + goto icmp_input; + } else { + UIP_LOG("ip: packet dropped since no address assigned."); + goto drop; + } +#endif /* UIP_PINGADDRCONF */ + + } else { + /* If IP broadcast support is configured, we check for a broadcast + UDP packet, which may be destined to us. */ +#if UIP_BROADCAST + DEBUG_PRINTF("UDP IP checksum 0x%04x\n", uip_ipchksum()); + if(BUF->proto == UIP_PROTO_UDP && + uip_ipaddr_cmp(BUF->destipaddr, uip_broadcast_addr) + /*&& + uip_ipchksum() == 0xffff*/) { + goto udp_input; + } +#endif /* UIP_BROADCAST */ + + /* Check if the packet is destined for our IP address. */ +#if !UIP_CONF_IPV6 + if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr)) { + UIP_STAT(++uip_stat.ip.drop); + goto drop; + } +#else /* UIP_CONF_IPV6 */ + /* For IPv6, packet reception is a little trickier as we need to + make sure that we listen to certain multicast addresses (all + hosts multicast address, and the solicited-node multicast + address) as well. However, we will cheat here and accept all + multicast packets that are sent to the ff02::/16 addresses. */ + if(!uip_ipaddr_cmp(BUF->destipaddr, uip_hostaddr) && + BUF->destipaddr[0] != HTONS(0xff02)) { + UIP_STAT(++uip_stat.ip.drop); + goto drop; + } +#endif /* UIP_CONF_IPV6 */ + } + +#if !UIP_CONF_IPV6 + if(uip_ipchksum() != 0xffff) { /* Compute and check the IP header + checksum. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.chkerr); + UIP_LOG("ip: bad checksum."); + goto drop; + } +#endif /* UIP_CONF_IPV6 */ + + if(BUF->proto == UIP_PROTO_TCP) { /* Check for TCP packet. If so, + proceed with TCP input + processing. */ + goto tcp_input; + } + +#if UIP_UDP + if(BUF->proto == UIP_PROTO_UDP) { + goto udp_input; + } +#endif /* UIP_UDP */ + +#if !UIP_CONF_IPV6 + /* ICMPv4 processing code follows. */ + if(BUF->proto != UIP_PROTO_ICMP) { /* We only allow ICMP packets from + here. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.protoerr); + UIP_LOG("ip: neither tcp nor icmp."); + goto drop; + } + +#if UIP_PINGADDRCONF + icmp_input: +#endif /* UIP_PINGADDRCONF */ + UIP_STAT(++uip_stat.icmp.recv); + + /* ICMP echo (i.e., ping) processing. This is simple, we only change + the ICMP type from ECHO to ECHO_REPLY and adjust the ICMP + checksum before we return the packet. */ + if(ICMPBUF->type != ICMP_ECHO) { + UIP_STAT(++uip_stat.icmp.drop); + UIP_STAT(++uip_stat.icmp.typeerr); + UIP_LOG("icmp: not icmp echo."); + goto drop; + } + + /* If we are configured to use ping IP address assignment, we use + the destination IP address of this ping packet and assign it to + ourself. */ +#if UIP_PINGADDRCONF + if((uip_hostaddr[0] | uip_hostaddr[1]) == 0) { + uip_hostaddr[0] = BUF->destipaddr[0]; + uip_hostaddr[1] = BUF->destipaddr[1]; + } +#endif /* UIP_PINGADDRCONF */ + + ICMPBUF->type = ICMP_ECHO_REPLY; + + if(ICMPBUF->icmpchksum >= HTONS(0xffff - (ICMP_ECHO << 8))) { + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8) + 1; + } else { + ICMPBUF->icmpchksum += HTONS(ICMP_ECHO << 8); + } + + /* Swap IP addresses. */ + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + + UIP_STAT(++uip_stat.icmp.sent); + goto send; + + /* End of IPv4 input header processing code. */ +#else /* !UIP_CONF_IPV6 */ + + /* This is IPv6 ICMPv6 processing code. */ + DEBUG_PRINTF("icmp6_input: length %d\n", uip_len); + + if(BUF->proto != UIP_PROTO_ICMP6) { /* We only allow ICMPv6 packets from + here. */ + UIP_STAT(++uip_stat.ip.drop); + UIP_STAT(++uip_stat.ip.protoerr); + UIP_LOG("ip: neither tcp nor icmp6."); + goto drop; + } + + UIP_STAT(++uip_stat.icmp.recv); + + /* If we get a neighbor solicitation for our address we should send + a neighbor advertisement message back. */ + if(ICMPBUF->type == ICMP6_NEIGHBOR_SOLICITATION) { + if(uip_ipaddr_cmp(ICMPBUF->icmp6data, uip_hostaddr)) { + + if(ICMPBUF->options[0] == ICMP6_OPTION_SOURCE_LINK_ADDRESS) { + /* Save the sender's address in our neighbor list. */ + uip_neighbor_add(ICMPBUF->srcipaddr, &(ICMPBUF->options[2])); + } + + /* We should now send a neighbor advertisement back to where the + neighbor solicication came from. */ + ICMPBUF->type = ICMP6_NEIGHBOR_ADVERTISEMENT; + ICMPBUF->flags = ICMP6_FLAG_S; /* Solicited flag. */ + + ICMPBUF->reserved1 = ICMPBUF->reserved2 = ICMPBUF->reserved3 = 0; + + uip_ipaddr_copy(ICMPBUF->destipaddr, ICMPBUF->srcipaddr); + uip_ipaddr_copy(ICMPBUF->srcipaddr, uip_hostaddr); + ICMPBUF->options[0] = ICMP6_OPTION_TARGET_LINK_ADDRESS; + ICMPBUF->options[1] = 1; /* Options length, 1 = 8 bytes. */ + memcpy(&(ICMPBUF->options[2]), &uip_ethaddr, sizeof(uip_ethaddr)); + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + goto send; + + } + goto drop; + } else if(ICMPBUF->type == ICMP6_ECHO) { + /* ICMP echo (i.e., ping) processing. This is simple, we only + change the ICMP type from ECHO to ECHO_REPLY and update the + ICMP checksum before we return the packet. */ + + ICMPBUF->type = ICMP6_ECHO_REPLY; + + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + ICMPBUF->icmpchksum = 0; + ICMPBUF->icmpchksum = ~uip_icmp6chksum(); + + UIP_STAT(++uip_stat.icmp.sent); + goto send; + } else { + DEBUG_PRINTF("Unknown icmp6 message type %d\n", ICMPBUF->type); + UIP_STAT(++uip_stat.icmp.drop); + UIP_STAT(++uip_stat.icmp.typeerr); + UIP_LOG("icmp: unknown ICMP message."); + goto drop; + } + + /* End of IPv6 ICMP processing. */ + +#endif /* !UIP_CONF_IPV6 */ + +#if UIP_UDP + /* UDP input processing. */ + udp_input: + /* UDP processing is really just a hack. We don't do anything to the + UDP/IP headers, but let the UDP application do all the hard + work. If the application sets uip_slen, it has a packet to + send. */ +#if UIP_UDP_CHECKSUMS + uip_len = uip_len - UIP_IPUDPH_LEN; + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + if(UDPBUF->udpchksum != 0 && uip_udpchksum() != 0xffff) { + UIP_STAT(++uip_stat.udp.drop); + UIP_STAT(++uip_stat.udp.chkerr); + UIP_LOG("udp: bad checksum."); + goto drop; + } +#else /* UIP_UDP_CHECKSUMS */ + uip_len = uip_len - UIP_IPUDPH_LEN; +#endif /* UIP_UDP_CHECKSUMS */ + + /* Demultiplex this UDP packet between the UDP "connections". */ + for(uip_udp_conn = &uip_udp_conns[0]; + uip_udp_conn < &uip_udp_conns[UIP_UDP_CONNS]; + ++uip_udp_conn) { + /* If the local UDP port is non-zero, the connection is considered + to be used. If so, the local port number is checked against the + destination port number in the received packet. If the two port + numbers match, the remote port number is checked if the + connection is bound to a remote port. Finally, if the + connection is bound to a remote IP address, the source IP + address of the packet is checked. */ + if(uip_udp_conn->lport != 0 && + UDPBUF->destport == uip_udp_conn->lport && + (uip_udp_conn->rport == 0 || + UDPBUF->srcport == uip_udp_conn->rport) && + (uip_ipaddr_cmp(uip_udp_conn->ripaddr, all_zeroes_addr) || + uip_ipaddr_cmp(uip_udp_conn->ripaddr, uip_broadcast_addr) || + uip_ipaddr_cmp(BUF->srcipaddr, uip_udp_conn->ripaddr))) { + goto udp_found; + } + } + UIP_LOG("udp: no matching connection found"); + goto drop; + + udp_found: + uip_conn = NULL; + uip_flags = UIP_NEWDATA; + uip_sappdata = uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN]; + uip_slen = 0; + UIP_UDP_APPCALL(); + udp_send: + if(uip_slen == 0) { + goto drop; + } + uip_len = uip_slen + UIP_IPUDPH_LEN; + +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = (uip_len >> 8); + BUF->len[1] = (uip_len & 0xff); +#endif /* UIP_CONF_IPV6 */ + + BUF->ttl = uip_udp_conn->ttl; + BUF->proto = UIP_PROTO_UDP; + + UDPBUF->udplen = HTONS(uip_slen + UIP_UDPH_LEN); + UDPBUF->udpchksum = 0; + + BUF->srcport = uip_udp_conn->lport; + BUF->destport = uip_udp_conn->rport; + + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(BUF->destipaddr, uip_udp_conn->ripaddr); + + uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN]; + +#if UIP_UDP_CHECKSUMS + /* Calculate UDP checksum. */ + UDPBUF->udpchksum = ~(uip_udpchksum()); + if(UDPBUF->udpchksum == 0) { + UDPBUF->udpchksum = 0xffff; + } +#endif /* UIP_UDP_CHECKSUMS */ + + goto ip_send_nolen; +#endif /* UIP_UDP */ + + /* TCP input processing. */ + tcp_input: + UIP_STAT(++uip_stat.tcp.recv); + + /* Start of TCP input header processing code. */ + + if(uip_tcpchksum() != 0xffff) { /* Compute and check the TCP + checksum. */ + UIP_STAT(++uip_stat.tcp.drop); + UIP_STAT(++uip_stat.tcp.chkerr); + UIP_LOG("tcp: bad checksum."); + goto drop; + } + + + /* Demultiplex this segment. */ + /* First check any active connections. */ + for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS - 1]; + ++uip_connr) { + if(uip_connr->tcpstateflags != UIP_CLOSED && + BUF->destport == uip_connr->lport && + BUF->srcport == uip_connr->rport && + uip_ipaddr_cmp(BUF->srcipaddr, uip_connr->ripaddr)) { + goto found; + } + } + + /* If we didn't find and active connection that expected the packet, + either this packet is an old duplicate, or this is a SYN packet + destined for a connection in LISTEN. If the SYN flag isn't set, + it is an old packet and we send a RST. */ + if((BUF->flags & TCP_CTL) != TCP_SYN) { + goto reset; + } + + tmp16 = BUF->destport; + /* Next, check listening connections. */ + for(c = 0; c < UIP_LISTENPORTS; ++c) { + if(tmp16 == uip_listenports[c]) + goto found_listen; + } + + /* No matching connection found, so we send a RST packet. */ + UIP_STAT(++uip_stat.tcp.synrst); + reset: + + /* We do not send resets in response to resets. */ + if(BUF->flags & TCP_RST) { + goto drop; + } + + UIP_STAT(++uip_stat.tcp.rst); + + BUF->flags = TCP_RST | TCP_ACK; + uip_len = UIP_IPTCPH_LEN; + BUF->tcpoffset = 5 << 4; + + /* Flip the seqno and ackno fields in the TCP header. */ + c = BUF->seqno[3]; + BUF->seqno[3] = BUF->ackno[3]; + BUF->ackno[3] = c; + + c = BUF->seqno[2]; + BUF->seqno[2] = BUF->ackno[2]; + BUF->ackno[2] = c; + + c = BUF->seqno[1]; + BUF->seqno[1] = BUF->ackno[1]; + BUF->ackno[1] = c; + + c = BUF->seqno[0]; + BUF->seqno[0] = BUF->ackno[0]; + BUF->ackno[0] = c; + + /* We also have to increase the sequence number we are + acknowledging. If the least significant byte overflowed, we need + to propagate the carry to the other bytes as well. */ + if(++BUF->ackno[3] == 0) { + if(++BUF->ackno[2] == 0) { + if(++BUF->ackno[1] == 0) { + ++BUF->ackno[0]; + } + } + } + + /* Swap port numbers. */ + tmp16 = BUF->srcport; + BUF->srcport = BUF->destport; + BUF->destport = tmp16; + + /* Swap IP addresses. */ + uip_ipaddr_copy(BUF->destipaddr, BUF->srcipaddr); + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + + /* And send out the RST packet! */ + goto tcp_send_noconn; + + /* This label will be jumped to if we matched the incoming packet + with a connection in LISTEN. In that case, we should create a new + connection and send a SYNACK in return. */ + found_listen: + /* First we check if there are any connections avaliable. Unused + connections are kept in the same table as used connections, but + unused ones have the tcpstate set to CLOSED. Also, connections in + TIME_WAIT are kept track of and we'll use the oldest one if no + CLOSED connections are found. Thanks to Eddie C. Dost for a very + nice algorithm for the TIME_WAIT search. */ + uip_connr = 0; + for(c = 0; c < UIP_CONNS; ++c) { + if(uip_conns[c].tcpstateflags == UIP_CLOSED) { + uip_connr = &uip_conns[c]; + break; + } + if(uip_conns[c].tcpstateflags == UIP_TIME_WAIT) { + if(uip_connr == 0 || + uip_conns[c].timer > uip_connr->timer) { + uip_connr = &uip_conns[c]; + } + } + } + + if(uip_connr == 0) { + /* All connections are used already, we drop packet and hope that + the remote end will retransmit the packet at a time when we + have more spare connections. */ + UIP_STAT(++uip_stat.tcp.syndrop); + UIP_LOG("tcp: found no unused connections."); + goto drop; + } + uip_conn = uip_connr; + + /* Fill in the necessary fields for the new connection. */ + uip_connr->rto = uip_connr->timer = UIP_RTO; + uip_connr->sa = 0; + uip_connr->sv = 4; + uip_connr->nrtx = 0; + uip_connr->lport = BUF->destport; + uip_connr->rport = BUF->srcport; + uip_ipaddr_copy(uip_connr->ripaddr, BUF->srcipaddr); + uip_connr->tcpstateflags = UIP_SYN_RCVD; + + uip_connr->snd_nxt[0] = iss[0]; + uip_connr->snd_nxt[1] = iss[1]; + uip_connr->snd_nxt[2] = iss[2]; + uip_connr->snd_nxt[3] = iss[3]; + uip_connr->len = 1; + + /* rcv_nxt should be the seqno from the incoming packet + 1. */ + uip_connr->rcv_nxt[3] = BUF->seqno[3]; + uip_connr->rcv_nxt[2] = BUF->seqno[2]; + uip_connr->rcv_nxt[1] = BUF->seqno[1]; + uip_connr->rcv_nxt[0] = BUF->seqno[0]; + uip_add_rcv_nxt(1); + + /* Parse the TCP MSS option, if present. */ + if((BUF->tcpoffset & 0xf0) > 0x50) { + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { + opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c]; + if(opt == TCP_OPT_END) { + /* End of options. */ + break; + } else if(opt == TCP_OPT_NOOP) { + ++c; + /* NOP option. */ + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { + /* An MSS option with the right option length. */ + tmp16 = ((u16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | + (u16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c]; + uip_connr->initialmss = uip_connr->mss = + tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; + + /* And we are done processing options. */ + break; + } else { + /* All other options have a length field, so that we easily + can skip past them. */ + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { + /* If the length field is zero, the options are malformed + and we don't process them further. */ + break; + } + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + } + } + } + + /* Our response will be a SYNACK. */ +#if UIP_ACTIVE_OPEN + tcp_send_synack: + BUF->flags = TCP_ACK; + + tcp_send_syn: + BUF->flags |= TCP_SYN; +#else /* UIP_ACTIVE_OPEN */ + tcp_send_synack: + BUF->flags = TCP_SYN | TCP_ACK; +#endif /* UIP_ACTIVE_OPEN */ + + /* We send out the TCP Maximum Segment Size option with our + SYNACK. */ + BUF->optdata[0] = TCP_OPT_MSS; + BUF->optdata[1] = TCP_OPT_MSS_LEN; + BUF->optdata[2] = (UIP_TCP_MSS) / 256; + BUF->optdata[3] = (UIP_TCP_MSS) & 255; + uip_len = UIP_IPTCPH_LEN + TCP_OPT_MSS_LEN; + BUF->tcpoffset = ((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4) << 4; + goto tcp_send; + + /* This label will be jumped to if we found an active connection. */ + found: + uip_conn = uip_connr; + uip_flags = 0; + /* We do a very naive form of TCP reset processing; we just accept + any RST and kill our connection. We should in fact check if the + sequence number of this reset is wihtin our advertised window + before we accept the reset. */ + if(BUF->flags & TCP_RST) { + uip_connr->tcpstateflags = UIP_CLOSED; + UIP_LOG("tcp: got reset, aborting connection."); + uip_flags = UIP_ABORT; + UIP_APPCALL(); + goto drop; + } + /* Calculated the length of the data, if the application has sent + any data to us. */ + c = (BUF->tcpoffset >> 4) << 2; + /* uip_len will contain the length of the actual TCP data. This is + calculated by subtracing the length of the TCP header (in + c) and the length of the IP header (20 bytes). */ + uip_len = uip_len - c - UIP_IPH_LEN; + + /* First, check if the sequence number of the incoming packet is + what we're expecting next. If not, we send out an ACK with the + correct numbers in. */ + if(!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) && + ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)))) { + if((uip_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) && + (BUF->seqno[0] != uip_connr->rcv_nxt[0] || + BUF->seqno[1] != uip_connr->rcv_nxt[1] || + BUF->seqno[2] != uip_connr->rcv_nxt[2] || + BUF->seqno[3] != uip_connr->rcv_nxt[3])) { + goto tcp_send_ack; + } + } + + /* Next, check if the incoming segment acknowledges any outstanding + data. If so, we update the sequence number, reset the length of + the outstanding data, calculate RTT estimations, and reset the + retransmission timer. */ + if((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr)) { + uip_add32(uip_connr->snd_nxt, uip_connr->len); + + if(BUF->ackno[0] == uip_acc32[0] && + BUF->ackno[1] == uip_acc32[1] && + BUF->ackno[2] == uip_acc32[2] && + BUF->ackno[3] == uip_acc32[3]) { + /* Update sequence number. */ + uip_connr->snd_nxt[0] = uip_acc32[0]; + uip_connr->snd_nxt[1] = uip_acc32[1]; + uip_connr->snd_nxt[2] = uip_acc32[2]; + uip_connr->snd_nxt[3] = uip_acc32[3]; + + + /* Do RTT estimation, unless we have done retransmissions. */ + if(uip_connr->nrtx == 0) { + signed char m; + m = uip_connr->rto - uip_connr->timer; + /* This is taken directly from VJs original code in his paper */ + m = m - (uip_connr->sa >> 3); + uip_connr->sa += m; + if(m < 0) { + m = -m; + } + m = m - (uip_connr->sv >> 2); + uip_connr->sv += m; + uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv; + + } + /* Set the acknowledged flag. */ + uip_flags = UIP_ACKDATA; + /* Reset the retransmission timer. */ + uip_connr->timer = uip_connr->rto; + + /* Reset length of outstanding data. */ + uip_connr->len = 0; + } + + } + + /* Do different things depending on in what state the connection is. */ + switch(uip_connr->tcpstateflags & UIP_TS_MASK) { + /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not + implemented, since we force the application to close when the + peer sends a FIN (hence the application goes directly from + ESTABLISHED to LAST_ACK). */ + case UIP_SYN_RCVD: + /* In SYN_RCVD we have sent out a SYNACK in response to a SYN, and + we are waiting for an ACK that acknowledges the data we sent + out the last time. Therefore, we want to have the UIP_ACKDATA + flag set. If so, we enter the ESTABLISHED state. */ + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_flags = UIP_CONNECTED; + uip_connr->len = 0; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); + } + uip_slen = 0; + UIP_APPCALL(); + goto appsend; + } + goto drop; +#if UIP_ACTIVE_OPEN + case UIP_SYN_SENT: + /* In SYN_SENT, we wait for a SYNACK that is sent in response to + our SYN. The rcv_nxt is set to sequence number in the SYNACK + plus one, and we send an ACK. We move into the ESTABLISHED + state. */ + if((uip_flags & UIP_ACKDATA) && + (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK)) { + + /* Parse the TCP MSS option, if present. */ + if((BUF->tcpoffset & 0xf0) > 0x50) { + for(c = 0; c < ((BUF->tcpoffset >> 4) - 5) << 2 ;) { + opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c]; + if(opt == TCP_OPT_END) { + /* End of options. */ + break; + } else if(opt == TCP_OPT_NOOP) { + ++c; + /* NOP option. */ + } else if(opt == TCP_OPT_MSS && + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) { + /* An MSS option with the right option length. */ + tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) | + uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c]; + uip_connr->initialmss = + uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16; + + /* And we are done processing options. */ + break; + } else { + /* All other options have a length field, so that we easily + can skip past them. */ + if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) { + /* If the length field is zero, the options are malformed + and we don't process them further. */ + break; + } + c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c]; + } + } + } + uip_connr->tcpstateflags = UIP_ESTABLISHED; + uip_connr->rcv_nxt[0] = BUF->seqno[0]; + uip_connr->rcv_nxt[1] = BUF->seqno[1]; + uip_connr->rcv_nxt[2] = BUF->seqno[2]; + uip_connr->rcv_nxt[3] = BUF->seqno[3]; + uip_add_rcv_nxt(1); + uip_flags = UIP_CONNECTED | UIP_NEWDATA; + uip_connr->len = 0; + uip_len = 0; + uip_slen = 0; + UIP_APPCALL(); + goto appsend; + } + /* Inform the application that the connection failed */ + uip_flags = UIP_ABORT; + UIP_APPCALL(); + /* The connection is closed after we send the RST */ + uip_conn->tcpstateflags = UIP_CLOSED; + goto reset; +#endif /* UIP_ACTIVE_OPEN */ + + case UIP_ESTABLISHED: + /* In the ESTABLISHED state, we call upon the application to feed + data into the uip_buf. If the UIP_ACKDATA flag is set, the + application should put new data into the buffer, otherwise we are + retransmitting an old segment, and the application should put that + data into the buffer. + + If the incoming packet is a FIN, we should close the connection on + this side as well, and we send out a FIN and enter the LAST_ACK + state. We require that there is no outstanding data; otherwise the + sequence numbers will be screwed up. */ + + if(BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + if(uip_outstanding(uip_connr)) { + goto drop; + } + uip_add_rcv_nxt(1 + uip_len); + uip_flags |= UIP_CLOSE; + if(uip_len > 0) { + uip_flags |= UIP_NEWDATA; + } + UIP_APPCALL(); + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_LAST_ACK; + uip_connr->nrtx = 0; + tcp_send_finack: + BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } + + /* Check the URG flag. If this is set, the segment carries urgent + data that we must pass to the application. */ + if((BUF->flags & TCP_URG) != 0) { +#if UIP_URGDATA > 0 + uip_urglen = (BUF->urgp[0] << 8) | BUF->urgp[1]; + if(uip_urglen > uip_len) { + /* There is more urgent data in the next segment to come. */ + uip_urglen = uip_len; + } + uip_add_rcv_nxt(uip_urglen); + uip_len -= uip_urglen; + uip_urgdata = uip_appdata; + uip_appdata += uip_urglen; + } else { + uip_urglen = 0; +#else /* UIP_URGDATA > 0 */ + uip_appdata = ((char *)uip_appdata) + ((BUF->urgp[0] << 8) | BUF->urgp[1]); + uip_len -= (BUF->urgp[0] << 8) | BUF->urgp[1]; +#endif /* UIP_URGDATA > 0 */ + } + + /* If uip_len > 0 we have TCP data in the packet, and we flag this + by setting the UIP_NEWDATA flag and update the sequence number + we acknowledge. If the application has stopped the dataflow + using uip_stop(), we must not accept any data packets from the + remote host. */ + if(uip_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED)) { + uip_flags |= UIP_NEWDATA; + uip_add_rcv_nxt(uip_len); + } + + /* Check if the available buffer space advertised by the other end + is smaller than the initial MSS for this connection. If so, we + set the current MSS to the window size to ensure that the + application does not send more data than the other end can + handle. + + If the remote host advertises a zero window, we set the MSS to + the initial MSS so that the application will send an entire MSS + of data. This data will not be acknowledged by the receiver, + and the application will retransmit it. This is called the + "persistent timer" and uses the retransmission mechanim. + */ + tmp16 = ((u16_t)BUF->wnd[0] << 8) + (u16_t)BUF->wnd[1]; + if(tmp16 > uip_connr->initialmss || + tmp16 == 0) { + tmp16 = uip_connr->initialmss; + } + uip_connr->mss = tmp16; + + /* If this packet constitutes an ACK for outstanding data (flagged + by the UIP_ACKDATA flag, we should call the application since it + might want to send more data. If the incoming packet had data + from the peer (as flagged by the UIP_NEWDATA flag), the + application must also be notified. + + When the application is called, the global variable uip_len + contains the length of the incoming data. The application can + access the incoming data through the global pointer + uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN + bytes into the uip_buf array. + + If the application wishes to send any data, this data should be + put into the uip_appdata and the length of the data should be + put into uip_len. If the application don't have any data to + send, uip_len must be set to 0. */ + if(uip_flags & (UIP_NEWDATA | UIP_ACKDATA)) { + uip_slen = 0; + UIP_APPCALL(); + + appsend: + + if(uip_flags & UIP_ABORT) { + uip_slen = 0; + uip_connr->tcpstateflags = UIP_CLOSED; + BUF->flags = TCP_RST | TCP_ACK; + goto tcp_send_nodata; + } + + if(uip_flags & UIP_CLOSE) { + uip_slen = 0; + uip_connr->len = 1; + uip_connr->tcpstateflags = UIP_FIN_WAIT_1; + uip_connr->nrtx = 0; + BUF->flags = TCP_FIN | TCP_ACK; + goto tcp_send_nodata; + } + + /* If uip_slen > 0, the application has data to be sent. */ + if(uip_slen > 0) { + + /* If the connection has acknowledged data, the contents of + the ->len variable should be discarded. */ + if((uip_flags & UIP_ACKDATA) != 0) { + uip_connr->len = 0; + } + + /* If the ->len variable is non-zero the connection has + already data in transit and cannot send anymore right + now. */ + if(uip_connr->len == 0) { + + /* The application cannot send more than what is allowed by + the mss (the minumum of the MSS and the available + window). */ + if(uip_slen > uip_connr->mss) { + uip_slen = uip_connr->mss; + } + + /* Remember how much data we send out now so that we know + when everything has been acknowledged. */ + uip_connr->len = uip_slen; + } else { + + /* If the application already had unacknowledged data, we + make sure that the application does not send (i.e., + retransmit) out more than it previously sent out. */ + uip_slen = uip_connr->len; + } + } + uip_connr->nrtx = 0; + apprexmit: + uip_appdata = uip_sappdata; + + /* If the application has data to be sent, or if the incoming + packet had new data in it, we must send out a packet. */ + if(uip_slen > 0 && uip_connr->len > 0) { + /* Add the length of the IP and TCP headers. */ + uip_len = uip_connr->len + UIP_TCPIP_HLEN; + /* We always set the ACK flag in response packets. */ + BUF->flags = TCP_ACK | TCP_PSH; + /* Send the packet. */ + goto tcp_send_noopts; + } + /* If there is no data to send, just send out a pure ACK if + there is newdata. */ + if(uip_flags & UIP_NEWDATA) { + uip_len = UIP_TCPIP_HLEN; + BUF->flags = TCP_ACK; + goto tcp_send_noopts; + } + } + goto drop; + case UIP_LAST_ACK: + /* We can close this connection if the peer has acknowledged our + FIN. This is indicated by the UIP_ACKDATA flag. */ + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_CLOSED; + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + } + break; + + case UIP_FIN_WAIT_1: + /* The application has closed the connection, but the remote host + hasn't closed its end yet. Thus we do nothing but wait for a + FIN from the other side. */ + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(BUF->flags & TCP_FIN) { + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + uip_connr->len = 0; + } else { + uip_connr->tcpstateflags = UIP_CLOSING; + } + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } else if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_FIN_WAIT_2; + uip_connr->len = 0; + goto drop; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_FIN_WAIT_2: + if(uip_len > 0) { + uip_add_rcv_nxt(uip_len); + } + if(BUF->flags & TCP_FIN) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + uip_add_rcv_nxt(1); + uip_flags = UIP_CLOSE; + UIP_APPCALL(); + goto tcp_send_ack; + } + if(uip_len > 0) { + goto tcp_send_ack; + } + goto drop; + + case UIP_TIME_WAIT: + goto tcp_send_ack; + + case UIP_CLOSING: + if(uip_flags & UIP_ACKDATA) { + uip_connr->tcpstateflags = UIP_TIME_WAIT; + uip_connr->timer = 0; + } + } + goto drop; + + + /* We jump here when we are ready to send the packet, and just want + to set the appropriate TCP sequence numbers in the TCP header. */ + tcp_send_ack: + BUF->flags = TCP_ACK; + tcp_send_nodata: + uip_len = UIP_IPTCPH_LEN; + tcp_send_noopts: + BUF->tcpoffset = (UIP_TCPH_LEN / 4) << 4; + tcp_send: + /* We're done with the input processing. We are now ready to send a + reply. Our job is to fill in all the fields of the TCP and IP + headers before calculating the checksum and finally send the + packet. */ + BUF->ackno[0] = uip_connr->rcv_nxt[0]; + BUF->ackno[1] = uip_connr->rcv_nxt[1]; + BUF->ackno[2] = uip_connr->rcv_nxt[2]; + BUF->ackno[3] = uip_connr->rcv_nxt[3]; + + BUF->seqno[0] = uip_connr->snd_nxt[0]; + BUF->seqno[1] = uip_connr->snd_nxt[1]; + BUF->seqno[2] = uip_connr->snd_nxt[2]; + BUF->seqno[3] = uip_connr->snd_nxt[3]; + + BUF->proto = UIP_PROTO_TCP; + + BUF->srcport = uip_connr->lport; + BUF->destport = uip_connr->rport; + + uip_ipaddr_copy(BUF->srcipaddr, uip_hostaddr); + uip_ipaddr_copy(BUF->destipaddr, uip_connr->ripaddr); + + if(uip_connr->tcpstateflags & UIP_STOPPED) { + /* If the connection has issued uip_stop(), we advertise a zero + window so that the remote host will stop sending data. */ + BUF->wnd[0] = BUF->wnd[1] = 0; + } else { + BUF->wnd[0] = ((UIP_RECEIVE_WINDOW) >> 8); + BUF->wnd[1] = ((UIP_RECEIVE_WINDOW) & 0xff); + } + + tcp_send_noconn: + BUF->ttl = UIP_TTL; +#if UIP_CONF_IPV6 + /* For IPv6, the IP length field does not include the IPv6 IP header + length. */ + BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); + BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); +#else /* UIP_CONF_IPV6 */ + BUF->len[0] = (uip_len >> 8); + BUF->len[1] = (uip_len & 0xff); +#endif /* UIP_CONF_IPV6 */ + + BUF->urgp[0] = BUF->urgp[1] = 0; + + /* Calculate TCP checksum. */ + BUF->tcpchksum = 0; + BUF->tcpchksum = ~(uip_tcpchksum()); + + ip_send_nolen: + +#if UIP_CONF_IPV6 + BUF->vtc = 0x60; + BUF->tcflow = 0x00; + BUF->flow = 0x00; +#else /* UIP_CONF_IPV6 */ + BUF->vhl = 0x45; + BUF->tos = 0; + BUF->ipoffset[0] = BUF->ipoffset[1] = 0; + ++ipid; + BUF->ipid[0] = ipid >> 8; + BUF->ipid[1] = ipid & 0xff; + /* Calculate IP checksum. */ + BUF->ipchksum = 0; + BUF->ipchksum = ~(uip_ipchksum()); + DEBUG_PRINTF("uip ip_send_nolen: chkecum 0x%04x\n", uip_ipchksum()); +#endif /* UIP_CONF_IPV6 */ + + UIP_STAT(++uip_stat.tcp.sent); + send: + DEBUG_PRINTF("Sending packet with length %d (%d)\n", uip_len, + (BUF->len[0] << 8) | BUF->len[1]); + + UIP_STAT(++uip_stat.ip.sent); + /* Return and let the caller do the actual transmission. */ + uip_flags = 0; + return; + drop: + uip_len = 0; + uip_flags = 0; + return; +} +/*---------------------------------------------------------------------------*/ +u16_t +htons(u16_t val) +{ + return HTONS(val); +} +/*---------------------------------------------------------------------------*/ +void +uip_send(const void *data, int len) +{ + if(len > 0) { + uip_slen = len; + if(data != uip_sappdata) { + memcpy(uip_sappdata, (data), uip_slen); + } + } +} +/** @} */ diff --git a/core/net/uip.h b/core/net/uip.h new file mode 100644 index 000000000..8b0c89d72 --- /dev/null +++ b/core/net/uip.h @@ -0,0 +1,1602 @@ + +/** + * \addtogroup uip + * @{ + */ + +/** + * \file + * Header file for the uIP TCP/IP stack. + * \author Adam Dunkels + * + * The uIP TCP/IP stack header file contains definitions for a number + * of C macros that are used by uIP programs as well as internal uIP + * structures, TCP/IP header structures and function declarations. + * + */ + + +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: uip.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + +#ifndef __UIP_H__ +#define __UIP_H__ + +#include "net/uipopt.h" + +/** + * Repressentation of an IP address. + * + */ +typedef u16_t uip_ip4addr_t[2]; +typedef u16_t uip_ip6addr_t[8]; +#if UIP_CONF_IPV6 +typedef uip_ip6addr_t uip_ipaddr_t; +#else /* UIP_CONF_IPV6 */ +typedef uip_ip4addr_t uip_ipaddr_t; +#endif /* UIP_CONF_IPV6 */ + +/*---------------------------------------------------------------------------*/ +/* First, the functions that should be called from the + * system. Initialization, the periodic timer and incoming packets are + * handled by the following three functions. + */ + +/** + * \defgroup uipconffunc uIP configuration functions + * @{ + * + * The uIP configuration functions are used for setting run-time + * parameters in uIP such as IP addresses. + */ + +/** + * Set the IP address of this host. + * + * The IP address is represented as a 4-byte array where the first + * octet of the IP address is put in the first member of the 4-byte + * array. + * + * Example: + \code + + uip_ipaddr_t addr; + + uip_ipaddr(&addr, 192,168,1,2); + uip_sethostaddr(&addr); + + \endcode + * \param addr A pointer to an IP address of type uip_ipaddr_t; + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_sethostaddr(addr) uip_ipaddr_copy(uip_hostaddr, (addr)) + +/** + * Get the IP address of this host. + * + * The IP address is represented as a 4-byte array where the first + * octet of the IP address is put in the first member of the 4-byte + * array. + * + * Example: + \code + uip_ipaddr_t hostaddr; + + uip_gethostaddr(&hostaddr); + \endcode + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the currently configured IP address. + * + * \hideinitializer + */ +#define uip_gethostaddr(addr) uip_ipaddr_copy((addr), uip_hostaddr) + +/** + * Set the default router's IP address. + * + * \param addr A pointer to a uip_ipaddr_t variable containing the IP + * address of the default router. + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_setdraddr(addr) uip_ipaddr_copy(uip_draddr, (addr)) + +/** + * Set the netmask. + * + * \param addr A pointer to a uip_ipaddr_t variable containing the IP + * address of the netmask. + * + * \sa uip_ipaddr() + * + * \hideinitializer + */ +#define uip_setnetmask(addr) uip_ipaddr_copy(uip_netmask, (addr)) + + +/** + * Get the default router's IP address. + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the IP address of the default router. + * + * \hideinitializer + */ +#define uip_getdraddr(addr) uip_ipaddr_copy((addr), uip_draddr) + +/** + * Get the netmask. + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the value of the netmask. + * + * \hideinitializer + */ +#define uip_getnetmask(addr) uip_ipaddr_copy((addr), uip_netmask) + +/** @} */ + +/** + * \defgroup uipinit uIP initialization functions + * @{ + * + * The uIP initialization functions are used for booting uIP. + */ + +/** + * uIP initialization function. + * + * This function should be called at boot up to initilize the uIP + * TCP/IP stack. + */ +void uip_init(void); + +/** + * uIP initialization function. + * + * This function may be used at boot time to set the initial ip_id. + */ +void uip_setipid(u16_t id); + +/** @} */ + +/** + * \defgroup uipdevfunc uIP device driver functions + * @{ + * + * These functions are used by a network device driver for interacting + * with uIP. + */ + +/** + * Process an incoming packet. + * + * This function should be called when the device driver has received + * a packet from the network. The packet from the device driver must + * be present in the uip_buf buffer, and the length of the packet + * should be placed in the uip_len variable. + * + * When the function returns, there may be an outbound packet placed + * in the uip_buf packet buffer. If so, the uip_len variable is set to + * the length of the packet. If no packet is to be sent out, the + * uip_len variable is set to 0. + * + * The usual way of calling the function is presented by the source + * code below. + \code + uip_len = devicedriver_poll(); + if(uip_len > 0) { + uip_input(); + if(uip_len > 0) { + devicedriver_send(); + } + } + \endcode + * + * \note If you are writing a uIP device driver that needs ARP + * (Address Resolution Protocol), e.g., when running uIP over + * Ethernet, you will need to call the uIP ARP code before calling + * this function: + \code + #define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + uip_len = ethernet_devicedrver_poll(); + if(uip_len > 0) { + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if(uip_len > 0) { + ethernet_devicedriver_send(); + } + } + \endcode + * + * \hideinitializer + */ +#define uip_input() uip_process(UIP_DATA) + +/** + * Periodic processing for a connection identified by its number. + * + * This function does the necessary periodic processing (timers, + * polling) for a uIP TCP conneciton, and should be called when the + * periodic uIP timer goes off. It should be called for every + * connection, regardless of whether they are open of closed. + * + * When the function returns, it may have an outbound packet waiting + * for service in the uIP packet buffer, and if so the uip_len + * variable is set to a value larger than zero. The device driver + * should be called to send out the packet. + * + * The ususal way of calling the function is through a for() loop like + * this: + \code + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + devicedriver_send(); + } + } + \endcode + * + * \note If you are writing a uIP device driver that needs ARP + * (Address Resolution Protocol), e.g., when running uIP over + * Ethernet, you will need to call the uip_arp_out() function before + * calling the device driver: + \code + for(i = 0; i < UIP_CONNS; ++i) { + uip_periodic(i); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } + \endcode + * + * \param conn The number of the connection which is to be periodically polled. + * + * \hideinitializer + */ +#define uip_periodic(conn) do { uip_conn = &uip_conns[conn]; \ + uip_process(UIP_TIMER); } while (0) + +/** + * + * + */ +#define uip_conn_active(conn) (uip_conns[conn].tcpstateflags != UIP_CLOSED) + +/** + * Perform periodic processing for a connection identified by a pointer + * to its structure. + * + * Same as uip_periodic() but takes a pointer to the actual uip_conn + * struct instead of an integer as its argument. This function can be + * used to force periodic processing of a specific connection. + * + * \param conn A pointer to the uip_conn struct for the connection to + * be processed. + * + * \hideinitializer + */ +#define uip_periodic_conn(conn) do { uip_conn = conn; \ + uip_process(UIP_TIMER); } while (0) + +/** + * Reuqest that a particular connection should be polled. + * + * Similar to uip_periodic_conn() but does not perform any timer + * processing. The application is polled for new data. + * + * \param conn A pointer to the uip_conn struct for the connection to + * be processed. + * + * \hideinitializer + */ +#define uip_poll_conn(conn) do { uip_conn = conn; \ + uip_process(UIP_POLL_REQUEST); } while (0) + + +#if UIP_UDP +/** + * Periodic processing for a UDP connection identified by its number. + * + * This function is essentially the same as uip_periodic(), but for + * UDP connections. It is called in a similar fashion as the + * uip_periodic() function: + \code + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + devicedriver_send(); + } + } + \endcode + * + * \note As for the uip_periodic() function, special care has to be + * taken when using uIP together with ARP and Ethernet: + \code + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + if(uip_len > 0) { + uip_arp_out(); + ethernet_devicedriver_send(); + } + } + \endcode + * + * \param conn The number of the UDP connection to be processed. + * + * \hideinitializer + */ +#define uip_udp_periodic(conn) do { uip_udp_conn = &uip_udp_conns[conn]; \ + uip_process(UIP_UDP_TIMER); } while (0) + +/** + * Periodic processing for a UDP connection identified by a pointer to + * its structure. + * + * Same as uip_udp_periodic() but takes a pointer to the actual + * uip_conn struct instead of an integer as its argument. This + * function can be used to force periodic processing of a specific + * connection. + * + * \param conn A pointer to the uip_udp_conn struct for the connection + * to be processed. + * + * \hideinitializer + */ +#define uip_udp_periodic_conn(conn) do { uip_udp_conn = conn; \ + uip_process(UIP_UDP_TIMER); } while (0) + + +#endif /* UIP_UDP */ + +/** + * The uIP packet buffer. + * + * The uip_buf array is used to hold incoming and outgoing + * packets. The device driver should place incoming data into this + * buffer. When sending data, the device driver should read the link + * level headers and the TCP/IP headers from this buffer. The size of + * the link level headers is configured by the UIP_LLH_LEN define. + * + * \note The application data need not be placed in this buffer, so + * the device driver must read it from the place pointed to by the + * uip_appdata pointer as illustrated by the following example: + \code + void + devicedriver_send(void) + { + hwsend(&uip_buf[0], UIP_LLH_LEN); + if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { + hwsend(&uip_buf[UIP_LLH_LEN], uip_len - UIP_LLH_LEN); + } else { + hwsend(&uip_buf[UIP_LLH_LEN], UIP_TCPIP_HLEN); + hwsend(uip_appdata, uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN); + } + } + \endcode + */ +extern u8_t uip_buf[UIP_BUFSIZE+2]; + +/** @} */ + +/*---------------------------------------------------------------------------*/ +/* Functions that are used by the uIP application program. Opening and + * closing connections, sending and receiving data, etc. is all + * handled by the functions below. +*/ +/** + * \defgroup uipappfunc uIP application functions + * @{ + * + * Functions used by an application running of top of uIP. + */ + +/** + * Start listening to the specified port. + * + * \note Since this function expects the port number in network byte + * order, a conversion using HTONS() or htons() is necessary. + * + \code + uip_listen(HTONS(80)); + \endcode + * + * \param port A 16-bit port number in network byte order. + */ +void uip_listen(u16_t port); + +/** + * Stop listening to the specified port. + * + * \note Since this function expects the port number in network byte + * order, a conversion using HTONS() or htons() is necessary. + * + \code + uip_unlisten(HTONS(80)); + \endcode + * + * \param port A 16-bit port number in network byte order. + */ +void uip_unlisten(u16_t port); + +/** + * Connect to a remote host using TCP. + * + * This function is used to start a new connection to the specified + * port on the specied host. It allocates a new connection identifier, + * sets the connection to the SYN_SENT state and sets the + * retransmission timer to 0. This will cause a TCP SYN segment to be + * sent out the next time this connection is periodically processed, + * which usually is done within 0.5 seconds after the call to + * uip_connect(). + * + * \note This function is avaliable only if support for active open + * has been configured by defining UIP_ACTIVE_OPEN to 1 in uipopt.h. + * + * \note Since this function requires the port number to be in network + * byte order, a conversion using HTONS() or htons() is necessary. + * + \code + uip_ipaddr_t ipaddr; + + uip_ipaddr(&ipaddr, 192,168,1,2); + uip_connect(&ipaddr, HTONS(80)); + \endcode + * + * \param ripaddr The IP address of the remote hot. + * + * \param port A 16-bit port number in network byte order. + * + * \return A pointer to the uIP connection identifier for the new connection, + * or NULL if no connection could be allocated. + * + */ +struct uip_conn *uip_connect(uip_ipaddr_t *ripaddr, u16_t port); + + + +/** + * \internal + * + * Check if a connection has outstanding (i.e., unacknowledged) data. + * + * \param conn A pointer to the uip_conn structure for the connection. + * + * \hideinitializer + */ +#define uip_outstanding(conn) ((conn)->len) + +/** + * Send data on the current connection. + * + * This function is used to send out a single segment of TCP + * data. Only applications that have been invoked by uIP for event + * processing can send data. + * + * The amount of data that actually is sent out after a call to this + * funcion is determined by the maximum amount of data TCP allows. uIP + * will automatically crop the data so that only the appropriate + * amount of data is sent. The function uip_mss() can be used to query + * uIP for the amount of data that actually will be sent. + * + * \note This function does not guarantee that the sent data will + * arrive at the destination. If the data is lost in the network, the + * application will be invoked with the uip_rexmit() event being + * set. The application will then have to resend the data using this + * function. + * + * \param data A pointer to the data which is to be sent. + * + * \param len The maximum amount of data bytes to be sent. + * + * \hideinitializer + */ +void uip_send(const void *data, int len); + +/** + * The length of any incoming data that is currently avaliable (if avaliable) + * in the uip_appdata buffer. + * + * The test function uip_data() must first be used to check if there + * is any data available at all. + * + * \hideinitializer + */ +/*void uip_datalen(void);*/ +#define uip_datalen() uip_len + +/** + * The length of any out-of-band data (urgent data) that has arrived + * on the connection. + * + * \note The configuration parameter UIP_URGDATA must be set for this + * function to be enabled. + * + * \hideinitializer + */ +#define uip_urgdatalen() uip_urglen + +/** + * Close the current connection. + * + * This function will close the current connection in a nice way. + * + * \hideinitializer + */ +#define uip_close() (uip_flags = UIP_CLOSE) + +/** + * Abort the current connection. + * + * This function will abort (reset) the current connection, and is + * usually used when an error has occured that prevents using the + * uip_close() function. + * + * \hideinitializer + */ +#define uip_abort() (uip_flags = UIP_ABORT) + +/** + * Tell the sending host to stop sending data. + * + * This function will close our receiver's window so that we stop + * receiving data for the current connection. + * + * \hideinitializer + */ +#define uip_stop() (uip_conn->tcpstateflags |= UIP_STOPPED) + +/** + * Find out if the current connection has been previously stopped with + * uip_stop(). + * + * \hideinitializer + */ +#define uip_stopped(conn) ((conn)->tcpstateflags & UIP_STOPPED) + +/** + * Restart the current connection, if is has previously been stopped + * with uip_stop(). + * + * This function will open the receiver's window again so that we + * start receiving data for the current connection. + * + * \hideinitializer + */ +#define uip_restart() do { uip_flags |= UIP_NEWDATA; \ + uip_conn->tcpstateflags &= ~UIP_STOPPED; \ + } while(0) + + +/* uIP tests that can be made to determine in what state the current + connection is, and what the application function should do. */ + +/** + * Is the current connection a UDP connection? + * + * This function checks whether the current connection is a UDP connection. + * + * \hideinitializer + * + */ +#define uip_udpconnection() (uip_conn == NULL) + +/** + * Is new incoming data available? + * + * Will reduce to non-zero if there is new data for the application + * present at the uip_appdata pointer. The size of the data is + * avaliable through the uip_len variable. + * + * \hideinitializer + */ +#define uip_newdata() (uip_flags & UIP_NEWDATA) + +/** + * Has previously sent data been acknowledged? + * + * Will reduce to non-zero if the previously sent data has been + * acknowledged by the remote host. This means that the application + * can send new data. + * + * \hideinitializer + */ +#define uip_acked() (uip_flags & UIP_ACKDATA) + +/** + * Has the connection just been connected? + * + * Reduces to non-zero if the current connection has been connected to + * a remote host. This will happen both if the connection has been + * actively opened (with uip_connect()) or passively opened (with + * uip_listen()). + * + * \hideinitializer + */ +#define uip_connected() (uip_flags & UIP_CONNECTED) + +/** + * Has the connection been closed by the other end? + * + * Is non-zero if the connection has been closed by the remote + * host. The application may then do the necessary clean-ups. + * + * \hideinitializer + */ +#define uip_closed() (uip_flags & UIP_CLOSE) + +/** + * Has the connection been aborted by the other end? + * + * Non-zero if the current connection has been aborted (reset) by the + * remote host. + * + * \hideinitializer + */ +#define uip_aborted() (uip_flags & UIP_ABORT) + +/** + * Has the connection timed out? + * + * Non-zero if the current connection has been aborted due to too many + * retransmissions. + * + * \hideinitializer + */ +#define uip_timedout() (uip_flags & UIP_TIMEDOUT) + +/** + * Do we need to retransmit previously data? + * + * Reduces to non-zero if the previously sent data has been lost in + * the network, and the application should retransmit it. The + * application should send the exact same data as it did the last + * time, using the uip_send() function. + * + * \hideinitializer + */ +#define uip_rexmit() (uip_flags & UIP_REXMIT) + +/** + * Is the connection being polled by uIP? + * + * Is non-zero if the reason the application is invoked is that the + * current connection has been idle for a while and should be + * polled. + * + * The polling event can be used for sending data without having to + * wait for the remote host to send data. + * + * \hideinitializer + */ +#define uip_poll() (uip_flags & UIP_POLL) + +/** + * Get the initial maxium segment size (MSS) of the current + * connection. + * + * \hideinitializer + */ +#define uip_initialmss() (uip_conn->initialmss) + +/** + * Get the current maxium segment size that can be sent on the current + * connection. + * + * The current maxiumum segment size that can be sent on the + * connection is computed from the receiver's window and the MSS of + * the connection (which also is available by calling + * uip_initialmss()). + * + * \hideinitializer + */ +#define uip_mss() (uip_conn->mss) + +/** + * Set up a new UDP connection. + * + * This function sets up a new UDP connection. The function will + * automatically allocate an unused local port for the new + * connection. However, another port can be chosen by using the + * uip_udp_bind() call, after the uip_udp_new() function has been + * called. + * + * Example: + \code + uip_ipaddr_t addr; + struct uip_udp_conn *c; + + uip_ipaddr(&addr, 192,168,2,1); + c = uip_udp_new(&addr, HTONS(12345)); + if(c != NULL) { + uip_udp_bind(c, HTONS(12344)); + } + \endcode + * \param ripaddr The IP address of the remote host. + * + * \param rport The remote port number in network byte order. + * + * \return The uip_udp_conn structure for the new connection or NULL + * if no connection could be allocated. + */ +struct uip_udp_conn *uip_udp_new(uip_ipaddr_t *ripaddr, u16_t rport); + +/** + * Removed a UDP connection. + * + * \param conn A pointer to the uip_udp_conn structure for the connection. + * + * \hideinitializer + */ +#define uip_udp_remove(conn) (conn)->lport = 0 + +/** + * Bind a UDP connection to a local port. + * + * \param conn A pointer to the uip_udp_conn structure for the + * connection. + * + * \param port The local port number, in network byte order. + * + * \hideinitializer + */ +#define uip_udp_bind(conn, port) (conn)->lport = port + +/** + * Send a UDP datagram of length len on the current connection. + * + * This function can only be called in response to a UDP event (poll + * or newdata). The data must be present in the uip_buf buffer, at the + * place pointed to by the uip_appdata pointer. + * + * \param len The length of the data in the uip_buf buffer. + * + * \hideinitializer + */ +#define uip_udp_send(len) uip_send((char *)uip_appdata, len) + +/** @} */ + +/* uIP convenience and converting functions. */ + +/** + * \defgroup uipconvfunc uIP conversion functions + * @{ + * + * These functions can be used for converting between different data + * formats used by uIP. + */ + +/** + * Construct an IP address from four bytes. + * + * This function constructs an IP address of the type that uIP handles + * internally from four bytes. The function is handy for specifying IP + * addresses to use with e.g. the uip_connect() function. + * + * Example: + \code + uip_ipaddr_t ipaddr; + struct uip_conn *c; + + uip_ipaddr(&ipaddr, 192,168,1,2); + c = uip_connect(&ipaddr, HTONS(80)); + \endcode + * + * \param addr A pointer to a uip_ipaddr_t variable that will be + * filled in with the IP address. + * + * \param addr0 The first octet of the IP address. + * \param addr1 The second octet of the IP address. + * \param addr2 The third octet of the IP address. + * \param addr3 The forth octet of the IP address. + * + * \hideinitializer + */ +#define uip_ipaddr(addr, addr0,addr1,addr2,addr3) do { \ + ((u16_t *)(addr))[0] = HTONS(((addr0) << 8) | (addr1)); \ + ((u16_t *)(addr))[1] = HTONS(((addr2) << 8) | (addr3)); \ + } while(0) + +/** + * Construct an IPv6 address from eight 16-bit words. + * + * This function constructs an IPv6 address. + * + * \hideinitializer + */ +#define uip_ip6addr(addr, addr0,addr1,addr2,addr3,addr4,addr5,addr6,addr7) do { \ + ((u16_t *)(addr))[0] = HTONS((addr0)); \ + ((u16_t *)(addr))[1] = HTONS((addr1)); \ + ((u16_t *)(addr))[2] = HTONS((addr2)); \ + ((u16_t *)(addr))[3] = HTONS((addr3)); \ + ((u16_t *)(addr))[4] = HTONS((addr4)); \ + ((u16_t *)(addr))[5] = HTONS((addr5)); \ + ((u16_t *)(addr))[6] = HTONS((addr6)); \ + ((u16_t *)(addr))[7] = HTONS((addr7)); \ + } while(0) + +/** + * Copy an IP address to another IP address. + * + * Copies an IP address from one place to another. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr_copy(&ipaddr2, &ipaddr1); + \endcode + * + * \param dest The destination for the copy. + * \param src The source from where to copy. + * + * \hideinitializer + */ +#if !UIP_CONF_IPV6 +#define uip_ipaddr_copy(dest, src) do { \ + ((u16_t *)dest)[0] = ((u16_t *)src)[0]; \ + ((u16_t *)dest)[1] = ((u16_t *)src)[1]; \ + } while(0) +#else /* !UIP_CONF_IPV6 */ +#define uip_ipaddr_copy(dest, src) memcpy(dest, src, sizeof(uip_ip6addr_t)) +#endif /* !UIP_CONF_IPV6 */ + +/** + * Compare two IP addresses + * + * Compares two IP addresses. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + if(uip_ipaddr_cmp(&ipaddr2, &ipaddr1)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * + * \hideinitializer + */ +#if !UIP_CONF_IPV6 +#define uip_ipaddr_cmp(addr1, addr2) (((u16_t *)addr1)[0] == ((u16_t *)addr2)[0] && \ + ((u16_t *)addr1)[1] == ((u16_t *)addr2)[1]) +#else /* !UIP_CONF_IPV6 */ +#define uip_ipaddr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0) +#endif /* !UIP_CONF_IPV6 */ + +/** + * Compare two IP addresses with netmasks + * + * Compares two IP addresses with netmasks. The masks are used to mask + * out the bits that are to be compared. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2, mask; + + uip_ipaddr(&mask, 255,255,255,0); + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr(&ipaddr2, 192,16,1,3); + if(uip_ipaddr_maskcmp(&ipaddr1, &ipaddr2, &mask)) { + printf("They are the same"); + } + \endcode + * + * \param addr1 The first IP address. + * \param addr2 The second IP address. + * \param mask The netmask. + * + * \hideinitializer + */ +#define uip_ipaddr_maskcmp(addr1, addr2, mask) \ + (((((u16_t *)addr1)[0] & ((u16_t *)mask)[0]) == \ + (((u16_t *)addr2)[0] & ((u16_t *)mask)[0])) && \ + ((((u16_t *)addr1)[1] & ((u16_t *)mask)[1]) == \ + (((u16_t *)addr2)[1] & ((u16_t *)mask)[1]))) + + +/** + * Mask out the network part of an IP address. + * + * Masks out the network part of an IP address, given the address and + * the netmask. + * + * Example: + \code + uip_ipaddr_t ipaddr1, ipaddr2, netmask; + + uip_ipaddr(&ipaddr1, 192,16,1,2); + uip_ipaddr(&netmask, 255,255,255,0); + uip_ipaddr_mask(&ipaddr2, &ipaddr1, &netmask); + \endcode + * + * In the example above, the variable "ipaddr2" will contain the IP + * address 192.168.1.0. + * + * \param dest Where the result is to be placed. + * \param src The IP address. + * \param mask The netmask. + * + * \hideinitializer + */ +#define uip_ipaddr_mask(dest, src, mask) do { \ + ((u16_t *)dest)[0] = ((u16_t *)src)[0] & ((u16_t *)mask)[0]; \ + ((u16_t *)dest)[1] = ((u16_t *)src)[1] & ((u16_t *)mask)[1]; \ + } while(0) + +/** + * Pick the first octet of an IP address. + * + * Picks out the first octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr1(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 1. + * + * \hideinitializer + */ +#define uip_ipaddr1(addr) (htons(((u16_t *)(addr))[0]) >> 8) + +/** + * Pick the second octet of an IP address. + * + * Picks out the second octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr2(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 2. + * + * \hideinitializer + */ +#define uip_ipaddr2(addr) (htons(((u16_t *)(addr))[0]) & 0xff) + +/** + * Pick the third octet of an IP address. + * + * Picks out the third octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr3(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 3. + * + * \hideinitializer + */ +#define uip_ipaddr3(addr) (htons(((u16_t *)(addr))[1]) >> 8) + +/** + * Pick the fourth octet of an IP address. + * + * Picks out the fourth octet of an IP address. + * + * Example: + \code + uip_ipaddr_t ipaddr; + u8_t octet; + + uip_ipaddr(&ipaddr, 1,2,3,4); + octet = uip_ipaddr4(&ipaddr); + \endcode + * + * In the example above, the variable "octet" will contain the value 4. + * + * \hideinitializer + */ +#define uip_ipaddr4(addr) (htons(((u16_t *)(addr))[1]) & 0xff) + +/** + * Convert 16-bit quantity from host byte order to network byte order. + * + * This macro is primarily used for converting constants from host + * byte order to network byte order. For converting variables to + * network byte order, use the htons() function instead. + * + * \hideinitializer + */ +#ifndef HTONS +# if UIP_BYTE_ORDER == UIP_BIG_ENDIAN +# define HTONS(n) (n) +# else /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +# define HTONS(n) (u16_t)((((u16_t) (n)) << 8) | (((u16_t) (n)) >> 8)) +# endif /* UIP_BYTE_ORDER == UIP_BIG_ENDIAN */ +#else +#error "HTONS already defined!" +#endif /* HTONS */ + +/** + * Convert 16-bit quantity from host byte order to network byte order. + * + * This function is primarily used for converting variables from host + * byte order to network byte order. For converting constants to + * network byte order, use the HTONS() macro instead. + */ +#ifndef htons +u16_t htons(u16_t val); +#endif /* htons */ +#ifndef ntohs +#define ntohs htons +#endif + +/** @} */ + +/** + * Pointer to the application data in the packet buffer. + * + * This pointer points to the application data when the application is + * called. If the application wishes to send data, the application may + * use this space to write the data into before calling uip_send(). + */ +extern void *uip_appdata; + +#if UIP_URGDATA > 0 +/* u8_t *uip_urgdata: + * + * This pointer points to any urgent data that has been received. Only + * present if compiled with support for urgent data (UIP_URGDATA). + */ +extern void *uip_urgdata; +#endif /* UIP_URGDATA > 0 */ + + +/** + * \defgroup uipdrivervars Variables used in uIP device drivers + * @{ + * + * uIP has a few global variables that are used in device drivers for + * uIP. + */ + +/** + * The length of the packet in the uip_buf buffer. + * + * The global variable uip_len holds the length of the packet in the + * uip_buf buffer. + * + * When the network device driver calls the uIP input function, + * uip_len should be set to the length of the packet in the uip_buf + * buffer. + * + * When sending packets, the device driver should use the contents of + * the uip_len variable to determine the length of the outgoing + * packet. + * + */ +extern u16_t uip_len; + +/** @} */ + +#if UIP_URGDATA > 0 +extern u16_t uip_urglen, uip_surglen; +#endif /* UIP_URGDATA > 0 */ + + +/** + * Representation of a uIP TCP connection. + * + * The uip_conn structure is used for identifying a connection. All + * but one field in the structure are to be considered read-only by an + * application. The only exception is the appstate field whos purpose + * is to let the application store application-specific state (e.g., + * file pointers) for the connection. The type of this field is + * configured in the "uipopt.h" header file. + */ +struct uip_conn { + uip_ipaddr_t ripaddr; /**< The IP address of the remote host. */ + + u16_t lport; /**< The local TCP port, in network byte order. */ + u16_t rport; /**< The local remote TCP port, in network byte + order. */ + + u8_t rcv_nxt[4]; /**< The sequence number that we expect to + receive next. */ + u8_t snd_nxt[4]; /**< The sequence number that was last sent by + us. */ + u16_t len; /**< Length of the data that was previously sent. */ + u16_t mss; /**< Current maximum segment size for the + connection. */ + u16_t initialmss; /**< Initial maximum segment size for the + connection. */ + u8_t sa; /**< Retransmission time-out calculation state + variable. */ + u8_t sv; /**< Retransmission time-out calculation state + variable. */ + u8_t rto; /**< Retransmission time-out. */ + u8_t tcpstateflags; /**< TCP state and flags. */ + u8_t timer; /**< The retransmission timer. */ + u8_t nrtx; /**< The number of retransmissions for the last + segment sent. */ + + /** The application state. */ + uip_tcp_appstate_t appstate; +}; + + +/** + * Pointer to the current TCP connection. + * + * The uip_conn pointer can be used to access the current TCP + * connection. + */ +extern struct uip_conn *uip_conn; +/* The array containing all uIP connections. */ +extern struct uip_conn uip_conns[UIP_CONNS]; +/** + * \addtogroup uiparch + * @{ + */ + +/** + * 4-byte array used for the 32-bit sequence number calculations. + */ +extern u8_t uip_acc32[4]; + +/** @} */ + + +#if UIP_UDP +/** + * Representation of a uIP UDP connection. + */ +struct uip_udp_conn { + uip_ipaddr_t ripaddr; /**< The IP address of the remote peer. */ + u16_t lport; /**< The local port number in network byte order. */ + u16_t rport; /**< The remote port number in network byte order. */ + u8_t ttl; /**< Default time-to-live. */ + + /** The application state. */ + uip_udp_appstate_t appstate; +}; + +/** + * The current UDP connection. + */ +extern struct uip_udp_conn *uip_udp_conn; +extern struct uip_udp_conn uip_udp_conns[UIP_UDP_CONNS]; +#endif /* UIP_UDP */ + +/** + * The structure holding the TCP/IP statistics that are gathered if + * UIP_STATISTICS is set to 1. + * + */ +struct uip_stats { + struct { + uip_stats_t drop; /**< Number of dropped packets at the IP + layer. */ + uip_stats_t recv; /**< Number of received packets at the IP + layer. */ + uip_stats_t sent; /**< Number of sent packets at the IP + layer. */ + uip_stats_t vhlerr; /**< Number of packets dropped due to wrong + IP version or header length. */ + uip_stats_t hblenerr; /**< Number of packets dropped due to wrong + IP length, high byte. */ + uip_stats_t lblenerr; /**< Number of packets dropped due to wrong + IP length, low byte. */ + uip_stats_t fragerr; /**< Number of packets dropped since they + were IP fragments. */ + uip_stats_t chkerr; /**< Number of packets dropped due to IP + checksum errors. */ + uip_stats_t protoerr; /**< Number of packets dropped since they + were neither ICMP, UDP nor TCP. */ + } ip; /**< IP statistics. */ + struct { + uip_stats_t drop; /**< Number of dropped ICMP packets. */ + uip_stats_t recv; /**< Number of received ICMP packets. */ + uip_stats_t sent; /**< Number of sent ICMP packets. */ + uip_stats_t typeerr; /**< Number of ICMP packets with a wrong + type. */ + } icmp; /**< ICMP statistics. */ + struct { + uip_stats_t drop; /**< Number of dropped TCP segments. */ + uip_stats_t recv; /**< Number of recived TCP segments. */ + uip_stats_t sent; /**< Number of sent TCP segments. */ + uip_stats_t chkerr; /**< Number of TCP segments with a bad + checksum. */ + uip_stats_t ackerr; /**< Number of TCP segments with a bad ACK + number. */ + uip_stats_t rst; /**< Number of recevied TCP RST (reset) segments. */ + uip_stats_t rexmit; /**< Number of retransmitted TCP segments. */ + uip_stats_t syndrop; /**< Number of dropped SYNs due to too few + connections was avaliable. */ + uip_stats_t synrst; /**< Number of SYNs for closed ports, + triggering a RST. */ + } tcp; /**< TCP statistics. */ +#if UIP_UDP + struct { + uip_stats_t drop; /**< Number of dropped UDP segments. */ + uip_stats_t recv; /**< Number of recived UDP segments. */ + uip_stats_t sent; /**< Number of sent UDP segments. */ + uip_stats_t chkerr; /**< Number of UDP segments with a bad + checksum. */ + } udp; /**< UDP statistics. */ +#endif /* UIP_UDP */ +}; + +/** + * The uIP TCP/IP statistics. + * + * This is the variable in which the uIP TCP/IP statistics are gathered. + */ +extern struct uip_stats uip_stat; + + +/*---------------------------------------------------------------------------*/ +/* All the stuff below this point is internal to uIP and should not be + * used directly by an application or by a device driver. + */ +/*---------------------------------------------------------------------------*/ +/* u8_t uip_flags: + * + * When the application is called, uip_flags will contain the flags + * that are defined in this file. Please read below for more + * infomation. + */ +extern u8_t uip_flags; + +/* The following flags may be set in the global variable uip_flags + before calling the application callback. The UIP_ACKDATA, + UIP_NEWDATA, and UIP_CLOSE flags may both be set at the same time, + whereas the others are mutualy exclusive. Note that these flags + should *NOT* be accessed directly, but only through the uIP + functions/macros. */ + +#define UIP_ACKDATA 1 /* Signifies that the outstanding data was + acked and the application should send + out new data instead of retransmitting + the last data. */ +#define UIP_NEWDATA 2 /* Flags the fact that the peer has sent + us new data. */ +#define UIP_REXMIT 4 /* Tells the application to retransmit the + data that was last sent. */ +#define UIP_POLL 8 /* Used for polling the application, to + check if the application has data that + it wants to send. */ +#define UIP_CLOSE 16 /* The remote host has closed the + connection, thus the connection has + gone away. Or the application signals + that it wants to close the + connection. */ +#define UIP_ABORT 32 /* The remote host has aborted the + connection, thus the connection has + gone away. Or the application signals + that it wants to abort the + connection. */ +#define UIP_CONNECTED 64 /* We have got a connection from a remote + host and have set up a new connection + for it, or an active connection has + been successfully established. */ + +#define UIP_TIMEDOUT 128 /* The connection has been aborted due to + too many retransmissions. */ + + +/* uip_process(flag): + * + * The actual uIP function which does all the work. + */ +void uip_process(u8_t flag); + +/* The following flags are passed as an argument to the uip_process() + function. They are used to distinguish between the two cases where + uip_process() is called. It can be called either because we have + incoming data that should be processed, or because the periodic + timer has fired. These values are never used directly, but only in + the macrose defined in this file. */ + +#define UIP_DATA 1 /* Tells uIP that there is incoming + data in the uip_buf buffer. The + length of the data is stored in the + global variable uip_len. */ +#define UIP_TIMER 2 /* Tells uIP that the periodic timer + has fired. */ +#define UIP_POLL_REQUEST 3 /* Tells uIP that a connection should + be polled. */ +#define UIP_UDP_SEND_CONN 4 /* Tells uIP that a UDP datagram + should be constructed in the + uip_buf buffer. */ +#if UIP_UDP +#define UIP_UDP_TIMER 5 +#endif /* UIP_UDP */ + +/* The TCP states used in the uip_conn->tcpstateflags. */ +#define UIP_CLOSED 0 +#define UIP_SYN_RCVD 1 +#define UIP_SYN_SENT 2 +#define UIP_ESTABLISHED 3 +#define UIP_FIN_WAIT_1 4 +#define UIP_FIN_WAIT_2 5 +#define UIP_CLOSING 6 +#define UIP_TIME_WAIT 7 +#define UIP_LAST_ACK 8 +#define UIP_TS_MASK 15 + +#define UIP_STOPPED 16 + +/* The TCP and IP headers. */ +struct uip_tcpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcflow; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPv4 header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ + + /* TCP header. */ + u16_t srcport, + destport; + u8_t seqno[4], + ackno[4], + tcpoffset, + flags, + wnd[2]; + u16_t tcpchksum; + u8_t urgp[2]; + u8_t optdata[4]; +}; + +/* The ICMP and IP headers. */ +struct uip_icmpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcf; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IPv4 header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ + + /* ICMP (echo) header. */ + u8_t type, icode; + u16_t icmpchksum; +#if !UIP_CONF_IPV6 + u16_t id, seqno; +#else /* !UIP_CONF_IPV6 */ + u8_t flags, reserved1, reserved2, reserved3; + u8_t icmp6data[16]; + u8_t options[1]; +#endif /* !UIP_CONF_IPV6 */ +}; + + +/* The UDP and IP headers. */ +struct uip_udpip_hdr { +#if UIP_CONF_IPV6 + /* IPv6 header. */ + u8_t vtc, + tcf; + u16_t flow; + u8_t len[2]; + u8_t proto, ttl; + uip_ip6addr_t srcipaddr, destipaddr; +#else /* UIP_CONF_IPV6 */ + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +#endif /* UIP_CONF_IPV6 */ + + /* UDP header. */ + u16_t srcport, + destport; + u16_t udplen; + u16_t udpchksum; +}; + + + +/** + * The buffer size available for user data in the \ref uip_buf buffer. + * + * This macro holds the available size for user data in the \ref + * uip_buf buffer. The macro is intended to be used for checking + * bounds of available user data. + * + * Example: + \code + snprintf(uip_appdata, UIP_APPDATA_SIZE, "%u\n", i); + \endcode + * + * \hideinitializer + */ +#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) + + +#define UIP_PROTO_ICMP 1 +#define UIP_PROTO_TCP 6 +#define UIP_PROTO_UDP 17 +#define UIP_PROTO_ICMP6 58 + +/* Header sizes. */ +#if UIP_CONF_IPV6 +#define UIP_IPH_LEN 40 +#else /* UIP_CONF_IPV6 */ +#define UIP_IPH_LEN 20 /* Size of IP header */ +#endif /* UIP_CONF_IPV6 */ +#define UIP_UDPH_LEN 8 /* Size of UDP header */ +#define UIP_TCPH_LEN 20 /* Size of TCP header */ +#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + + UDP + header */ +#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + + TCP + header */ +#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN + + +#if UIP_FIXEDADDR +extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; +#else /* UIP_FIXEDADDR */ +extern uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr; +#endif /* UIP_FIXEDADDR */ +extern const uip_ipaddr_t uip_broadcast_addr; + + +/** + * Representation of a 48-bit Ethernet address. + */ +struct uip_eth_addr { + u8_t addr[6]; +}; + +/** + * Calculate the Internet checksum over a buffer. + * + * The Internet checksum is the one's complement of the one's + * complement sum of all 16-bit words in the buffer. + * + * See RFC1071. + * + * \param buf A pointer to the buffer over which the checksum is to be + * computed. + * + * \param len The length of the buffer over which the checksum is to + * be computed. + * + * \return The Internet checksum of the buffer. + */ +u16_t uip_chksum(u16_t *buf, u16_t len); + +/** + * Calculate the IP header checksum of the packet header in uip_buf. + * + * The IP header checksum is the Internet checksum of the 20 bytes of + * the IP header. + * + * \return The IP header checksum of the IP header in the uip_buf + * buffer. + */ +u16_t uip_ipchksum(void); + +/** + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. + * + * The TCP checksum is the Internet checksum of data contents of the + * TCP segment, and a pseudo-header as defined in RFC793. + * + * \return The TCP checksum of the TCP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_tcpchksum(void); + +/** + * Calculate the UDP checksum of the packet in uip_buf and uip_appdata. + * + * The UDP checksum is the Internet checksum of data contents of the + * UDP segment, and a pseudo-header as defined in RFC768. + * + * \return The UDP checksum of the UDP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_udpchksum(void); + + +#endif /* __UIP_H__ */ + + +/** @} */ diff --git a/core/net/uip_arch.h b/core/net/uip_arch.h new file mode 100644 index 000000000..9ee37578c --- /dev/null +++ b/core/net/uip_arch.h @@ -0,0 +1,138 @@ +/** + * \addtogroup uip + * {@ + */ + +/** + * \defgroup uiparch Architecture specific uIP functions + * @{ + * + * The functions in the architecture specific module implement the IP + * check sum and 32-bit additions. + * + * The IP checksum calculation is the most computationally expensive + * operation in the TCP/IP stack and it therefore pays off to + * implement this in efficient assembler. The purpose of the uip-arch + * module is to let the checksum functions to be implemented in + * architecture specific assembler. + * + */ + +/** + * \file + * Declarations of architecture specific functions. + * \author Adam Dunkels + */ + +/* + * Copyright (c) 2001, 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: uip_arch.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + +#ifndef __UIP_ARCH_H__ +#define __UIP_ARCH_H__ + +#include "net/uip.h" + +/** + * Carry out a 32-bit addition. + * + * Because not all architectures for which uIP is intended has native + * 32-bit arithmetic, uIP uses an external C function for doing the + * required 32-bit additions in the TCP protocol processing. This + * function should add the two arguments and place the result in the + * global variable uip_acc32. + * + * \note The 32-bit integer pointed to by the op32 parameter and the + * result in the uip_acc32 variable are in network byte order (big + * endian). + * + * \param op32 A pointer to a 4-byte array representing a 32-bit + * integer in network byte order (big endian). + * + * \param op16 A 16-bit integer in host byte order. + */ +void uip_add32(u8_t *op32, u16_t op16); + +/** + * Calculate the Internet checksum over a buffer. + * + * The Internet checksum is the one's complement of the one's + * complement sum of all 16-bit words in the buffer. + * + * See RFC1071. + * + * \note This function is not called in the current version of uIP, + * but future versions might make use of it. + * + * \param buf A pointer to the buffer over which the checksum is to be + * computed. + * + * \param len The length of the buffer over which the checksum is to + * be computed. + * + * \return The Internet checksum of the buffer. + */ +u16_t uip_chksum(u16_t *buf, u16_t len); + +/** + * Calculate the IP header checksum of the packet header in uip_buf. + * + * The IP header checksum is the Internet checksum of the 20 bytes of + * the IP header. + * + * \return The IP header checksum of the IP header in the uip_buf + * buffer. + */ +u16_t uip_ipchksum(void); + +/** + * Calculate the TCP checksum of the packet in uip_buf and uip_appdata. + * + * The TCP checksum is the Internet checksum of data contents of the + * TCP segment, and a pseudo-header as defined in RFC793. + * + * \note The uip_appdata pointer that points to the packet data may + * point anywhere in memory, so it is not possible to simply calculate + * the Internet checksum of the contents of the uip_buf buffer. + * + * \return The TCP checksum of the TCP segment in uip_buf and pointed + * to by uip_appdata. + */ +u16_t uip_tcpchksum(void); + +u16_t uip_udpchksum(void); + +/** @} */ +/** @} */ + +#endif /* __UIP_ARCH_H__ */ diff --git a/core/net/uip_arp.c b/core/net/uip_arp.c new file mode 100644 index 000000000..2c54e47c1 --- /dev/null +++ b/core/net/uip_arp.c @@ -0,0 +1,427 @@ +/** + * \addtogroup uip + * @{ + */ + +/** + * \defgroup uiparp uIP Address Resolution Protocol + * @{ + * + * The Address Resolution Protocol ARP is used for mapping between IP + * addresses and link level addresses such as the Ethernet MAC + * addresses. ARP uses broadcast queries to ask for the link level + * address of a known IP address and the host which is configured with + * the IP address for which the query was meant, will respond with its + * link level address. + * + * \note This ARP implementation only supports Ethernet. + */ + +/** + * \file + * Implementation of the ARP Address Resolution Protocol. + * \author Adam Dunkels + * + */ + +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: uip_arp.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + + +#include "net/uip_arp.h" + +#include + +struct arp_hdr { + struct uip_eth_hdr ethhdr; + u16_t hwtype; + u16_t protocol; + u8_t hwlen; + u8_t protolen; + u16_t opcode; + struct uip_eth_addr shwaddr; + u16_t sipaddr[2]; + struct uip_eth_addr dhwaddr; + u16_t dipaddr[2]; +}; + +struct ethip_hdr { + struct uip_eth_hdr ethhdr; + /* IP header. */ + u8_t vhl, + tos, + len[2], + ipid[2], + ipoffset[2], + ttl, + proto; + u16_t ipchksum; + u16_t srcipaddr[2], + destipaddr[2]; +}; + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +#define ARP_HWTYPE_ETH 1 + +struct arp_entry { + u16_t ipaddr[2]; + struct uip_eth_addr ethaddr; + u8_t time; +}; + +static const struct uip_eth_addr broadcast_ethaddr = + {{0xff,0xff,0xff,0xff,0xff,0xff}}; +static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff}; + +static struct arp_entry arp_table[UIP_ARPTAB_SIZE]; +static u16_t ipaddr[2]; +static u8_t i, c; + +static u8_t arptime; +static u8_t tmpage; + +#define BUF ((struct arp_hdr *)&uip_buf[0]) +#define IPBUF ((struct ethip_hdr *)&uip_buf[0]) +/*-----------------------------------------------------------------------------------*/ +/** + * Initialize the ARP module. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_init(void) +{ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + memset(arp_table[i].ipaddr, 0, 4); + } +} +/*-----------------------------------------------------------------------------------*/ +/** + * Periodic ARP processing function. + * + * This function performs periodic timer processing in the ARP module + * and should be called at regular intervals. The recommended interval + * is 10 seconds between the calls. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_timer(void) +{ + struct arp_entry *tabptr; + + ++arptime; + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 && + arptime - tabptr->time >= UIP_ARP_MAXAGE) { + memset(tabptr->ipaddr, 0, 4); + } + } + +} +/*-----------------------------------------------------------------------------------*/ +static void +uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr) +{ + register struct arp_entry *tabptr; + /* Walk through the ARP mapping table and try to find an entry to + update. If none is found, the IP -> MAC address mapping is + inserted in the ARP table. */ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + + tabptr = &arp_table[i]; + /* Only check those entries that are actually in use. */ + if(tabptr->ipaddr[0] != 0 && + tabptr->ipaddr[1] != 0) { + + /* Check if the source IP address of the incoming packet matches + the IP address in this ARP table entry. */ + if(ipaddr[0] == tabptr->ipaddr[0] && + ipaddr[1] == tabptr->ipaddr[1]) { + + /* An old entry found, update this and return. */ + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = arptime; + + return; + } + } + } + + /* If we get here, no existing ARP table entry was found, so we + create one. */ + + /* First, we try to find an unused entry in the ARP table. */ + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(tabptr->ipaddr[0] == 0 && + tabptr->ipaddr[1] == 0) { + break; + } + } + + /* If no unused entry is found, we try to find the oldest entry and + throw it away. */ + if(i == UIP_ARPTAB_SIZE) { + tmpage = 0; + c = 0; + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(arptime - tabptr->time > tmpage) { + tmpage = arptime - tabptr->time; + c = i; + } + } + i = c; + tabptr = &arp_table[i]; + } + + /* Now, i is the ARP table entry which we will fill with the new + information. */ + memcpy(tabptr->ipaddr, ipaddr, 4); + memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6); + tabptr->time = arptime; +} +/*-----------------------------------------------------------------------------------*/ +/** + * ARP processing for incoming IP packets + * + * This function should be called by the device driver when an IP + * packet has been received. The function will check if the address is + * in the ARP cache, and if so the ARP cache entry will be + * refreshed. If no ARP cache entry was found, a new one is created. + * + * This function expects an IP packet with a prepended Ethernet header + * in the uip_buf[] buffer, and the length of the packet in the global + * variable uip_len. + */ +/*-----------------------------------------------------------------------------------*/ +#if 0 +void +uip_arp_ipin(void) +{ + uip_len -= sizeof(struct uip_eth_hdr); + + /* Only insert/update an entry if the source IP address of the + incoming IP packet comes from a host on the local network. */ + if((IPBUF->srcipaddr[0] & uip_netmask[0]) != + (uip_hostaddr[0] & uip_netmask[0])) { + return; + } + if((IPBUF->srcipaddr[1] & uip_netmask[1]) != + (uip_hostaddr[1] & uip_netmask[1])) { + return; + } + uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src)); + + return; +} +#endif /* 0 */ +/*-----------------------------------------------------------------------------------*/ +/** + * ARP processing for incoming ARP packets. + * + * This function should be called by the device driver when an ARP + * packet has been received. The function will act differently + * depending on the ARP packet type: if it is a reply for a request + * that we previously sent out, the ARP cache will be filled in with + * the values from the ARP reply. If the incoming ARP packet is an ARP + * request for our IP address, an ARP reply packet is created and put + * into the uip_buf[] buffer. + * + * When the function returns, the value of the global variable uip_len + * indicates whether the device driver should send out a packet or + * not. If uip_len is zero, no packet should be sent. If uip_len is + * non-zero, it contains the length of the outbound packet that is + * present in the uip_buf[] buffer. + * + * This function expects an ARP packet with a prepended Ethernet + * header in the uip_buf[] buffer, and the length of the packet in the + * global variable uip_len. + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_arpin(void) +{ + + if(uip_len < sizeof(struct arp_hdr)) { + uip_len = 0; + return; + } + uip_len = 0; + + switch(BUF->opcode) { + case HTONS(ARP_REQUEST): + /* ARP request. If it asked for our address, we send out a + reply. */ + /* if(BUF->dipaddr[0] == uip_hostaddr[0] && + BUF->dipaddr[1] == uip_hostaddr[1]) {*/ + if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { + /* First, we register the one who made the request in our ARP + table, since it is likely that we will do more communication + with this host in the future. */ + uip_arp_update(BUF->sipaddr, &BUF->shwaddr); + + /* The reply opcode is 2. */ + BUF->opcode = HTONS(2); + + memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6); + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6); + + BUF->dipaddr[0] = BUF->sipaddr[0]; + BUF->dipaddr[1] = BUF->sipaddr[1]; + BUF->sipaddr[0] = uip_hostaddr[0]; + BUF->sipaddr[1] = uip_hostaddr[1]; + + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + uip_len = sizeof(struct arp_hdr); + } + break; + case HTONS(ARP_REPLY): + /* ARP reply. We insert or update the ARP table if it was meant + for us. */ + /* if(BUF->dipaddr[0] == uip_hostaddr[0] && + BUF->dipaddr[1] == uip_hostaddr[1]) {*/ + if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) { + uip_arp_update(BUF->sipaddr, &BUF->shwaddr); + } + break; + } + + return; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Prepend Ethernet header to an outbound IP packet and see if we need + * to send out an ARP request. + * + * This function should be called before sending out an IP packet. The + * function checks the destination IP address of the IP packet to see + * what Ethernet MAC address that should be used as a destination MAC + * address on the Ethernet. + * + * If the destination IP address is in the local network (determined + * by logical ANDing of netmask and our IP address), the function + * checks the ARP cache to see if an entry for the destination IP + * address is found. If so, an Ethernet header is prepended and the + * function returns. If no ARP cache entry is found for the + * destination IP address, the packet in the uip_buf[] is replaced by + * an ARP request packet for the IP address. The IP packet is dropped + * and it is assumed that they higher level protocols (e.g., TCP) + * eventually will retransmit the dropped packet. + * + * If the destination IP address is not on the local network, the IP + * address of the default router is used instead. + * + * When the function returns, a packet is present in the uip_buf[] + * buffer, and the length of the packet is in the global variable + * uip_len. + */ +/*-----------------------------------------------------------------------------------*/ +void +uip_arp_out(void) +{ + struct arp_entry *tabptr; + + /* Find the destination IP address in the ARP table and construct + the Ethernet header. If the destination IP addres isn't on the + local network, we use the default router's IP address instead. + + If not ARP table entry is found, we overwrite the original IP + packet with an ARP request for the IP address. */ + + /* First check if destination is a local broadcast. */ + if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) { + memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6); + } else { + /* Check if the destination address is on the local network. */ + if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) { + /* Destination address was not on the local network, so we need to + use the default router's IP address instead of the destination + address when determining the MAC address. */ + uip_ipaddr_copy(ipaddr, uip_draddr); + } else { + /* Else, we use the destination IP address. */ + uip_ipaddr_copy(ipaddr, IPBUF->destipaddr); + } + + for(i = 0; i < UIP_ARPTAB_SIZE; ++i) { + tabptr = &arp_table[i]; + if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) { + break; + } + } + + if(i == UIP_ARPTAB_SIZE) { + /* The destination address was not in our ARP table, so we + overwrite the IP packet with an ARP request. */ + + memset(BUF->ethhdr.dest.addr, 0xff, 6); + memset(BUF->dhwaddr.addr, 0x00, 6); + memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6); + + uip_ipaddr_copy(BUF->dipaddr, ipaddr); + uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr); + BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */ + BUF->hwtype = HTONS(ARP_HWTYPE_ETH); + BUF->protocol = HTONS(UIP_ETHTYPE_IP); + BUF->hwlen = 6; + BUF->protolen = 4; + BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP); + + uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN]; + + uip_len = sizeof(struct arp_hdr); + return; + } + + /* Build an ethernet header. */ + memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6); + } + memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6); + + IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP); + + uip_len += sizeof(struct uip_eth_hdr); +} +/*-----------------------------------------------------------------------------------*/ + +/** @} */ +/** @} */ diff --git a/core/net/uip_arp.h b/core/net/uip_arp.h new file mode 100644 index 000000000..b9a7bfb39 --- /dev/null +++ b/core/net/uip_arp.h @@ -0,0 +1,145 @@ +/** + * \addtogroup uip + * @{ + */ + +/** + * \addtogroup uiparp + * @{ + */ + +/** + * \file + * Macros and definitions for the ARP module. + * \author Adam Dunkels + */ + + +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: uip_arp.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + +#ifndef __UIP_ARP_H__ +#define __UIP_ARP_H__ + +#include "net/uip.h" + + +extern struct uip_eth_addr uip_ethaddr; + +/** + * The Ethernet header. + */ +struct uip_eth_hdr { + struct uip_eth_addr dest; + struct uip_eth_addr src; + u16_t type; +}; + +#define UIP_ETHTYPE_ARP 0x0806 +#define UIP_ETHTYPE_IP 0x0800 +#define UIP_ETHTYPE_IPV6 0x86dd + + +/* The uip_arp_init() function must be called before any of the other + ARP functions. */ +void uip_arp_init(void); + +/* The uip_arp_ipin() function should be called whenever an IP packet + arrives from the Ethernet. This function refreshes the ARP table or + inserts a new mapping if none exists. The function assumes that an + IP packet with an Ethernet header is present in the uip_buf buffer + and that the length of the packet is in the uip_len variable. */ +/*void uip_arp_ipin(void);*/ +#define uip_arp_ipin() + +/* The uip_arp_arpin() should be called when an ARP packet is received + by the Ethernet driver. This function also assumes that the + Ethernet frame is present in the uip_buf buffer. When the + uip_arp_arpin() function returns, the contents of the uip_buf + buffer should be sent out on the Ethernet if the uip_len variable + is > 0. */ +void uip_arp_arpin(void); + +/* The uip_arp_out() function should be called when an IP packet + should be sent out on the Ethernet. This function creates an + Ethernet header before the IP header in the uip_buf buffer. The + Ethernet header will have the correct Ethernet MAC destination + address filled in if an ARP table entry for the destination IP + address (or the IP address of the default router) is present. If no + such table entry is found, the IP packet is overwritten with an ARP + request and we rely on TCP to retransmit the packet that was + overwritten. In any case, the uip_len variable holds the length of + the Ethernet frame that should be transmitted. */ +void uip_arp_out(void); + +/* The uip_arp_timer() function should be called every ten seconds. It + is responsible for flushing old entries in the ARP table. */ +void uip_arp_timer(void); + +/** @} */ + +/** + * \addtogroup uipconffunc + * @{ + */ + + +/** + * Specifiy the Ethernet MAC address. + * + * The ARP code needs to know the MAC address of the Ethernet card in + * order to be able to respond to ARP queries and to generate working + * Ethernet headers. + * + * \note This macro only specifies the Ethernet MAC address to the ARP + * code. It cannot be used to change the MAC address of the Ethernet + * card. + * + * \param eaddr A pointer to a struct uip_eth_addr containing the + * Ethernet MAC address of the Ethernet card. + * + * \hideinitializer + */ +#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr.addr[0]; \ + uip_ethaddr.addr[1] = eaddr.addr[1];\ + uip_ethaddr.addr[2] = eaddr.addr[2];\ + uip_ethaddr.addr[3] = eaddr.addr[3];\ + uip_ethaddr.addr[4] = eaddr.addr[4];\ + uip_ethaddr.addr[5] = eaddr.addr[5];} while(0) + +/** @} */ + + +#endif /* __UIP_ARP_H__ */ +/** @} */ diff --git a/core/net/uipbuf.c b/core/net/uipbuf.c new file mode 100644 index 000000000..ff6831372 --- /dev/null +++ b/core/net/uipbuf.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uipbuf.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +#if 0 /* This whole file is #ifdef'd out - the contents are to be removed */ + +#include "net/uipbuf.h" + +#include + +/*---------------------------------------------------------------------------*/ +void +uipbuf_setup(struct uipbuf_buffer *buf, + u8_t *bufptr, u16_t bufsize) +{ + buf->buffer = buf->ptr = bufptr; + buf->bufsize = buf->left = bufsize; +} +/*---------------------------------------------------------------------------*/ +u8_t +uipbuf_bufdata(struct uipbuf_buffer *buf, u16_t len, + u8_t **dataptr, u16_t *datalen) +{ + if(*datalen < buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left -= *datalen; + *dataptr += *datalen; + *datalen = 0; + return UIPBUF_NOT_FULL; + } else if(*datalen == buf->left) { + memcpy(buf->ptr, *dataptr, *datalen); + buf->ptr += *datalen; + buf->left = 0; + *dataptr += *datalen; + *datalen = 0; + return UIPBUF_FULL; + } else { + memcpy(buf->ptr, *dataptr, buf->left); + buf->ptr += buf->left; + *datalen -= buf->left; + *dataptr += buf->left; + buf->left = 0; + return UIPBUF_FULL; + } + +} +/*---------------------------------------------------------------------------*/ +u8_t +uipbuf_bufto(register struct uipbuf_buffer *buf, u8_t endmarker, + register u8_t **dataptr, register u16_t *datalen) +{ + u8_t c; + /* + int len; + + ptr = memchr(*dataptr, endmarker, *datalen); + if(ptr != NULL) { + len = ptr - *dataptr; + } else { + len = *datalen; + } + memcpy(buf->ptr, *dataptr, len); + *dataptr += len; + *datalen -= len; + buf->ptr += len; + */ + while(buf->left > 0 && *datalen > 0) { + c = *buf->ptr = **dataptr; + ++*dataptr; + ++buf->ptr; + --*datalen; + --buf->left; + + if(c == endmarker) { + return UIPBUF_FOUND; + } + } + + if(*datalen == 0) { + return UIPBUF_NOT_FOUND; + } + + while(*datalen > 0) { + c = **dataptr; + --*datalen; + ++*dataptr; + + if(c == endmarker) { + return UIPBUF_FOUND | UIPBUF_FULL; + } + } + + return UIPBUF_FULL; +} +/*----------------------------------------------------------------------------*/ +u16_t +uipbuf_len(struct uipbuf_buffer *buf) +{ + return buf->bufsize - buf->left; +} +/*----------------------------------------------------------------------------*/ +#endif /* 0 */ diff --git a/core/net/uipbuf.h b/core/net/uipbuf.h new file mode 100644 index 000000000..16ff56bc0 --- /dev/null +++ b/core/net/uipbuf.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: uipbuf.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ +/** + * \file + * uIP data buffering helper functions. + * \author + * Adam Dunkels + * + */ + +#if 0 /* This whole file is #ifdef'd out - the contents are to be removed */ + +#ifndef __UIPBUF_H__ +#define __UIPBUF_H__ + +#include "net/uip.h" + +/** + * \defgroup uipbuf uIP data buffering helper library. + * + * The event driven API that uIP uses can be tricky to use when + * dealing with incoming TCP data. The data can be split over any + * number of incoming segments and uIP does not provide any stream + * abstraction by itself. To remedy this, the uIP data buffering + * helper library provides a set of functions that make buffering data + * easier. + * + * The data buffering library provides a structure that holds a + * pointer to a buffer and the state of the buffer, as well as a set + * of functions for manipulating the buffer state. The functions are + * intended to facilitate buffering of both data that is of a known + * size and data that is terminated by a specified byte. + * + * @{ + */ + +/** + * Return value of the buffering functions that indicates that a + * buffer was not filled by incoming data. + * + * \hideinitializer + */ +#define UIPBUF_NOT_FULL 0 +#define UIPBUF_NOT_FOUND 0 + +/** + * Return value of the buffering functions that indicates that a + * buffer was completely filled by incoming data. + * + * \hideinitializer + */ +#define UIPBUF_FULL 1 + +/** + * Return value of the buffering functions that indicates that an + * end-marker byte was found. + * + * \hideinitializer + */ +#define UIPBUF_FOUND 2 + +/** + * The structure that holds the state of a uIP buffer. + * + * This structure holds the state of a uIP buffer. The structure has + * no user-visible elements, but is used through the functions + * provided by the library. + * + * \hideinitializer + */ +struct uipbuf_buffer { + u8_t *ptr, *buffer; + unsigned short left, bufsize; +}; + +/** + * Set up a new uIP buffer structure. + * + * This function is used for setting up a uIP buffer structure with a + * specified size. The function should be called the first time a uIP + * buffer is used. The caller must provide the memory for holding the + * buffered bytes and the size of the buffer memory. + * + * \param buf A pointer to a uipbuf_buffer structure that is to be + * initialized. + * + * \param bufptr A pointer to the memory for holding the buffered + * data. + * + * \param size The size of the buffer memory. + * + */ +void uipbuf_setup(struct uipbuf_buffer *buf, + u8_t *bufptr, u16_t size); + +/** + * Buffer data until the buffer is full. + * + * This function puts data into the buffer, but no more than the + * buffer can hold. + * + * \param buf A pointer to the ::uipbuf_buffer structure that holds + * the state of the buffer. + * + * \param dataptr A pointer to the data that is to be buffered. + * + * \param datalen The length of the data that is to be buffered. + * + * \return If the buffer was not filled, the value UIPBUF_NOT_FULL + * is returned. If the buffer was filled, the number of bytes that + * could not be buffered is returned. If the buffer was exactly filled + * with the data, the value of 0 is returned. + * + */ +u8_t uipbuf_bufdata(struct uipbuf_buffer *buf, u16_t len, + u8_t **dataptr, u16_t *datalen); + +/** + * Buffer data until a specific character is found or the buffer is full. + * + * This function puts data into the buffer until a specific marker + * byte is found. The marker byte is put into the buffer at the end of + * the data. + * + * \param buf A pointer to the ::uipbuf_buffer structure that holds + * the state of the buffer. + * + * \param dataptr A pointer to the data that is to be buffered. + * + * \param datalen The length of the data that is to be buffered. + * + * \param byte The end-marker byte that indicates the end of the data + * that is to be buffered. + * + * \return This function returns the number of protruding bytes after + * the end-marker byte, if the marker was found. If the marker was not + * found and all of the data was buffered, the value of + * UIPBUF_NOT_FOUND is returned. If the marker was not found, but the + * data made the buffer fill up, the value of UIPBUF_FULL is returned. + * + */ +u8_t uipbuf_bufto(struct uipbuf_buffer *buf, u8_t endmarker, + u8_t **dataptr, u16_t *datalen); + +u16_t uipbuf_len(struct uipbuf_buffer *buf); + +/** @} */ + +#endif /* __UIPBUF_H__ */ +#endif /* 0 */ diff --git a/core/net/uiplib.c b/core/net/uiplib.c new file mode 100644 index 000000000..6ec22d90f --- /dev/null +++ b/core/net/uiplib.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of + * Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * 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 and the Contiki operating system. + * + * $Id: uiplib.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + + +#include "net/uip.h" +#include "net/uiplib.h" + + +/*-----------------------------------------------------------------------------------*/ +unsigned char +uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr) +{ + unsigned char tmp; + char c; + unsigned char i, j; + + tmp = 0; + + for(i = 0; i < 4; ++i) { + j = 0; + do { + c = *addrstr; + ++j; + if(j > 4) { + return 0; + } + if(c == '.' || c == 0) { + *ipaddr = tmp; + ++ipaddr; + tmp = 0; + } else if(c >= '0' && c <= '9') { + tmp = (tmp * 10) + (c - '0'); + } else { + return 0; + } + ++addrstr; + } while(c != '.' && c != 0); + } + return 1; +} + +/*-----------------------------------------------------------------------------------*/ diff --git a/core/net/uiplib.h b/core/net/uiplib.h new file mode 100644 index 000000000..8ebc0ee7e --- /dev/null +++ b/core/net/uiplib.h @@ -0,0 +1,71 @@ +/** + * \file + * Various uIP library functions. + * \author + * Adam Dunkels + * + */ + +/* + * 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: uiplib.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ +#ifndef __UIPLIB_H__ +#define __UIPLIB_H__ + +/** + * \addtogroup uipconvfunc + * @{ + */ + +/** + * Convert a textual representation of an IP address to a numerical representation. + * + * This function takes a textual representation of an IP address in + * the form a.b.c.d and converts it into a 4-byte array that can be + * used by other uIP functions. + * + * \param addrstr A pointer to a string containing the IP address in + * textual form. + * + * \param addr A pointer to a 4-byte array that will be filled in with + * the numerical representation of the address. + * + * \retval 0 If the IP address could not be parsed. + * \retval Non-zero If the IP address was parsed. + */ +unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr); + +/** @} */ + +#endif /* __UIPLIB_H__ */ diff --git a/core/net/uipopt.h b/core/net/uipopt.h new file mode 100644 index 000000000..5977db47f --- /dev/null +++ b/core/net/uipopt.h @@ -0,0 +1,546 @@ +/** + * \defgroup uipopt Configuration options for uIP + * @{ + * + * uIP is configured using the per-project configuration file + * "uipopt.h". This file contains all compile-time options for uIP and + * should be tweaked to match each specific project. The uIP + * distribution contains a documented example "uipopt.h" that can be + * copied and modified for each project. + * + * \note Contiki does not use the uipopt.h file to configure uIP, but + * uses a per-port uip-conf.h file that should be edited instead. + */ + +/** + * \file + * Configuration options for uIP. + * \author Adam Dunkels + * + * This file is used for tweaking various configuration options for + * uIP. You should make a copy of this file into one of your project's + * directories instead of editing this example "uipopt.h" file that + * comes with the uIP distribution. + */ + +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: uipopt.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + +#ifndef __UIPOPT_H__ +#define __UIPOPT_H__ + +#ifndef UIP_LITTLE_ENDIAN +#define UIP_LITTLE_ENDIAN 3412 +#endif /* UIP_LITTLE_ENDIAN */ +#ifndef UIP_BIG_ENDIAN +#define UIP_BIG_ENDIAN 1234 +#endif /* UIP_BIG_ENDIAN */ + +#include "contiki-conf.h" + +/*------------------------------------------------------------------------------*/ + +/** + * \defgroup uipoptstaticconf Static configuration options + * @{ + * + * These configuration options can be used for setting the IP address + * settings statically, but only if UIP_FIXEDADDR is set to 1. The + * configuration options for a specific node includes IP address, + * netmask and default router as well as the Ethernet address. The + * netmask, default router and Ethernet address are appliciable only + * if uIP should be run over Ethernet. + * + * All of these should be changed to suit your project. +*/ + +/** + * Determines if uIP should use a fixed IP address or not. + * + * If uIP should use a fixed IP address, the settings are set in the + * uipopt.h file. If not, the macros uip_sethostaddr(), + * uip_setdraddr() and uip_setnetmask() should be used instead. + * + * \hideinitializer + */ +#define UIP_FIXEDADDR 0 + +/** + * Ping IP address asignment. + * + * uIP uses a "ping" packets for setting its own IP address if this + * option is set. If so, uIP will start with an empty IP address and + * the destination IP address of the first incoming "ping" (ICMP echo) + * packet will be used for setting the hosts IP address. + * + * \note This works only if UIP_FIXEDADDR is 0. + * + * \hideinitializer + */ +#ifdef UIP_CONF_PINGADDRCONF +#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF +#else /* UIP_CONF_PINGADDRCONF */ +#define UIP_PINGADDRCONF 0 +#endif /* UIP_CONF_PINGADDRCONF */ + + +/** + * Specifies if the uIP ARP module should be compiled with a fixed + * Ethernet MAC address or not. + * + * If this configuration option is 0, the macro uip_setethaddr() can + * be used to specify the Ethernet address at run-time. + * + * \hideinitializer + */ +#define UIP_FIXEDETHADDR 0 + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \defgroup uipoptip IP configuration options + * @{ + * + */ +/** + * The IP TTL (time to live) of IP packets sent by uIP. + * + * This should normally not be changed. + */ +#define UIP_TTL 64 + +/** + * Turn on support for IP packet reassembly. + * + * uIP supports reassembly of fragmented IP packets. This features + * requires an additonal amount of RAM to hold the reassembly buffer + * and the reassembly code size is approximately 700 bytes. The + * reassembly buffer is of the same size as the uip_buf buffer + * (configured by UIP_BUFSIZE). + * + * \note IP packet reassembly is not heavily tested. + * + * \hideinitializer + */ +#define UIP_REASSEMBLY 0 + +/** + * The maximum time an IP fragment should wait in the reassembly + * buffer before it is dropped. + * + */ +#define UIP_REASS_MAXAGE 40 + +/** @} */ + +/*------------------------------------------------------------------------------*/ +/** + * \defgroup uipoptudp UDP configuration options + * @{ + * + * \note The UDP support in uIP is still not entirely complete; there + * is no support for sending or receiving broadcast or multicast + * packets, but it works well enough to support a number of vital + * applications such as DNS queries, though + */ + +/** + * Toggles wether UDP support should be compiled in or not. + * + * \hideinitializer + */ +#ifdef UIP_CONF_UDP +#define UIP_UDP UIP_CONF_UDP +#else /* UIP_CONF_UDP */ +#define UIP_UDP 1 +#endif /* UIP_CONF_UDP */ + +/** + * Toggles if UDP checksums should be used or not. + * + * \note Support for UDP checksums is currently not included in uIP, + * so this option has no function. + * + * \hideinitializer + */ +#ifdef UIP_CONF_UDP_CHECKSUMS +#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS +#else +#define UIP_UDP_CHECKSUMS 0 +#endif + +/** + * The maximum amount of concurrent UDP connections. + * + * \hideinitializer + */ +#ifdef UIP_CONF_UDP_CONNS +#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS +#else /* UIP_CONF_UDP_CONNS */ +#define UIP_UDP_CONNS 10 +#endif /* UIP_CONF_UDP_CONNS */ + +/** + * The name of the function that should be called when UDP datagrams arrive. + * + * \hideinitializer + */ + + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \defgroup uipopttcp TCP configuration options + * @{ + */ + +/** + * Determines if support for opening connections from uIP should be + * compiled in. + * + * If the applications that are running on top of uIP for this project + * do not need to open outgoing TCP connections, this configration + * option can be turned off to reduce the code size of uIP. + * + * \hideinitializer + */ +#define UIP_ACTIVE_OPEN 1 + +/** + * The maximum number of simultaneously open TCP connections. + * + * Since the TCP connections are statically allocated, turning this + * configuration knob down results in less RAM used. Each TCP + * connection requires approximatly 30 bytes of memory. + * + * \hideinitializer + */ +#ifndef UIP_CONF_MAX_CONNECTIONS +#define UIP_CONNS 10 +#else /* UIP_CONF_MAX_CONNECTIONS */ +#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS +#endif /* UIP_CONF_MAX_CONNECTIONS */ + + +/** + * The maximum number of simultaneously listening TCP ports. + * + * Each listening TCP port requires 2 bytes of memory. + * + * \hideinitializer + */ +#ifndef UIP_CONF_MAX_LISTENPORTS +#define UIP_LISTENPORTS 20 +#else /* UIP_CONF_MAX_LISTENPORTS */ +#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS +#endif /* UIP_CONF_MAX_LISTENPORTS */ + +/** + * Determines if support for TCP urgent data notification should be + * compiled in. + * + * Urgent data (out-of-band data) is a rarely used TCP feature that + * very seldom would be required. + * + * \hideinitializer + */ +#define UIP_URGDATA 0 + +/** + * The initial retransmission timeout counted in timer pulses. + * + * This should not be changed. + */ +#define UIP_RTO 3 + +/** + * The maximum number of times a segment should be retransmitted + * before the connection should be aborted. + * + * This should not be changed. + */ +#define UIP_MAXRTX 8 + +/** + * The maximum number of times a SYN segment should be retransmitted + * before a connection request should be deemed to have been + * unsuccessful. + * + * This should not need to be changed. + */ +#define UIP_MAXSYNRTX 5 + +/** + * The TCP maximum segment size. + * + * This is should not be to set to more than + * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN. + */ +#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) + +/** + * The size of the advertised receiver's window. + * + * Should be set low (i.e., to the size of the uip_buf buffer) is the + * application is slow to process incoming data, or high (32768 bytes) + * if the application processes data quickly. + * + * \hideinitializer + */ +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_RECEIVE_WINDOW UIP_TCP_MSS +#else +#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW +#endif + +/** + * How long a connection should stay in the TIME_WAIT state. + * + * This configiration option has no real implication, and it should be + * left untouched. + */ +#define UIP_TIME_WAIT_TIMEOUT 120 + + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \defgroup uipoptarp ARP configuration options + * @{ + */ + +/** + * The size of the ARP table. + * + * This option should be set to a larger value if this uIP node will + * have many connections from the local network. + * + * \hideinitializer + */ +#ifdef UIP_CONF_ARPTAB_SIZE +#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE +#else +#define UIP_ARPTAB_SIZE 8 +#endif + +/** + * The maxium age of ARP table entries measured in 10ths of seconds. + * + * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD + * default). + */ +#define UIP_ARP_MAXAGE 120 + +/** @} */ + +/*------------------------------------------------------------------------------*/ + +/** + * \defgroup uipoptgeneral General configuration options + * @{ + */ + +/** + * The size of the uIP packet buffer. + * + * The uIP packet buffer should not be smaller than 60 bytes, and does + * not need to be larger than 1500 bytes. Lower size results in lower + * TCP throughput, larger size results in higher TCP throughput. + * + * \hideinitializer + */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_BUFSIZE 400 +#else /* UIP_CONF_BUFFER_SIZE */ +#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE +#endif /* UIP_CONF_BUFFER_SIZE */ + + +/** + * Determines if statistics support should be compiled in. + * + * The statistics is useful for debugging and to show the user. + * + * \hideinitializer + */ +#ifndef UIP_CONF_STATISTICS +#define UIP_STATISTICS 0 +#else /* UIP_CONF_STATISTICS */ +#define UIP_STATISTICS UIP_CONF_STATISTICS +#endif /* UIP_CONF_STATISTICS */ + +/** + * Determines if logging of certain events should be compiled in. + * + * This is useful mostly for debugging. The function uip_log() + * must be implemented to suit the architecture of the project, if + * logging is turned on. + * + * \hideinitializer + */ +#ifndef UIP_CONF_LOGGING +#define UIP_LOGGING 0 +#else /* UIP_CONF_LOGGING */ +#define UIP_LOGGING UIP_CONF_LOGGING +#endif /* UIP_CONF_LOGGING */ + +/** + * Broadcast support. + * + * This flag configures IP broadcast support. This is useful only + * together with UDP. + * + * \hideinitializer + * + */ +#ifndef UIP_CONF_BROADCAST +#define UIP_BROADCAST 0 +#else /* UIP_CONF_BROADCAST */ +#define UIP_BROADCAST UIP_CONF_BROADCAST +#endif /* UIP_CONF_BROADCAST */ + +/** + * Print out a uIP log message. + * + * This function must be implemented by the module that uses uIP, and + * is called by uIP whenever a log message is generated. + */ +void uip_log(char *msg); + +/** + * The link level header length. + * + * This is the offset into the uip_buf where the IP header can be + * found. For Ethernet, this should be set to 14. For SLIP, this + * should be set to 0. + * + * \hideinitializer + */ +#ifdef UIP_CONF_LLH_LEN +#define UIP_LLH_LEN UIP_CONF_LLH_LEN +#else /* UIP_CONF_LLH_LEN */ +#define UIP_LLH_LEN 14 +#endif /* UIP_CONF_LLH_LEN */ + +/** @} */ +/*------------------------------------------------------------------------------*/ +/** + * \defgroup uipoptcpu CPU architecture configuration + * @{ + * + * The CPU architecture configuration is where the endianess of the + * CPU on which uIP is to be run is specified. Most CPUs today are + * little endian, and the most notable exception are the Motorolas + * which are big endian. The BYTE_ORDER macro should be changed to + * reflect the CPU architecture on which uIP is to be run. + */ + +/** + * The byte order of the CPU architecture on which uIP is to be run. + * + * This option can be either BIG_ENDIAN (Motorola byte order) or + * LITTLE_ENDIAN (Intel byte order). + * + * \hideinitializer + */ +#ifdef UIP_CONF_BYTE_ORDER +#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER +#else /* UIP_CONF_BYTE_ORDER */ +#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN +#endif /* UIP_CONF_BYTE_ORDER */ + +/** @} */ +/*------------------------------------------------------------------------------*/ + +/** + * \defgroup uipoptapp Appication specific configurations + * @{ + * + * An uIP application is implemented using a single application + * function that is called by uIP whenever a TCP/IP event occurs. The + * name of this function must be registered with uIP at compile time + * using the UIP_APPCALL definition. + * + * uIP applications can store the application state within the + * uip_conn structure by specifying the type of the application + * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t. + * + * The file containing the definitions must be included in the + * uipopt.h file. + * + * The following example illustrates how this can look. + \code + +void httpd_appcall(void); +#define UIP_APPCALL httpd_appcall + +struct httpd_state { + u8_t state; + u16_t count; + char *dataptr; + char *script; +}; +typedef struct httpd_state uip_tcp_appstate_t + \endcode + */ + +/** + * \var #define UIP_APPCALL + * + * The name of the application function that uIP should call in + * response to TCP/IP events. + * + */ + +/** + * \var typedef uip_tcp_appstate_t + * + * The type of the application state that is to be stored in the + * uip_conn structure. This usually is typedef:ed to a struct holding + * application state information. + */ + +/** + * \var typedef uip_udp_appstate_t + * + * The type of the application state that is to be stored in the + * uip_conn structure. This usually is typedef:ed to a struct holding + * application state information. + */ +/** @} */ + +#include "net/tcpip.h" + +#endif /* __UIPOPT_H__ */ +/** @} */ diff --git a/core/sys/arg.c b/core/sys/arg.c new file mode 100644 index 000000000..9df45198b --- /dev/null +++ b/core/sys/arg.c @@ -0,0 +1,133 @@ +/** + * \file + * Argument buffer for passing arguments when starting processes + * \author Adam Dunkels + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup arg Argument buffer + * @{ + * + * The argument buffer can be used when passing an argument from an + * exiting process to a process that has not been created yet. Since + * the exiting process will have exited when the new process is + * started, the argument cannot be passed in any of the processes' + * addres spaces. In such situations, the argument buffer can be used. + * + * The argument buffer is statically allocated in memory and is + * globally accessible to all processes. + * + * An argument buffer is allocated with the arg_alloc() function and + * deallocated with the arg_free() function. The arg_free() function + * is designed so that it can take any pointer, not just an argument + * buffer pointer. If the pointer to arg_free() is not an argument + * buffer, the function does nothing. + */ + +/* + * 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: arg.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ + +#include "sys/arg.h" + +/** + * \internal Structure used for holding an argument buffer. + */ +struct argbuf { + char buf[128]; + char used; +}; + +static struct argbuf bufs[1]; + +/*-----------------------------------------------------------------------------------*/ +/** + * \internal Initalizer, called by the dispatcher module. + */ +/*-----------------------------------------------------------------------------------*/ +void +arg_init(void) +{ + bufs[0].used = 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Allocates an argument buffer. + * + * \param size The requested size of the buffer, in bytes. + * + * \return Pointer to allocated buffer, or NULL if no buffer could be + * allocated. + * + * \note It currently is not possible to allocate argument buffers of + * any other size than 128 bytes. + * + */ +/*-----------------------------------------------------------------------------------*/ +char * +arg_alloc(char size) +{ + if(bufs[0].used == 0) { + bufs[0].used = 1; + return bufs[0].buf; + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Deallocates an argument buffer. + * + * This function deallocates the argument buffer pointed to by the + * parameter, but only if the buffer actually is an argument buffer + * and is allocated. It is perfectly safe to call this function with + * any pointer. + * + * \param arg A pointer. + */ +/*-----------------------------------------------------------------------------------*/ +void +arg_free(char *arg) +{ + if(arg == bufs[0].buf) { + bufs[0].used = 0; + } +} +/*-----------------------------------------------------------------------------------*/ +/** @} */ +/** @} */ diff --git a/core/sys/arg.h b/core/sys/arg.h new file mode 100644 index 000000000..4abcb820d --- /dev/null +++ b/core/sys/arg.h @@ -0,0 +1,43 @@ +/* + * 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: arg.h,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + * + */ +#ifndef __ARG_H__ +#define __ARG_H__ + +void arg_init(void); + +char *arg_alloc(char size); +void arg_free(char *arg); + +#endif /* __ARG_H__ */ diff --git a/core/sys/autostart.c b/core/sys/autostart.c new file mode 100644 index 000000000..1fe80f59b --- /dev/null +++ b/core/sys/autostart.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: autostart.c,v 1.1 2006/06/17 22:41:19 adamdunkels Exp $ + */ + +/** + * \file + * Implementation of module for automatically starting and exiting a list of processes. + * \author + * Adam Dunkels + */ + +#include "sys/autostart.h" + +/*---------------------------------------------------------------------------*/ +void +autostart_start(struct process *processes[]) +{ + int i; + + for(i = 0; processes[i] != NULL; ++i) { + process_start(processes[i], NULL); + } +} +/*---------------------------------------------------------------------------*/ +void +autostart_exit(struct process *processes[]) +{ + int i; + + for(i = 0; processes[i] != NULL; ++i) { + process_exit(processes[i]); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/sys/autostart.h b/core/sys/autostart.h new file mode 100644 index 000000000..74ae81c6f --- /dev/null +++ b/core/sys/autostart.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: autostart.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \file + * Header file for module for automatically starting and exiting a list of processes. + * \author + * Adam Dunkels + */ + +#ifndef __AUTOSTART_H__ +#define __AUTOSTART_H__ + +#include "sys/process.h" + +#if ! CC_NO_VA_ARGS +#if AUTOSTART_ENABLE +#define AUTOSTART_PROCESSES(...) \ +const struct process *autostart_processes[] = {__VA_ARGS__, NULL}; +#else /* AUTOSTART_ENABLE */ +#define AUTOSTART_PROCESSES(...) +#endif /* AUTOSTART_ENABLE */ +#else +#error "C compiler must support __VA_ARGS__ macro" +#endif + +extern const struct process *autostart_processes[]; + +void autostart_start(struct process *processes[]); +void autostart_exit(struct process *processes[]); + +#endif /* __AUTOSTART_H__ */ diff --git a/core/sys/cc.h b/core/sys/cc.h new file mode 100644 index 000000000..af23545f3 --- /dev/null +++ b/core/sys/cc.h @@ -0,0 +1,111 @@ +/** + * \file + * Default definitions of C compiler quirk work-arounds. + * \author Adam Dunkels + * + * This file is used for making use of extra functionality of some C + * compilers used for Contiki, and defining work-arounds for various + * quirks and problems with some other C compilers. + */ + +/* + * 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: cc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __CC_H__ +#define __CC_H__ + +#include "contiki-conf.h" + +/** + * Configure if the C compiler supports the "register" keyword for + * function arguments. + */ +#if CC_CONF_REGISTER_ARGS +#define CC_REGISTER_ARG register +#else /* CC_CONF_REGISTER_ARGS */ +#define CC_REGISTER_ARG +#endif /* CC_CONF_REGISTER_ARGS */ + +/** + * Configure if the C compiler supports the arguments for function + * pointers. + */ +#if CC_CONF_FUNCTION_POINTER_ARGS +#define CC_FUNCTION_POINTER_ARGS 1 +#else /* CC_CONF_FUNCTION_POINTER_ARGS */ +#define CC_FUNCTION_POINTER_ARGS 0 +#endif /* CC_CONF_FUNCTION_POINTER_ARGS */ + +/** + * Configure if the C compiler supports fastcall function + * declarations. + */ +#ifdef CC_CONF_FASTCALL +#define CC_FASTCALL CC_CONF_FASTCALL +#else /* CC_CONF_FASTCALL */ +#define CC_FASTCALL +#endif /* CC_CONF_FASTCALL */ + +/** + * Configure work-around for unsigned char bugs with sdcc. + */ +#if CC_CONF_UNSIGNED_CHAR_BUGS +#define CC_UNSIGNED_CHAR_BUGS 1 +#else /* CC_CONF_UNSIGNED_CHAR_BUGS */ +#define CC_UNSIGNED_CHAR_BUGS 0 +#endif /* CC_CONF_UNSIGNED_CHAR_BUGS */ + +/** + * Configure if C compiler supports double hash marks in C macros. + */ +#if CC_CONF_DOUBLE_HASH +#define CC_DOUBLE_HASH 1 +#else /* CC_CONF_DOUBLE_HASH */ +#define CC_DOUBLE_HASH 0 +#endif /* CC_CONF_DOUBLE_HASH */ + +#ifdef CC_CONF_INLINE +#define CC_INLINE CC_CONF_INLINE +#else /* CC_CONF_INLINE */ +#define CC_INLINE +#endif /* CC_CONF_INLINE */ + +#if CC_CONF_NO_VA_ARGS +#define CC_NO_VA_ARGS CC_CONF_VA_ARGS +#endif + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ +#endif /* __CC_H__ */ diff --git a/core/sys/clock.h b/core/sys/clock.h new file mode 100644 index 000000000..be0d99cf6 --- /dev/null +++ b/core/sys/clock.h @@ -0,0 +1,97 @@ +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup clock Clock library + * + * The clock library is the interface between Contiki and the platform + * specific clock functionality. The clock library performs a single + * function: measuring time. Additionally, the clock library provides + * a macro, CLOCK_SECOND, which corresponds to one second of system + * time. + * + * \note The clock library need in many cases not be used + * directly. Rather, the \ref timer "timer library" or the \ref etimer + * "event timers" should be used. + * + * \sa \ref timer "Timer library" + * \sa \ref etimer "Event timers" + * + * @{ + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: clock.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __CLOCK_H__ +#define __CLOCK_H__ + +#include "contiki-conf.h" + +/** + * Initialize the clock library. + * + * This function initializes the clock library and should be called + * from the main() function of the system. + * + */ +void clock_init(void); + +/** + * Get the current clock time. + * + * This function returns the current system clock time. + * + * \return The current clock time, measured in system ticks. + */ +clock_time_t clock_time(void); + +void clock_delay(unsigned int); + +/** + * A second, measured in system clock time. + * + * \hideinitializer + */ +#ifdef CLOCK_CONF_SECOND +#define CLOCK_SECOND CLOCK_CONF_SECOND +#else +#define CLOCK_SECOND (clock_time_t)32 +#endif + +#endif /* __CLOCK_H__ */ + +/** @} */ +/** @} */ diff --git a/core/sys/dsc.h b/core/sys/dsc.h new file mode 100644 index 000000000..b89b52cfb --- /dev/null +++ b/core/sys/dsc.h @@ -0,0 +1,128 @@ +/** + * \file + * Declaration of the DSC program description structure. + * \author Adam Dunkels + * + */ + +/** + * \addtogroup loader + * @{ + */ + +/** + * \page dsc The program description structure + * + * The Contiki DSC structure is used for describing programs. It + * includes a string describing the program, the name of the program + * file on disk (or a pointer to the programs initialization function + * for systems without disk support), a bitmap icon and a text version + * of the same icon. + * + * The DSC is saved into a file which can be loaded by programs such + * as the "Directory" application which reads all DSC files on disk + * and presents the icons and descriptions in a window. + * + */ + +/* + * 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: dsc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __DSC_H__ +#define __DSC_H__ + +#include "ctk/ctk.h" + +/** + * The DSC program description structure. + * + * The DSC structure is used for describing a Contiki program. It + * includes a short textual description of the program, either the + * name of the program on disk, or a pointer to the init() function, + * and an icon for the program. + */ +struct dsc { + char *description; /**< A text string containing a one-line + description of the program */ + +#if WITH_LOADER_ARCH + char *prgname; /**< The name of the program on disk. */ +#else /* WITH_LOADER_ARCH */ + struct process *process; /**< A pointer to the program's process. */ +#endif /* WITH_LOADER_ARCH */ + + struct ctk_icon *icon; /**< A pointer to the ctk_icon structure for + the DSC. */ + +#if WITH_LOADER_ARCH + void *loadaddr; /**< The loading address of the DSC. Used by + the LOADER_UNLOAD() function when + deallocating the memory allocated for the + DSC when loading it. */ +#endif /* WITH_LOADER_ARCH */ +}; + +/** + * Intantiating macro for the DSC structure. + * + * \param dscname The name of the C variable which is to contain the + * DSC. + * + * \param description A one-line text describing the program. + * + * \param prgname The name of the program on disk. + * + * \param initfunc A pointer to the initialization function of the + * program. + * + * \param icon A pointer to the CTK icon. + */ +#if WITH_LOADER_ARCH +#define DSC(dscname, description, prgname, process, icon) \ + const struct dsc dscname = {description, prgname, icon} +#else /* WITH_LOADER_ARCH */ +#define DSC(dscname, description, prgname, process, icon) \ + PROCESS_NAME(process); \ + const struct dsc dscname = {description, &process, icon} +#endif /* WITH_LOADER_ARCH */ + +#define DSC_HEADER(name) extern struct dsc name; + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +/** @} */ + +#endif /* _DSC_H__ */ diff --git a/core/sys/etimer.c b/core/sys/etimer.c new file mode 100644 index 000000000..bd8c0f9da --- /dev/null +++ b/core/sys/etimer.c @@ -0,0 +1,260 @@ +/** + * \addtogroup etimer + * @{ + */ + +/** + * \file + * Event timer library implementation. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: etimer.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include "contiki-conf.h" + +#include "sys/etimer.h" +#include "sys/process.h" + +static struct etimer *timerlist; +static clock_time_t next_expiration; + +PROCESS(etimer_process, "Event timer"); +/*---------------------------------------------------------------------------*/ +static void +update_time(void) +{ + clock_time_t nextt; + struct etimer *t; + + if (timerlist == NULL) { + next_expiration = 0; + } else { + t = timerlist; + nextt = t->timer.start + t->timer.interval; + for(t = t->next; t != NULL; t = t->next) { + if(t->timer.start + t->timer.interval < nextt) { + nextt = t->timer.start + t->timer.interval; + } + } + next_expiration = nextt; + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(etimer_process, ev, data) +{ + struct etimer *t, *u; + + PROCESS_BEGIN(); + + timerlist = NULL; + + while(1) { + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_EXITED) { + struct process *p = data; + + while(timerlist != NULL && timerlist->p == p) { + timerlist = timerlist->next; + } + + if(timerlist != NULL) { + t = timerlist; + while(t->next != NULL) { + if(t->next->p == p) { + t->next = t->next->next; + } else + t = t->next; + } + } + continue; + } else if(ev != PROCESS_EVENT_POLL) { + continue; + } + + again: + + u = NULL; + + for(t = timerlist; t != NULL; t = t->next) { + if(timer_expired(&t->timer)) { + if(process_post(t->p, PROCESS_EVENT_TIMER, t) == PROCESS_ERR_OK) { + + /* Reset the process ID of the event timer, to signal that the + etimer has expired. This is later checked in the + etimer_expired() function. */ + t->p = PROCESS_NONE; + if(u != NULL) { + u->next = t->next; + } else { + timerlist = t->next; + } + t->next = NULL; + update_time(); + goto again; + } else { + etimer_request_poll(); + } + } + u = t; + } + + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +etimer_request_poll(void) +{ + process_poll(&etimer_process); +} +/*---------------------------------------------------------------------------*/ +static void +add_timer(struct etimer *timer) +{ + struct etimer *t; + + if(timer->p != PROCESS_NONE) { + /* Timer not on list. */ + + for(t = timerlist; t != NULL; t = t->next) { + if(t == timer) { + /* Timer already on list, bail out. */ + update_time(); + return; + } + } + } + + timer->p = PROCESS_CURRENT(); + timer->next = timerlist; + timerlist = timer; + + update_time(); +} +/*---------------------------------------------------------------------------*/ +void +etimer_set(struct etimer *et, clock_time_t interval) +{ + timer_set(&et->timer, interval); + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void +etimer_reset(struct etimer *et) +{ + timer_reset(&et->timer); + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void +etimer_restart(struct etimer *et) +{ + timer_restart(&et->timer); + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void +etimer_adjust(struct etimer *et, int timediff) +{ + et->timer.start += timediff; + update_time(); +} +/*---------------------------------------------------------------------------*/ +int +etimer_expired(struct etimer *et) +{ + return et->p == PROCESS_NONE; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +etimer_expiration_time(struct etimer *et) +{ + return et->timer.start + et->timer.interval; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +etimer_start_time(struct etimer *et) +{ + return et->timer.start; +} +/*---------------------------------------------------------------------------*/ +int +etimer_pending(void) +{ + return timerlist != NULL; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +etimer_next_expiration_time(void) +{ + return etimer_pending() ? next_expiration : 0; +} +/*---------------------------------------------------------------------------*/ +void +etimer_stop(struct etimer *et) +{ + struct etimer *t; + + /* First check if et is the first event timer on the list. */ + if(et == timerlist) { + timerlist = timerlist->next; + update_time(); + } else { + /* Else walk through the list and try to find the item before the + et timer. */ + for(t = timerlist; t != NULL && t->next != et; t = t->next); + + if(t != NULL) { + /* We've found the item before the event timer that we are about + to remove. We point the items next pointer to the event after + the removed item. */ + t->next = et->next; + + update_time(); + } + } + + /* Remove the next pointer from the item to be removed. */ + et->next = NULL; + /* Set the timer as expired */ + et->p = PROCESS_NONE; +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/sys/etimer.h b/core/sys/etimer.h new file mode 100644 index 000000000..40a98f52e --- /dev/null +++ b/core/sys/etimer.h @@ -0,0 +1,242 @@ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup etimer Event timers + * + * Event timers provides a way to generate timed events. An event + * timer will post an event to the process that set the timer when the + * event timer expires. + * + * An event timer is declared as a \c struct \c etimer and all access + * to the event timer is made by a pointer to the declared event + * timer. + * + * \sa \ref timer "Simple timer library" + * \sa \ref clock "Clock library" (used by the timer library) + * + * @{ + */ + + +/** + * \file + * Event timer header file. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: etimer.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __ETIMER_H__ +#define __ETIMER_H__ + +#include "sys/timer.h" +#include "sys/process.h" + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with etimer_set() before it can be used. + * + * \hideinitializer + */ +struct etimer { + struct timer timer; + struct etimer *next; + struct process *p; +}; + +/** + * \name Functions called from application programs + * @{ + */ + +/** + * \brief Set an event timer. + * \param et A pointer to the event timer + * \param interval The interval before the timer expires. + * + * This function is used to set an event timer for a time + * sometime in the future. When the event timer expires, + * the event PROCESS_EVENT_TIMER will be posted to the + * process that called the etimer_set() function. + * + */ +void etimer_set(struct etimer *et, clock_time_t interval); + +/** + * \brief Reset an event timer with the same interval as was + * previously set. + * \param et A pointer to the event timer. + * + * This function resets the event timer with the same + * interval that was given to the event timer with the + * etimer_set() function. The start point of the interval + * is the exact time that the event timer last + * expired. Therefore, this function will cause the timer + * to be stable over time, unlike the etimer_restart() + * function. + * + * \sa etimer_restart() + */ +void etimer_reset(struct etimer *et); + +/** + * \brief Restart an event timer from the current point in time + * \param et A pointer to the event timer. + * + * This function restarts the event timer with the same + * interval that was given to the etimer_set() + * function. The event timer will start at the current + * time. + * + * \note A periodic timer will drift if this function is + * used to reset it. For periodic timers, use the + * etimer_reset() function instead. + * + * \sa etimer_reset() + */ +void etimer_restart(struct etimer *et); + +/** + * \brief Adjust the expiration time for an event timer + * \param et A pointer to the event timer. + * \param td The time difference to adjust the expiration time with. + * + * This function is used to adjust the time the event + * timer will expire. It can be used to synchronize + * periodic timers without the need to restart the timer + * or change the timer interval. + * + * \note This function should only be used for small + * adjustments. For large adjustments use etimer_set() + * instead. + * + * \note A periodic timer will drift unless the + * etimer_reset() function is used. + * + * \sa etimer_set() + * \sa etimer_reset() + */ +void etimer_adjust(struct etimer *et, int td); + +/** + * \brief Get the expiration time for the event timer. + * \param et A pointer to the event timer + * \return The expiration time for the event timer. + * + * This function returns the expiration time for an event timer. + */ +clock_time_t etimer_expiration_time(struct etimer *et); + +/** + * \brief Get the start time for the event timer. + * \param et A pointer to the event timer + * \return The start time for the event timer. + * + * This function returns the start time (when the timer + * was last set) for an event timer. + */ +clock_time_t etimer_start_time(struct etimer *et); + +/** + * \brief Check if an event timer has expired. + * \param et A pointer to the event timer + * \return Non-zero if the timer has expired, zero otherwise. + * + * This function tests if an event timer has expired and + * returns true or false depending on its status. + */ +int etimer_expired(struct etimer *et); + +/** + * \brief Stop a pending event timer. + * \param et A pointer to the pending event timer. + * + * This function stops an event timer that has previously + * been set with etimer_set() or etimer_reset(). After + * this function has been called, the event timer will not + * emit any event when it expires. + * + */ +void etimer_stop(struct etimer *et); + +/** @} */ + +/** + * \name Functions called from timer interrupts, by the system + * @{ + */ + +/** + * \brief Make the event timer aware that the clock has changed + * + * This function is used to inform the event timer module + * that the system clock has been updated. Typically, this + * function would be called from the timer interrupt + * handler when the clock has ticked. + */ +void etimer_request_poll(void); + +/** + * \brief Check if there are any non-expired event timers. + * \return True if there are active event timers, false if there are + * no active timers. + * + * This function checks if there are any active event + * timers that have not expired. + */ +int etimer_pending(void); + +/** + * \brief Get next event timer expiration time. + * \return Next expiration time of all pending event timers. + * If there are no pending event timers this function + * returns 0. + * + * This functions returns next expiration time of all + * pending event timers. + */ +clock_time_t etimer_next_expiration_time(void); + + +/** @} */ + +PROCESS_NAME(etimer_process); +#endif /* __ETIMER_H__ */ +/** @} */ +/** @} */ diff --git a/core/sys/lc-addrlabels.h b/core/sys/lc-addrlabels.h new file mode 100644 index 000000000..10578bedb --- /dev/null +++ b/core/sys/lc-addrlabels.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: lc-addrlabels.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on the "Labels as + * values" feature of gcc + * \author + * Adam Dunkels + * + * This implementation of local continuations is based on a special + * feature of the GCC C compiler called "labels as values". This + * feature allows assigning pointers with the address of the code + * corresponding to a particular C label. + * + * For more information, see the GCC documentation: + * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html + * + * Thanks to dividuum for finding the nice local scope label + * implementation. + */ + +#ifndef __LC_ADDRLABELS_H__ +#define __LC_ADDRLABELS_H__ + +/** \hideinitializer */ +typedef void * lc_t; + +#define LC_INIT(s) s = NULL + + +#define LC_RESUME(s) \ + do { \ + if(s != NULL) { \ + goto *s; \ + } \ + } while(0) + +#define LC_SET(s) \ + do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0) + +#define LC_END(s) + +#endif /* __LC_ADDRLABELS_H__ */ +/** @} */ diff --git a/core/sys/lc-switch.h b/core/sys/lc-switch.h new file mode 100644 index 000000000..64050f7e6 --- /dev/null +++ b/core/sys/lc-switch.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: lc-switch.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup lc + * @{ + */ + +/** + * \file + * Implementation of local continuations based on switch() statment + * \author Adam Dunkels + * + * This implementation of local continuations uses the C switch() + * statement to resume execution of a function somewhere inside the + * function's body. The implementation is based on the fact that + * switch() statements are able to jump directly into the bodies of + * control structures such as if() or while() statmenets. + * + * This implementation borrows heavily from Simon Tatham's coroutines + * implementation in C: + * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html + */ + +#ifndef __LC_SWITCH_H__ +#define __LC_SWTICH_H__ + +/* WARNING! lc implementation using switch() does not work if an + LC_SET() is done within another switch() statement! */ + +/** \hideinitializer */ +typedef unsigned short lc_t; + +#define LC_INIT(s) s = 0; + +#define LC_RESUME(s) switch(s) { case 0: + +#define LC_SET(s) s = __LINE__; case __LINE__: + +#define LC_END(s) } + +#endif /* __LC_SWITCH_H__ */ + +/** @} */ diff --git a/core/sys/lc.h b/core/sys/lc.h new file mode 100644 index 000000000..33c472c9a --- /dev/null +++ b/core/sys/lc.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: lc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \defgroup lc Local continuations + * @{ + * + * Local continuations form the basis for implementing protothreads. A + * local continuation can be set in a specific function to + * capture the state of the function. After a local continuation has + * been set can be resumed in order to restore the state of the + * function at the point where the local continuation was set. + * + * + */ + +/** + * \file lc.h + * Local continuations + * \author + * Adam Dunkels + * + */ + +#ifdef DOXYGEN +/** + * Initialize a local continuation. + * + * This operation initializes the local continuation, thereby + * unsetting any previously set continuation state. + * + * \hideinitializer + */ +#define LC_INIT(lc) + +/** + * Set a local continuation. + * + * The set operation saves the state of the function at the point + * where the operation is executed. As far as the set operation is + * concerned, the state of the function does not include the + * call-stack or local (automatic) variables, but only the program + * counter and such CPU registers that needs to be saved. + * + * \hideinitializer + */ +#define LC_SET(lc) + +/** + * Resume a local continuation. + * + * The resume operation resumes a previously set local continuation, thus + * restoring the state in which the function was when the local + * continuation was set. If the local continuation has not been + * previously set, the resume operation does nothing. + * + * \hideinitializer + */ +#define LC_RESUME(lc) + +/** + * Mark the end of local continuation usage. + * + * The end operation signifies that local continuations should not be + * used any more in the function. This operation is not needed for + * most implementations of local continuation, but is required by a + * few implementations. + * + * \hideinitializer + */ +#define LC_END(lc) + +/** + * \var typedef lc_t; + * + * The local continuation type. + * + * \hideinitializer + */ +#endif /* DOXYGEN */ + +#ifndef __LC_H__ +#define __LC_H__ + +#ifdef LC_CONF_INCLUDE +#include LC_CONF_INCLUDE +#else /* LC_CONF_INCLUDE */ +#include "sys/lc-switch.h" +#endif /* LC_CONF_INCLUDE */ + +#endif /* __LC_H__ */ + +/** @} */ +/** @} */ diff --git a/core/sys/loader.h b/core/sys/loader.h new file mode 100644 index 000000000..cff06e849 --- /dev/null +++ b/core/sys/loader.h @@ -0,0 +1,132 @@ +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup loader The Contiki program loader + * + * The Contiki program loader is an abstract interface for loading and + * starting programs. + * + * @{ + */ + +/** + * \file + * Default definitions and error values for the Contiki program loader. + * \author Adam Dunkels + * + */ + +/* + * 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: loader.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __LOADER_H__ +#define __LOADER_H__ + +/* Errors that the LOADER_LOAD() function may return: */ + +#define LOADER_OK 0 /**< No error. */ +#define LOADER_ERR_READ 1 /**< Read error. */ +#define LOADER_ERR_HDR 2 /**< Header error. */ +#define LOADER_ERR_OS 3 /**< Wrong OS. */ +#define LOADER_ERR_FMT 4 /**< Data format error. */ +#define LOADER_ERR_MEM 5 /**< Not enough memory. */ +#define LOADER_ERR_OPEN 6 /**< Could not open file. */ +#define LOADER_ERR_ARCH 7 /**< Wrong architecture. */ +#define LOADER_ERR_VERSION 8 /**< Wrong OS version. */ +#define LOADER_ERR_NOLOADER 9 /**< Program loading not supported. */ + +#ifdef LOADER_CONF_ARCH +#include LOADER_CONF_ARCH +#endif /* LOADER_CONF_ARCH */ + +/** + * Load and execute a program. + * + * This macro is used for loading and executing a program, and + * requires support from the architecture dependant code. The actual + * program loading is made by architecture specific functions. + * + * \note A program loaded with LOADER_LOAD() must call the + * LOADER_UNLOAD() function to unload itself. + * + * \param name The name of the program to be loaded. + * + * \param arg A pointer argument that is passed to the program. + * + * \return A loader error, or LOADER_OK if loading was successful. + */ +#ifndef LOADER_LOAD +#define LOADER_LOAD(name, arg) LOADER_ERR_NOLOADER +#endif /* LOADER_LOAD */ + +/** + * Unload a program from memory. + * + * This macro is used for unloading a program and deallocating any + * memory that was allocated during the loading of the program. This + * function must be called by the program itself. + * + */ +#ifndef LOADER_UNLOAD +#define LOADER_UNLOAD() +#endif /* LOADER_UNLOAD */ + +/** + * Load a DSC (program description). + * + * Loads a DSC (program description) into memory and returns a pointer + * to the dsc. + * + * \return A pointer to the DSC or NULL if it could not be loaded. + */ +#ifndef LOADER_LOAD_DSC +#define LOADER_LOAD_DSC(name) NULL +#endif /* LOADER_LOAD_DSC */ + +/** + * Unload a DSC (program description). + * + * Unload a DSC from memory and deallocate any memory that was + * allocated when it was loaded. + */ +#ifndef LOADER_UNLOAD_DSC +#define LOADER_UNLOAD_DSC(dsc) +#endif /* LOADER_UNLOAD */ + +#endif /* __LOADER_H__ */ + +/** @} */ +/** @} */ diff --git a/core/sys/log.h b/core/sys/log.h new file mode 100644 index 000000000..2460210fa --- /dev/null +++ b/core/sys/log.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: log.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __LOG_H__ +#define __LOG_H__ + +#include "contiki-conf.h" + +#if LOG_CONF_ENABLED +void log_message(const char *part1, const char *part2); +#else /* LOG_CONF_ENABLED */ +#define log_message(p1, p2) +#endif /* LOG_CONF_ENABLED */ + +#endif /* __LOG_H__ */ diff --git a/core/sys/mt.c b/core/sys/mt.c new file mode 100644 index 000000000..0efea5793 --- /dev/null +++ b/core/sys/mt.c @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: mt.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \file + * Implementation of the archtecture agnostic parts of the preemptive + * multithreading library for Contiki. + * + * \author + * Adam Dunkels + * + */ + +#include "contiki.h" +#include "sys/mt.h" +#include "sys/cc.h" + +#define MT_STATE_READY 1 +#define MT_STATE_RUNNING 2 +#define MT_STATE_WAITING 3 +#define MT_STATE_PEEK 4 +#define MT_STATE_EXITED 5 + +static struct mt_thread *current; + +/*--------------------------------------------------------------------------*/ +void +mt_init(void) +{ + mtarch_init(); +} +/*--------------------------------------------------------------------------*/ +void +mt_remove(void) +{ + mtarch_remove(); +} +/*--------------------------------------------------------------------------*/ +void +mt_start(struct mt_thread *thread, void (* function)(void *), void *data) +{ + /* Call the architecture dependant function to set up the processor + stack with the correct parameters. */ + mtarch_start(&thread->thread, function, data); + + thread->state = MT_STATE_READY; +} +/*--------------------------------------------------------------------------*/ +void +mt_exec(struct mt_thread *thread) +{ + if(thread->state == MT_STATE_READY || + thread->state == MT_STATE_PEEK) { + thread->state = MT_STATE_RUNNING; + current = thread; + /* Switch context to the thread. The function call will not return + until the the thread has yielded, or is preempted. */ + /*printf("swtis\n");*/ + mtarch_exec(&thread->thread); + } +} +/*--------------------------------------------------------------------------*/ +void +mt_exit(void) +{ + current->state = MT_STATE_EXITED; + current = NULL; + mtarch_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mt_exec_event(struct mt_thread *thread, process_event_t ev, + process_data_t data) +{ + if(thread->state == MT_STATE_WAITING || + thread->state == MT_STATE_PEEK) { + *(thread->evptr) = ev; + *(thread->dataptr) = data; + thread->state = MT_STATE_RUNNING; + current = thread; + /* Switch context to the thread. The function call will not return + until the the thread has yielded, or is preempted. */ + mtarch_exec(&thread->thread); + } +} +/*--------------------------------------------------------------------------*/ +void +mt_yield(void) +{ + mtarch_pstop(); + current->state = MT_STATE_READY; + current = NULL; + /* This function is called from the running thread, and we call the + switch function in order to switch the thread to the main Contiki + program instead. For us, the switch function will not return + until the next time we are scheduled to run. */ + mtarch_yield(); + +} +/*--------------------------------------------------------------------------*/ +void +mt_post(struct process *p, process_event_t ev, + process_data_t data) +{ + /* Turn off preemption to ensure mutual exclusion of kernel. */ + mtarch_pstop(); + + process_post(p, ev, data); + + /* Turn preemption on again. */ + mtarch_pstart(); +} +/*--------------------------------------------------------------------------*/ +void +mt_wait(process_event_t *ev, process_data_t *data) +{ + mtarch_pstop(); + current->evptr = ev; + current->dataptr = data; + current->state = MT_STATE_WAITING; + current = NULL; + mtarch_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mt_peek(process_event_t *ev, process_data_t *data) +{ + mtarch_pstop(); + *ev = PROCESS_EVENT_NONE; + current->evptr = ev; + current->dataptr = data; + current->state = MT_STATE_PEEK; + current = NULL; + mtarch_yield(); +} +/*--------------------------------------------------------------------------*/ +void +mtp_start(struct mt_process *t, + void (* function)(void *), void *data) +{ + mt_start(&t->t, function, data); + process_start(t->p, function); +} +/*--------------------------------------------------------------------------*/ +void +mtp_exit(void) +{ + mtarch_pstop(); + mt_exit(); + mt_remove(); +} +/*--------------------------------------------------------------------------*/ +/*void +mtp_eventhandler(ek_event_t ev, ek_data_t data) +{ + struct mtp_thread *thread = (struct mtp_thread *)EK_PROC_STATE(EK_CURRENT()); + + if(ev == EK_EVENT_REQUEST_EXIT) { + ek_exit(); + LOADER_UNLOAD(); + + } else if(ev == EK_EVENT_INIT) { + + ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); + + } else if(ev == EK_EVENT_CONTINUE) { + + if(thread->t.state == MT_STATE_READY || + thread->t.state == MT_STATE_PEEK) { + mt_exec(&thread->t); + if(thread->t.state == MT_STATE_EXITED) { + ek_exit(); + LOADER_UNLOAD(); + } else { + ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); + } + } + } else { + mt_exec_event(&thread->t, ev, data); + if(thread->t.state == MT_STATE_EXITED) { + ek_exit(); + LOADER_UNLOAD(); + } else if(thread->t.state == MT_STATE_READY || + thread->t.state == MT_STATE_PEEK) { + ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_CONTINUE, NULL); + } + } +}*/ +/*--------------------------------------------------------------------------*/ diff --git a/core/sys/mt.h b/core/sys/mt.h new file mode 100644 index 000000000..242f76d75 --- /dev/null +++ b/core/sys/mt.h @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: mt.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup mt Multi-threading library + * + * The event driven Contiki kernel does not provide multi-threading + * by itself - instead, preemptive multi-threading is implemented + * as a library that optionally can be linked with applications. This + * library constists of two parts: a platform independent part, which is + * the same for all platforms on which Contiki runs, and a platform + * specific part, which must be implemented specifically for the + * platform that the multi-threading library should run. + * + * @{ + */ + +/** + * \defgroup mtarch Architecture support for multi-threading + * @{ + * + * The Contiki multi-threading library requires some architecture + * specific support for seting up and switching stacks. This support + * requires three stack manipulation functions to be implemented: + * mtarch_start(), which sets up the stack frame for a new thread, + * mtarch_exec(), which switches in the stack of a thread, and + * mtarch_yield(), which restores the kernel stack from a thread's + * stack. Additionally, two functions for controlling the preemption + * (if any) must be implemented: mtarch_preemption_start() and + * mtarch_preemption_stop(). If no preemption is used, these functions + * can be implemented as empty functions. Finally, the function + * mtarch_init() is called by mt_init(), and can be used for + * initalization of timer interrupts, or any other mechanisms required + * for correct operation of the architecture specific support funcions. + * + */ + +/** + * \file + * Header file for the preemptive multitasking library for Contiki. + * \author + * Adam Dunkels + * + */ +#ifndef __MT_H__ +#define __MT_H__ + +#include "contiki.h" + + +/** + * An opaque structure that is used for holding the state of a thread. + * + * The structure should be defined in the "mtarch.h" file. This + * structure typically holds the entire stack for the thread. + */ +struct mtarch_thread; + +/** + * Initialize the architecture specific support functions for the + * multi-thread library. + * + * This function is implemented by the architecture specific functions + * for the multi-thread library and is called by the mt_init() + * function as part of the initialization of the library. The + * mtarch_init() function can be used for, e.g., starting preemtion + * timers or other architecture specific mechanisms required for the + * operation of the library. + */ +void mtarch_init(void); + +/** + * Uninstall library and clean up. + * + */ +void mtarch_remove(void); + +/** + * Setup the stack frame for a thread that is being started. + * + * This function is called by the mt_start() function in order to set + * up the architecture specific stack of the thread to be started. + * + * \param thread A pointer to a struct mtarch_thread for the thread to + * be started. + * + * \param function A pointer to the function that the thread will + * start executing the first time it is scheduled to run. + * + * \param data A pointer to the argument that the function should be + * passed. + */ +void mtarch_start(struct mtarch_thread *thread, + void (* function)(void *data), + void *data); + +/** + * Yield the processor. + * + * This function is called by the mt_yield() function, which is called + * from the running thread in order to give up the processor. + * + */ +void mtarch_yield(void); + +/** + * Start executing a thread. + * + * This function is called from mt_exec() and the purpose of the + * function is to start execution of the thread. The function should + * switch in the stack of the thread, and does not return until the + * thread has explicitly yielded (using mt_yield()) or until it is + * preempted. + * + */ +void mtarch_exec(struct mtarch_thread *thread); + + +void mtarch_pstart(void); +void mtarch_pstop(void); + +/** @} */ + + +#include "mtarch.h" + +struct mt_thread { + int state; + process_event_t *evptr; + process_data_t *dataptr; + struct mtarch_thread thread; +}; + +/** + * No error. + * + * \hideinitializer + */ +#define MT_OK 1 + +/** + * Initializes the multithreading library. + * + */ +void mt_init(void); + +/** + * Uninstalls library and cleans up. + * + */ +void mt_remove(void); + + +/** + * Starts a multithreading thread. + * + * \param thread Pointer to an mt_thread struct that must have been + * previously allocated by the caller. + * + * \param function A pointer to the entry function of the thread that is + * to be set up. + * + * \param data A pointer that will be passed to the entry function. + * + */ +void mt_start(struct mt_thread *thread, void (* function)(void *), void *data); + +/** + * Execute parts of a thread. + * + * This function is called by a Contiki process and runs a + * thread. The function does not return until the thread has yielded, + * or is preempted. + * + * \note The thread must first be initialized with the mt_init() function. + * + * \param thread A pointer to a struct mt_thread block that must be + * allocated by the caller. + * + */ +void mt_exec(struct mt_thread *thread); + +/** + * Post an event to a thread. + * + * This function posts an event to a thread. The thread will be + * scheduled if the thread currently is waiting for the posted event + * number. If the thread is not waiting for the event, this function + * does nothing. + * + * \note The thread must first be initialized with the mt_init() function. + * + * \param thread A pointer to a struct mt_thread block that must be + * allocated by the caller. + * + * \param s The event that is posted to the thread. + * + * \param data An opaque pointer to a user specified structure + * containing additonal information, or NULL if no additional + * information is needed. + */ +void mt_exec_event(struct mt_thread *thread, process_event_t s, + process_data_t data); + +/** + * Voluntarily give up the processor. + * + * This function is called by a running thread in order to give up + * control of the CPU. + * + */ +void mt_yield(void); + +/** + * Post an event to another process. + * + * This function is called by a running thread and will emit a signal + * to another Contiki process. This will cause the currently executing + * thread to yield. + * + * \param p The process receiving the signal, or PROCESS_BROADCAST + * for a broadcast event. + * + * \param ev The event to be posted. + * + * \param data A pointer to a message that is to be delivered together + * with the signal. + * + */ +void mt_post(struct process *p, process_event_t ev, process_data_t data); + +/** + * Block and wait for an event to occur. + * + * This function can be called by a running thread in order to block + * and wait for an event. The function returns when an event has + * occured. The event number and the associated data are placed in the + * variables pointed to by the function arguments. + * + * \param ev A pointer to a process_event_t variable. The variable + * will be filled with the number event that woke the thread. + * + * \param data A pointer to a process_data_t variable. The variable + * will be filled with the data associated with the event that woke + * the thread. + * + */ +void mt_wait(process_event_t *ev, process_data_t *data); + +/** + * Exit a thread. + * + * This function is called from within an executing thread in order to + * exit the thread. The function never returns. + * + */ +void mt_exit(void); + +/** + * \defgroup mtp Multi-threading library convenience functions + * @{ + * + * The Contiki multi-threading library has an interface that might be + * hard to use. Therefore, the mtp module provides a simpler + * interface. + * + * Example: +\code +static void +example_thread_code(void *data) +{ + while(1) { + printf("Test\n"); + mt_yield(); + } +} +MTP(example_thread, "Example thread", p1, t1, t1_idle); + +int +main(int argc, char *argv[]) +{ + mtp_start(&example_thread, example_thread_code, NULL); +} +\endcode +* +*/ + + +/** + * Declare a multithreaded process. + * + * This macro is used to declare a multithreaded process. + * + * \hideinitializer + */ +#define MT_PROCESS(name, strname) \ +extern struct mt_process name##mt_process; \ +struct process name = { NULL, strname, mt_process_thread }; \ +static struct mt_process thread = {&name} + +struct mt_process { + struct process *p; + struct mt_thread t; +}; + +/** + * Start a thread. + * + * This function starts the process in which the thread is to run, and + * also sets up the thread to run within the process. The function + * should be passed variable names declared with the MTP() macro. + * + * \param t A pointer to a thread structure previously declared with MTP(). + * + * \param function A pointer to the function that the thread should + * start executing. + * + * \param data A pointer that the function should be passed when first + * invocated. + */ +void mtp_start(struct mt_process *p, + void (* function)(void *), void *data); + +void mtp_exit(void); +void mtp_eventhandler(process_event_t ev, process_data_t data); + +/** @} */ +/** @} */ +/** @} */ +#endif /* __MT_H__ */ diff --git a/core/sys/process.c b/core/sys/process.c new file mode 100644 index 000000000..7e7ce9648 --- /dev/null +++ b/core/sys/process.c @@ -0,0 +1,402 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: process.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup process + * @{ + */ + +/** + * \file + * Implementation of the Contiki process kernel. + * \author + * Adam Dunkels + * + */ + +#include + +#include "sys/process.h" +#include "sys/arg.h" + +/* + * Pointer to the currently running process structure. + */ +struct process *process_list = NULL; +struct process *process_current = NULL; + +static process_event_t lastevent; + +/* + * Structure used for keeping the queue of active events. + */ +struct event_data { + process_event_t ev; + process_data_t data; + struct process *p; +}; + +#ifdef PROCESS_CONF_FASTPOLL +#define NPOLLS PROCESS_CONF_FASTPOLL +#include +static volatile unsigned npolls; +static struct process *needpoll[NPOLLS]; +#endif +static process_num_events_t nevents, fevent; +static struct event_data events[PROCESS_CONF_NUMEVENTS]; + +static volatile unsigned char poll_requested; + +#define PROCESS_STATE_NONE 0 +#define PROCESS_STATE_INIT 1 +#define PROCESS_STATE_RUNNING 2 +#define PROCESS_STATE_NEEDS_POLL 3 + +static void call_process(struct process *p, process_event_t ev, process_data_t data); + + +/*---------------------------------------------------------------------------*/ +process_event_t +process_alloc_event(void) +{ + return lastevent++; +} +/*---------------------------------------------------------------------------*/ +void +process_start(struct process *p, char *arg) +{ + struct process *q; + + /* First make sure that we don't try to start a process that is + already running. */ + for(q = process_list; q != p && q != NULL; q = q->next); + + /* If we found the process on the process list, we bail out. */ + if(q == p) { + return; + } + /* Put on the procs list.*/ + p->next = process_list; + process_list = p; + + p->state = PROCESS_STATE_INIT; + + PT_INIT(&p->pt); + + /* Post an asynchronous event to the process. */ + process_post(p, PROCESS_EVENT_INIT, (process_data_t)arg); +} +/*---------------------------------------------------------------------------*/ +static void +exit_process(struct process *p, struct process *fromprocess) +{ + register struct process *q; + struct process *old_current = process_current; + + if(p->state != PROCESS_STATE_NONE) { + /* Process was running */ + p->state = PROCESS_STATE_NONE; + + /* + * Post a synchronous event to all processes to inform them that + * this process is about to exit. This will allow services to + * deallocate state associated with this process. + */ + for(q = process_list; q != NULL; q = q->next) { + if(p != q) { + call_process(q, PROCESS_EVENT_EXITED, (process_data_t)p); + } + } + + if(p->thread != NULL && p != fromprocess) { + /* Post the exit event to the process that is about to exit. */ + process_current = p; + p->thread(&p->pt, PROCESS_EVENT_EXIT, NULL); + } + } + + if(p == process_list) { + process_list = process_list->next; + } else { + for(q = process_list; q != NULL; q = q->next) { + if(q->next == p) { + q->next = p->next; + break; + } + } + } + + { + int n; + int i = fevent; + for(n = nevents; n > 0; n--) { + if(events[i].p == p) { + events[i].p = PROCESS_ZOMBIE; +#if 0 + printf("soft panic: exiting process has remaining event 0x%x\n", + events[i].ev); +#endif + } + i = (i + 1) % PROCESS_CONF_NUMEVENTS; + } +#ifdef NPOLLS + for(i = 0; i < NPOLLS && i < npolls; i++) { + if(needpoll[i] == p) { + needpoll[i] = PROCESS_ZOMBIE; + } + } +#endif + } + process_current = old_current; +} +/*---------------------------------------------------------------------------*/ +static void +call_process(struct process *p, process_event_t ev, process_data_t data) +{ + int ret; + + if((p->state == PROCESS_STATE_RUNNING || + p->state == PROCESS_STATE_NEEDS_POLL) && + p->thread != NULL) { + process_current = p; + + ret = p->thread(&p->pt, ev, data); + if(ret == PT_EXITED || + ret == PT_ENDED || + ev == PROCESS_EVENT_EXIT) { + exit_process(p, p); + } + } +} +/*---------------------------------------------------------------------------*/ +void +process_exit(struct process *p) +{ + exit_process(p, PROCESS_CURRENT()); +} +/*---------------------------------------------------------------------------*/ +void +process_init(void) +{ + lastevent = PROCESS_EVENT_MAX; + + nevents = fevent = 0; + + process_current = process_list = NULL; +} +/*---------------------------------------------------------------------------*/ +/* + * Call each process' poll handler. + */ +/*---------------------------------------------------------------------------*/ +static void +do_poll(void) +{ + struct process *p; + + poll_requested = 0; + +#ifdef NPOLLS + unsigned i; + int s; + /* Fastpoll */ + //printf("F %d\n", npolls); + for(i = 0; i < npolls; i++) { + do_more: + if(i == NPOLLS) { + goto slowpoll; + } + if(needpoll[i] != PROCESS_ZOMBIE + && needpoll[i]->state == PROCESS_STATE_NEEDS_POLL) { + needpoll[i]->state = PROCESS_STATE_RUNNING; + call_process(needpoll[i], PROCESS_EVENT_POLL, NULL); + } + } + s = splhigh(); + if(i == npolls) { + npolls = 0; + splx(s); + return; + } + splx(s); + goto do_more; + + /* Call poll handlers. */ + slowpoll: + //printf("S %d\n", npolls); + npolls = 0; +#endif + /* Call poll handlers. */ + for(p = process_list; p != NULL; p = p->next) { + + if(p->state == PROCESS_STATE_NEEDS_POLL) { + p->state = PROCESS_STATE_RUNNING; + call_process(p, PROCESS_EVENT_POLL, NULL); + } + +#if 0 + /* If a poll has been requested for one of the processes, we start + from the beginning again. */ + if(poll_requested) { + poll_requested = 0; + p = process_list; + } +#endif + } +} +/*---------------------------------------------------------------------------*/ +/* + * Process the next event in the event queue and deliver it to + * listening processes. + */ +/*---------------------------------------------------------------------------*/ +static void +do_event(void) +{ + static process_event_t ev; + static process_data_t data; + static struct process *receiver; + static struct process *p; + + /* + * If there are any events in the queue, take the first one and walk + * through the list of processes to see if the event should be + * delivered to any of them. If so, we call the event handler + * function for the process. We only process one event at a time and + * call the poll handlers inbetween. + */ + + if(nevents > 0) { + + /* There are events that we should deliver. */ + ev = events[fevent].ev; + + data = events[fevent].data; + receiver = events[fevent].p; + + /* Since we have seen the new event, we move pointer upwards + and decrese the number of events. */ + fevent = (fevent + 1) % PROCESS_CONF_NUMEVENTS; + --nevents; + + /* If this is a broadcast event, we deliver it to all events, in + order of their priority. */ + if(receiver == PROCESS_BROADCAST) { + for(p = process_list; p != NULL; p = p->next) { + + /* If we have been requested to poll a process, we do this in + between processing the broadcast event. */ + if(poll_requested) { + do_poll(); + } + call_process(p, ev, data); + } + } else if(receiver == PROCESS_ZOMBIE) { + /* This process has exited. */ + } else { + /* This is not a broadcast event, so we deliver it to the + specified process. */ + /* If the event was an INIT event, we should also update the + state of the process. */ + if(ev == PROCESS_EVENT_INIT) { + receiver->state = PROCESS_STATE_RUNNING; + } + + /* Make sure that the process actually is running. */ + call_process(receiver, ev, data); + } + } +} +/*---------------------------------------------------------------------------*/ +int +process_run(void) +{ + /* Process "poll" events. */ + if(poll_requested) { + do_poll(); + } + + /* Process one event */ + do_event(); + + return nevents + poll_requested; +} +/*---------------------------------------------------------------------------*/ +int +process_post(struct process *p, process_event_t ev, process_data_t data) +{ + static unsigned char snum; + + if(nevents == PROCESS_CONF_NUMEVENTS) { + printf("soft panic: event queue is full\n"); + return PROCESS_ERR_FULL; + } + + snum = (fevent + nevents) % PROCESS_CONF_NUMEVENTS; + events[snum].ev = ev; + events[snum].data = data; + events[snum].p = p; + ++nevents; + + return PROCESS_ERR_OK; +} +/*---------------------------------------------------------------------------*/ +void +process_post_synch(struct process *p, process_event_t ev, process_data_t data) +{ + struct process *caller = process_current; + + call_process(p, ev, data); + process_current = caller; +} +/*---------------------------------------------------------------------------*/ +void +process_poll(struct process *p) +{ + if(p != NULL) { + if(p->state == PROCESS_STATE_RUNNING) { + p->state = PROCESS_STATE_NEEDS_POLL; + poll_requested = 1; +#ifdef NPOLLS + int s = splhigh(); + if(npolls < NPOLLS) { + needpoll[npolls] = p; + } + if(npolls != ~0u) npolls++; /* Beware of overflow! */ + splx(s); +#endif + } + } +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/core/sys/process.h b/core/sys/process.h new file mode 100644 index 000000000..1d689de30 --- /dev/null +++ b/core/sys/process.h @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: process.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup sys + * @{ + */ + +/** + * \defgroup process Contiki processes + * + * A process in Contiki consists of a single \ref pt protothread. + * + * @{ + */ + +/** + * \file + * Header file for the Contiki process interface. + * \author + * Adam Dunkels + * + */ +#ifndef __PROCESS_H__ +#define __PROCESS_H__ + +#include "sys/pt.h" +#include "sys/cc.h" + +typedef unsigned char process_event_t; +typedef void * process_data_t; +typedef unsigned char process_num_events_t; + +/** + * \name Return values + * @{ + */ + +/** + * \brief Return value indicating that an operation was successful. + * + * This value is returned to indicate that an operation + * was successful. + */ +#define PROCESS_ERR_OK 0 +/** + * \brief Return value indicating that the event queue was full. + * + * This value is returned from process_post() to indicate + * that the event queue was full and that an event could + * not be posted. + */ +#define PROCESS_ERR_FULL 1 +/* @} */ + +#define PROCESS_NONE NULL + +#ifndef PROCESS_CONF_NUMEVENTS +#define PROCESS_CONF_NUMEVENTS 32 +#endif /* PROCESS_CONF_NUMEVENTS */ + +#define PROCESS_EVENT_NONE 0x80 +#define PROCESS_EVENT_INIT 0x81 +#define PROCESS_EVENT_POLL 0x82 +#define PROCESS_EVENT_EXIT 0x83 +#define PROCESS_EVENT_SERVICE_REMOVED 0x84 +#define PROCESS_EVENT_CONTINUE 0x85 +#define PROCESS_EVENT_MSG 0x86 +#define PROCESS_EVENT_EXITED 0x87 +#define PROCESS_EVENT_TIMER 0x88 +#define PROCESS_EVENT_MAX 0x89 + +#define PROCESS_BROADCAST NULL +#define PROCESS_ZOMBIE ((struct process *)0x1) + +/** + * \name Process protothread functions + * @{ + */ + +/** + * Define the beginning of a process. + * + * This macro defines the beginning of a process, and must always + * appear in a PROCESS_THREAD() definition. The PROCESS_END() macro + * must come at the end of the process. + * + * \hideinitializer + */ +#define PROCESS_BEGIN() PT_BEGIN(process_pt) + +/** + * Define the end of a process. + * + * This macro defines the end of a process. It must appear in a + * PROCESS_THREAD() definition and must always be included. The + * process exits when the PROCESS_END() macro is reached. + * + * \hideinitializer + */ +#define PROCESS_END() PT_END(process_pt) + +/** + * Wait for an event to be posted to the process. + * + * This macro blocks the currently running process until the process + * receives an event. + * + * \hideinitializer + */ +#define PROCESS_WAIT_EVENT() PROCESS_YIELD() + +/** + * Wait for an event to be posted to the process, with an extra + * condition. + * + * This macro is similar to PROCESS_WAIT_EVENT() in that it blocks the + * currently running process until the process receives an event. But + * PROCESS_WAIT_EVENT_UNTIL() takes an extra condition which must be + * true for the process to continue. + * + * \param c The condition that must be true for the process to continue. + * \sa PT_WAIT_UNTIL() + * + * \hideinitializer + */ +#define PROCESS_WAIT_EVENT_UNTIL(c) PROCESS_YIELD_UNTIL(c) + +/** + * Yield the currently running process. + * + * \hideinitializer + */ +#define PROCESS_YIELD() PT_YIELD(process_pt) + +/** + * Yield the currently running process until a condition occurs. + * + * This macro is different from PROCESS_WAIT_UNTIL() in that + * PROCESS_YIELD_UNTIL() is guaranteed to always yield at least + * once. This ensures that the process does not end up in an infinite + * loop and monopolizing the CPU. + * + * \param c The condition to wait for. + * + * \hideinitializer + */ +#define PROCESS_YIELD_UNTIL(c) PT_YIELD_UNTIL(process_pt, c) + +/** + * Wait for a condition to occur. + * + * This macro does not guarantee that the process yields, and should + * therefore be used with care. In most cases, PROCESS_WAIT_EVENT(), + * PROCESS_WAIT_EVENT_UNTIL(), PROCESS_YIELD() or + * PROCESS_YIELD_UNTIL() should be used instead. + * + * \param c The condition to wait for. + * + * \hideinitializer + */ +#define PROCESS_WAIT_UNTIL(c) PT_WAIT_UNTIL(process_pt, c) + +/** + * Exit the currently running process. + * + * \hideinitializer + */ +#define PROCESS_EXIT() PT_EXIT(process_pt) + +/** + * Spawn a protothread from the process. + * + * \param pt The protothread state (struct pt) for the new protothread + * \param thread The call to the protothread function. + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PROCESS_SPAWN(pt, thread) PT_SPAWN(process_pt, pt, thread) + +/** + * Yield the process for a short while. + * + * This macro yields the currently running process for a short while, + * thus letting other processes run before the process continues. + * + * \hideinitializer + */ +#define PROCESS_PAUSE() do { \ + process_post(PROCESS_CURRENT(), PROCESS_EVENT_CONTINUE, NULL); \ + PROCESS_WAIT_EVENT(); \ +} while(0) + +/** @} end of protothread functions */ + +/** + * \name Poll and exit handlers + * @{ + */ +/** + * Specify an action when a process is polled. + * + * \note This declaration must come immediately before the + * PROCESS_BEGIN() macro. + * + * \param handler The action to be performed. + * + * \hideinitializer + */ +#define PROCESS_POLLHANDLER(handler) if(ev == PROCESS_EVENT_POLL) { handler; } + +/** + * Specify an action when a process exits. + * + * \note This declaration must come immediately before the + * PROCESS_BEGIN() macro. + * + * \param handler The action to be performed. + * + * \hideinitializer + */ +#define PROCESS_EXITHANDLER(handler) if(ev == PROCESS_EVENT_EXIT) { handler; } + +/** @} */ + +/** + * \name Process declaration and definion + * @{ + */ + +/** + * Define the body of a process. + * + * This macro is used to define the body (protothread) of a + * process. The process is called whenever an event occurs in the + * system, A process always start with the PROCESS_BEGIN() macro and + * end with the PROCESS_END() macro. + * + * \hideinitializer + */ +#define PROCESS_THREAD(name, ev, data) \ +static PT_THREAD(process_thread_##name(struct pt *process_pt, \ + process_event_t ev, \ + process_data_t data)) + +#if PROCESS_LOADABLE +#define PROCESS_LOAD(name) const struct process *process_load = &name; +#else /* PROCESS_LOADABLE */ +#define PROCESS_LOAD(name) +#endif /* PROCESS_LOADABLE */ +extern const struct process *process_load; + +/** + * Declare the name of a process. + * + * This macro is typically used in header files to declare the name of + * a process that is implemented in the C file. + * + * \hideinitializer + */ +#define PROCESS_NAME(name) extern struct process name + +/** + * Declare a process that should not be automatically loaded. + * + * This macro is similar to the PROCESS() declaration, with the + * difference that for programs that are compiled as loadable + * programs, processes declared with the PROCESS_NOLOAD() declaration + * will not be automatically started when the program is loaded. + * + * \hideinitializer + */ +#define PROCESS_NOLOAD(name, strname) \ + PROCESS_THREAD(name, ev, data); \ + struct process name = { NULL, strname, \ + process_thread_##name }; +/** + * Declare a process. + * + * This macro declares a process. The process has two names: the + * variable of the process structure, which is used by the C program, + * and a human readable string name, which is used when debugging. + * + * \note For programs that are compiled as loadable programs: the + * process declared with the PROCESS() declaration will be + * automatically started when the program is loaded. The + * PROCESS_NOLOAD() declaration can be used to declare a process that + * shouldn't be automatically loaded. + * + * \param name The variable name of the process structure. + * \param strname The string repressentation of the process' name. + * + * \hideinitializer + */ +#define PROCESS(name, strname) \ + PROCESS_NOLOAD(name, strname); \ + PROCESS_LOAD(name) + +/** @} */ + +struct process { + struct process *next; + const char *name; + PT_THREAD((* thread)(struct pt *, process_event_t, process_data_t)); + struct pt pt; + unsigned char state; +}; + +/** + * \name Functions called from application programs + * @{ + */ + +/** + * Start a process. + * + * \param p A pointer to a process structure. + * + * \param arg An argument pointer that can be passed to the new + * process + * + */ +void process_start(struct process *p, char *arg); + +/** + * Post an asynchronous event. + * + * This function posts an asynchronous event to one or more + * processes. The handing of the event is deferred until the target + * process is scheduled by the kernel. An event can be broadcast to + * all processes, in which case all processes in the system will be + * scheduled to handle the event. + * + * \param ev The event to be posted. + * + * \param data The auxillary data to be sent with the event + * + * \param p The process to which the event should be posted, or + * PROCESS_BROADCAST if the event should be posted to all processes. + * + * \retval PROCESS_ERR_OK The event could be posted. + * + * \retval PROCESS_ERR_FULL The event queue was full and the event could + * not be posted. + */ +int process_post(struct process *p, process_event_t ev, process_data_t data); + +/** + * Post a synchronous event to a process. + * + * \param p A pointer to the process' process structure. + * + * \param ev The event to be posted. + * + * \param data A pointer to additional data that is posted together + * with the event. + */ +void process_post_synch(struct process *p, + process_event_t ev, process_data_t data); + +/** + * \brief Cause a process to exit + * \param p The process that is to be exited + * + * This function causes a process to exit. The process can + * either be the currently executing process, or another + * process that is currently running. + * + * \sa PROCESS_CURRENT() + */ +void process_exit(struct process *p); + + +/** + * Get a pointer to the currently running process. + * + * This macro get a pointer to the currently running + * process. Typically, this macro is used to post an event to the + * current process with process_post(). + * + * \hideinitializer + */ +#define PROCESS_CURRENT() process_current +extern struct process *process_current; + +#define PROCESS_SET_FLAGS(flags) +#define PROCESS_NO_BROADCAST + +/** + * Switch context to another process + * + * This function switch context to the specified process and executes + * the code as if run by that process. Typical use of this function is + * to switch context in services, called by other processes. Each + * PROCESS_CONTEXT_BEGIN() must be followed by the + * PROCESS_CONTEXT_END() macro to end the context switch. + * + * Example: + \code + PROCESS_CONTEXT_BEGIN(&test_process); + etimer_set(&timer, CLOCK_SECOND); + PROCESS_CONTEXT_END(&test_process); + \endcode + * + * \param p The process to use as context + * + * \sa PROCESS_CONTEXT_END() + * \sa PROCESS_CURRENT() + */ +#define PROCESS_CONTEXT_BEGIN(p) {\ +struct process *tmp_current = PROCESS_CURRENT();\ +process_current = p + +/** + * End a context switch + * + * This function ends a context switch and changes back to the + * previous process. + * + * \param p The process used in the context switch + * + * \sa PROCESS_CONTEXT_START() + */ +#define PROCESS_CONTEXT_END(p) process_current = tmp_current; } + +/** + * \brief Allocate a global event number. + * \return The allocated event number + * + * In Contiki, event numbers above 128 are global and may + * be posted from one process to another. This function + * allocates one such event number. + * + * \note There currently is no way to deallocate an allocated event + * number. + */ +process_event_t process_alloc_event(void); + +/** @} */ + +/** + * \name Functions called from device drivers + * @{ + */ + +/** + * Request a process to be polled. + * + * This function typically is called from an interrupt handler to + * cause a process to be polled. + * + * \param p A pointer to the process' process structure. + */ +void process_poll(struct process *p); + +/** @} */ + +/** + * \name Functions called by the system and boot-up code + * @{ + */ + +/** + * \brief Initialize the process module. + * + * This function initializes the process module and should + * be called by the system boot-up code. + */ +void process_init(void); + +/** + * Run the system once - call poll handlers and process one event. + * + * This function should be called repeatedly from the main() program + * to actuall run the Contiki system. It calls the necessary poll + * handlers, and processes one event. The function returns the number + * of events that are waiting in the event queue so that the caller + * may choose to put the CPU to sleep when there are no pending + * events. + * + * \return The number of events that are currently waiting in the + * event queue. + */ +int process_run(void); + +/** @} */ + +extern struct process *process_list; + +#define PROCESS_LIST() process_list + +#endif /* __PROCESS_H__ */ + +/** @} */ +/** @} */ diff --git a/core/sys/procinit.c b/core/sys/procinit.c new file mode 100644 index 000000000..169b0cff4 --- /dev/null +++ b/core/sys/procinit.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: procinit.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include "contiki.h" +#include "sys/procinit.h" + +extern const struct process *procinit[]; + +/*---------------------------------------------------------------------------*/ +void +procinit_init(void) +{ + int i; + + for(i = 0; procinit[i] != NULL; ++i) { + process_start((struct process *)procinit[i], NULL); + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/sys/procinit.h b/core/sys/procinit.h new file mode 100644 index 000000000..f00dcdcd0 --- /dev/null +++ b/core/sys/procinit.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: procinit.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __PROCINIT_H__ +#define __PROCINIT_H__ + +#include "sys/process.h" + +#if ! CC_NO_VA_ARGS +#define PROCINIT(...) \ +const struct process *procinit[] = {__VA_ARGS__, NULL}; +#endif + +void procinit_init(void); + +#endif /* __PROCINIT_H__ */ diff --git a/core/sys/pt-sem.h b/core/sys/pt-sem.h new file mode 100644 index 000000000..042c54b1d --- /dev/null +++ b/core/sys/pt-sem.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: pt-sem.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \defgroup ptsem Protothread semaphores + * @{ + * + * This module implements counting semaphores on top of + * protothreads. Semaphores are a synchronization primitive that + * provide two operations: "wait" and "signal". The "wait" operation + * checks the semaphore counter and blocks the thread if the counter + * is zero. The "signal" operation increases the semaphore counter but + * does not block. If another thread has blocked waiting for the + * semaphore that is signalled, the blocked thread will become + * runnable again. + * + * Semaphores can be used to implement other, more structured, + * synchronization primitives such as monitors and message + * queues/bounded buffers (see below). + * + * The following example shows how the producer-consumer problem, also + * known as the bounded buffer problem, can be solved using + * protothreads and semaphores. Notes on the program follow after the + * example. + * + \code +#include "pt-sem.h" + +#define NUM_ITEMS 32 +#define BUFSIZE 8 + +static struct pt_sem mutex, full, empty; + +PT_THREAD(producer(struct pt *pt)) +{ + static int produced; + + PT_BEGIN(pt); + + for(produced = 0; produced < NUM_ITEMS; ++produced) { + + PT_SEM_WAIT(pt, &full); + + PT_SEM_WAIT(pt, &mutex); + add_to_buffer(produce_item()); + PT_SEM_SIGNAL(pt, &mutex); + + PT_SEM_SIGNAL(pt, &empty); + } + + PT_END(pt); +} + +PT_THREAD(consumer(struct pt *pt)) +{ + static int consumed; + + PT_BEGIN(pt); + + for(consumed = 0; consumed < NUM_ITEMS; ++consumed) { + + PT_SEM_WAIT(pt, &empty); + + PT_SEM_WAIT(pt, &mutex); + consume_item(get_from_buffer()); + PT_SEM_SIGNAL(pt, &mutex); + + PT_SEM_SIGNAL(pt, &full); + } + + PT_END(pt); +} + +PT_THREAD(driver_thread(struct pt *pt)) +{ + static struct pt pt_producer, pt_consumer; + + PT_BEGIN(pt); + + PT_SEM_INIT(&empty, 0); + PT_SEM_INIT(&full, BUFSIZE); + PT_SEM_INIT(&mutex, 1); + + PT_INIT(&pt_producer); + PT_INIT(&pt_consumer); + + PT_WAIT_THREAD(pt, producer(&pt_producer) & + consumer(&pt_consumer)); + + PT_END(pt); +} + \endcode + * + * The program uses three protothreads: one protothread that + * implements the consumer, one thread that implements the producer, + * and one protothread that drives the two other protothreads. The + * program uses three semaphores: "full", "empty" and "mutex". The + * "mutex" semaphore is used to provide mutual exclusion for the + * buffer, the "empty" semaphore is used to block the consumer is the + * buffer is empty, and the "full" semaphore is used to block the + * producer is the buffer is full. + * + * The "driver_thread" holds two protothread state variables, + * "pt_producer" and "pt_consumer". It is important to note that both + * these variables are declared as static. If the static + * keyword is not used, both variables are stored on the stack. Since + * protothreads do not store the stack, these variables may be + * overwritten during a protothread wait operation. Similarly, both + * the "consumer" and "producer" protothreads declare their local + * variables as static, to avoid them being stored on the stack. + * + * + */ + +/** + * \file + * Counting semaphores implemented on protothreads + * \author + * Adam Dunkels + * + */ + +#ifndef __PT_SEM_H__ +#define __PT_SEM_H__ + +#include "sys/pt.h" + +struct pt_sem { + unsigned int count; +}; + +/** + * Initialize a semaphore + * + * This macro initializes a semaphore with a value for the + * counter. Internally, the semaphores use an "unsigned int" to + * represent the counter, and therefore the "count" argument should be + * within range of an unsigned int. + * + * \param s (struct pt_sem *) A pointer to the pt_sem struct + * representing the semaphore + * + * \param c (unsigned int) The initial count of the semaphore. + * \hideinitializer + */ +#define PT_SEM_INIT(s, c) (s)->count = c + +/** + * Wait for a semaphore + * + * This macro carries out the "wait" operation on the semaphore. The + * wait operation causes the protothread to block while the counter is + * zero. When the counter reaches a value larger than zero, the + * protothread will continue. + * + * \param pt (struct pt *) A pointer to the protothread (struct pt) in + * which the operation is executed. + * + * \param s (struct pt_sem *) A pointer to the pt_sem struct + * representing the semaphore + * + * \hideinitializer + */ +#define PT_SEM_WAIT(pt, s) \ + do { \ + PT_WAIT_UNTIL(pt, (s)->count > 0); \ + --(s)->count; \ + } while(0) + +/** + * Signal a semaphore + * + * This macro carries out the "signal" operation on the semaphore. The + * signal operation increments the counter inside the semaphore, which + * eventually will cause waiting protothreads to continue executing. + * + * \param pt (struct pt *) A pointer to the protothread (struct pt) in + * which the operation is executed. + * + * \param s (struct pt_sem *) A pointer to the pt_sem struct + * representing the semaphore + * + * \hideinitializer + */ +#define PT_SEM_SIGNAL(pt, s) ++(s)->count + +#endif /* __PT_SEM_H__ */ + +/** @} */ +/** @} */ + diff --git a/core/sys/pt.h b/core/sys/pt.h new file mode 100644 index 000000000..23f861fb2 --- /dev/null +++ b/core/sys/pt.h @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2004-2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: pt.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** + * \addtogroup pt + * @{ + */ + +/** + * \file + * Protothreads implementation. + * \author + * Adam Dunkels + * + */ + +#ifndef __PT_H__ +#define __PT_H__ + +#include "sys/lc.h" + +struct pt { + lc_t lc; +}; + +#define PT_WAITING 0 +#define PT_EXITED 1 +#define PT_ENDED 2 +#define PT_YIELDED 3 + +/** + * \name Initialization + * @{ + */ + +/** + * Initialize a protothread. + * + * Initializes a protothread. Initialization must be done prior to + * starting to execute the protothread. + * + * \param pt A pointer to the protothread control structure. + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_INIT(pt) LC_INIT((pt)->lc) + +/** @} */ + +/** + * \name Declaration and definition + * @{ + */ + +/** + * Declaration of a protothread. + * + * This macro is used to declare a protothread. All protothreads must + * be declared with this macro. + * + * \param name_args The name and arguments of the C function + * implementing the protothread. + * + * \hideinitializer + */ +#define PT_THREAD(name_args) char name_args + +/** + * Declare the start of a protothread inside the C function + * implementing the protothread. + * + * This macro is used to declare the starting point of a + * protothread. It should be placed at the start of the function in + * which the protothread runs. All C statements above the PT_BEGIN() + * invokation will be executed each time the protothread is scheduled. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc) + +/** + * Declare the end of a protothread. + * + * This macro is used for declaring that a protothread ends. It must + * always be used together with a matching PT_BEGIN() macro. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \ + PT_INIT(pt); return PT_ENDED; } + +/** @} */ + +/** + * \name Blocked wait + * @{ + */ + +/** + * Block and wait until condition is true. + * + * This macro blocks the protothread until the specified condition is + * true. + * + * \param pt A pointer to the protothread control structure. + * \param condition The condition. + * + * \hideinitializer + */ +#define PT_WAIT_UNTIL(pt, condition) \ + do { \ + LC_SET((pt)->lc); \ + if(!(condition)) { \ + return PT_WAITING; \ + } \ + } while(0) + +/** + * Block and wait while condition is true. + * + * This function blocks and waits while condition is true. See + * PT_WAIT_UNTIL(). + * + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * \hideinitializer + */ +#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond)) + +/** @} */ + +/** + * \name Hierarchical protothreads + * @{ + */ + +/** + * Block and wait until a child protothread completes. + * + * This macro schedules a child protothread. The current protothread + * will block until the child protothread completes. + * + * \note The child protothread must be manually initialized with the + * PT_INIT() function before this function is used. + * + * \param pt A pointer to the protothread control structure. + * \param thread The child protothread with arguments + * + * \sa PT_SPAWN() + * + * \hideinitializer + */ +#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread)) + +/** + * Spawn a child protothread and wait until it exits. + * + * This macro spawns a child protothread and waits until it exits. The + * macro can only be used within a protothread. + * + * \param pt A pointer to the protothread control structure. + * \param child A pointer to the child protothread's control structure. + * \param thread The child protothread with arguments + * + * \hideinitializer + */ +#define PT_SPAWN(pt, child, thread) \ + do { \ + PT_INIT((child)); \ + PT_WAIT_THREAD((pt), (thread)); \ + } while(0) + +/** @} */ + +/** + * \name Exiting and restarting + * @{ + */ + +/** + * Restart the protothread. + * + * This macro will block and cause the running protothread to restart + * its execution at the place of the PT_BEGIN() call. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_RESTART(pt) \ + do { \ + PT_INIT(pt); \ + return PT_WAITING; \ + } while(0) + +/** + * Exit the protothread. + * + * This macro causes the protothread to exit. If the protothread was + * spawned by another protothread, the parent protothread will become + * unblocked and can continue to run. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_EXIT(pt) \ + do { \ + PT_INIT(pt); \ + return PT_EXITED; \ + } while(0) + +/** @} */ + +/** + * \name Calling a protothread + * @{ + */ + +/** + * Schedule a protothread. + * + * This function shedules a protothread. The return value of the + * function is non-zero if the protothread is running or zero if the + * protothread has exited. + * + * \param f The call to the C function implementing the protothread to + * be scheduled + * + * \hideinitializer + */ +#define PT_SCHEDULE(f) ((f) == PT_WAITING) + +/** @} */ + +/** + * \name Yielding from a protothread + * @{ + */ + +/** + * Yield from the current protothread. + * + * This function will yield the protothread, thereby allowing other + * processing to take place in the system. + * + * \param pt A pointer to the protothread control structure. + * + * \hideinitializer + */ +#define PT_YIELD(pt) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if(PT_YIELD_FLAG == 0) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** + * \brief Yield from the protothread until a condition occurs. + * \param pt A pointer to the protothread control structure. + * \param cond The condition. + * + * This function will yield the protothread, until the + * specified condition evaluates to true. + * + * + * \hideinitializer + */ +#define PT_YIELD_UNTIL(pt, cond) \ + do { \ + PT_YIELD_FLAG = 0; \ + LC_SET((pt)->lc); \ + if((PT_YIELD_FLAG == 0) || !(cond)) { \ + return PT_YIELDED; \ + } \ + } while(0) + +/** @} */ + +#endif /* __PT_H__ */ + +/** @} */ diff --git a/core/sys/service.c b/core/sys/service.c new file mode 100644 index 000000000..646c6328e --- /dev/null +++ b/core/sys/service.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: service.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include + +#include "contiki.h" + +/** + * \addtogroup service + * @{ + */ + +/** + * \file + * Implementation of the Contiki service mechanism. + * \author + * Adam Dunkels + */ + +static struct service *services_list = NULL; + +/*---------------------------------------------------------------------------*/ +void +service_register(struct service *s) +{ + struct service *existing; + + + s->p = PROCESS_CURRENT(); + + existing = service_find(s->name); + if(existing != NULL) { + service_remove(existing); + } + + s->next = services_list; + services_list = s; +} +/*---------------------------------------------------------------------------*/ +void +service_remove(struct service *s) +{ + struct service *t; + + + /* Check if service is first on the list. */ + if(s == services_list) { + services_list = s->next; + + /* Post a notification to the owner process. */ + process_post(s->p, PROCESS_EVENT_SERVICE_REMOVED, s); + + } else { + for(t = services_list; t != NULL && t->next != s; t = t->next); + if(t != NULL) { + t->next = s->next; + + /* Post a notification to the owner process. */ + process_post(s->p, PROCESS_EVENT_SERVICE_REMOVED, s); + } + } + + s->next = NULL; +} +/*---------------------------------------------------------------------------*/ +struct service * +service_find(const char *name) +{ + struct service *s; + + + for(s = services_list; s != NULL; s = s->next) { + if(strcmp(s->name, name) == 0) { + return s; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/core/sys/service.h b/core/sys/service.h new file mode 100644 index 000000000..86cc3bf06 --- /dev/null +++ b/core/sys/service.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: service.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +/** \addtogroup sys + * @{ + */ + +/** + * \defgroup service The Contiki service mechanism + * + * The Contiki service mechanism enables cross-process functions. A + * service that is registered by one process can be accessed by other + * processes in the system. Services can be transparently replaced at + * run-time. + * + * A service has an interface that callers use to access the service's + * functions. This interface typically is defined in a header file + * that is included by all users of the service. A service interface + * is defined with the SERVICE_INTERFACE() macro. + * + * A service implementation is declared with the SERVICE() macro. The + * SERVICE() statement specifies the actual functions that are used to + * implement the service. + * + * Every service has a controlling process. The controlling process + * registers the service with the system when it starts, and is also + * notified if the service is removed or replaced. A process may + * register any number of services. + * + * Service registration is done with a SERVICE_REGISTER() + * statement. If a service with the same name is already registered, + * this is removed before the new service is registered. + * + * The SERVICE_CALL() macro is used to call a service. If the service + * to be called is not registered, the SERVICE_CALL() statement does + * nothing. The SERVICE_FIND() function can be used to check if a + * particular service exists before calling SERVICE_CALL(). + * + * @{ + */ + +/** + * \file + * Header file for the Contiki service mechanism. + * \author + * Adam Dunkels + */ + +#ifndef __SERVICE_H__ +#define __SERVICE_H__ + +#include "contiki.h" + +struct service { + struct service *next; + struct process *p; + const char *name; + const void *interface; +}; + +/** + * \name Service declaration and defition + * @{ + */ + +/** + * Define the name and interface of a service. + * + * This statement defines the name and interface of a service. + * + * \param name The name of the service. + * + * \param interface A list of function declarations that comprises the + * service interface. This list must be enclosed by curly brackets and + * consist of declarations of function pointers separated by + * semicolons. + * + * \hideinitializer + */ +#define SERVICE_INTERFACE(name, interface) struct name interface; + +#if ! CC_NO_VA_ARGS +/** + * \brief Define an implementation of a service interface. + * \param name The name of this particular instance of the service, for use with SERVICE_REGISTER(). + * \param service_name The name of the service, from the SERVICE_INTERFACE(). + * \param ... A structure containing the functions that implements the service. + * + * This statement defines the name of this implementation + * of the service and defines the functions that actually + * implement the functions offered by the service. + * + * \hideinitializer + */ +#define SERVICE(name, service_name, ...) \ + static struct service_name name##_interface = __VA_ARGS__ ; \ + struct service name = { NULL, NULL, service_name##_name, & name##_interface } +#endif + +/** @} */ + +/** + * \name Calling a service + * @{ + */ + +/** + * Call a function from a specified service, if it is registered. + * + * + * \param service_name The name of the service that is to be called. + * + * \param function The function that is to be called. This is a full + * function call, including parameters. + * + * \hideinitializer + */ +#define SERVICE_CALL(service_name, function) \ + { \ + struct service *service_s; \ + service_s = service_find(service_name##_name); \ + if(service_s != NULL) { \ + ((const struct service_name *)service_s->interface)->function; \ + } \ + } + +/* @} */ + +#define SERVICE_EXISTS(service_name) (service_find(service_name##_name) != NULL) + +/** + * \name Service registration and removal + * @{ + */ + +/** + * Register a service. + * + * \hideinitializer + */ +#define SERVICE_REGISTER(name) service_register(&name) + +/** + * Remove a service. + * + * \hideinitializer + */ +#define SERVICE_REMOVE(service_name) service_remove(&service_name) + +/** @} */ + +/** + * Find service. + * + * \hideinitializer + */ +#define SERVICE_FIND(service_name) service_find(service_name##_name) + +void service_register(struct service *s); +void service_remove(struct service *s); +struct service *service_find(const char *name); + +#endif /* __SERVICE_H__ */ +/** @} */ +/** @} */ diff --git a/core/sys/timer.c b/core/sys/timer.c new file mode 100644 index 000000000..c77ec0508 --- /dev/null +++ b/core/sys/timer.c @@ -0,0 +1,128 @@ +/** + * \addtogroup timer + * @{ + */ + +/** + * \file + * Timer library implementation. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: timer.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ + +#include "contiki-conf.h" +#include "sys/clock.h" +#include "sys/timer.h" + +/*---------------------------------------------------------------------------*/ +/** + * Set a timer. + * + * This function is used to set a timer for a time sometime in the + * future. The function timer_expired() will evaluate to true after + * the timer has expired. + * + * \param t A pointer to the timer + * \param interval The interval before the timer expires. + * + */ +void +timer_set(struct timer *t, clock_time_t interval) +{ + t->interval = interval; + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Reset the timer with the same interval. + * + * This function resets the timer with the same interval that was + * given to the timer_set() function. The start point of the interval + * is the exact time that the timer last expired. Therefore, this + * function will cause the timer to be stable over time, unlike the + * timer_rester() function. + * + * \param t A pointer to the timer. + * + * \sa timer_restart() + */ +void +timer_reset(struct timer *t) +{ + t->start += t->interval; +} +/*---------------------------------------------------------------------------*/ +/** + * Restart the timer from the current point in time + * + * This function restarts a timer with the same interval that was + * given to the timer_set() function. The timer will start at the + * current time. + * + * \note A periodic timer will drift if this function is used to reset + * it. For preioric timers, use the timer_reset() function instead. + * + * \param t A pointer to the timer. + * + * \sa timer_reset() + */ +void +timer_restart(struct timer *t) +{ + t->start = clock_time(); +} +/*---------------------------------------------------------------------------*/ +/** + * Check if a timer has expired. + * + * This function tests if a timer has expired and returns true or + * false depending on its status. + * + * \param t A pointer to the timer + * + * \return Non-zero if the timer has expired, zero otherwise. + * + */ +int +timer_expired(struct timer *t) +{ + return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval; +} +/*---------------------------------------------------------------------------*/ + +/** @} */ diff --git a/core/sys/timer.h b/core/sys/timer.h new file mode 100644 index 000000000..aefd34e48 --- /dev/null +++ b/core/sys/timer.h @@ -0,0 +1,100 @@ +/** \addtogroup sys + * @{ */ + +/** + * \defgroup timer Timer library + * + * The Contiki kernel does not provide support for timed + * events. Rather, an application that wants to use timers needs to + * explicitly use the timer library. + * + * The timer library provides functions for setting, resetting and + * restarting timers, and for checking if a timer has expired. An + * application must "manually" check if its timers have expired; this + * is not done automatically. + * + * A timer is declared as a \c struct \c timer and all access to the + * timer is made by a pointer to the declared timer. + * + * \note The timer library is not able to post events when a timer + * expires. The \ref etimer "Event timers" should be used for this + * purpose. + * + * \note The timer library uses the \ref clock "Clock library" to + * measure time. Intervals should be specified in the format used by + * the clock library. + * + * \sa \ref etimer "Event timers" + * + * @{ + */ + + +/** + * \file + * Timer library header file. + * \author + * Adam Dunkels + */ + +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: timer.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include "sys/clock.h" + +/** + * A timer. + * + * This structure is used for declaring a timer. The timer must be set + * with timer_set() before it can be used. + * + * \hideinitializer + */ +struct timer { + clock_time_t start; + clock_time_t interval; +}; + +void timer_set(struct timer *t, clock_time_t interval); +void timer_reset(struct timer *t); +void timer_restart(struct timer *t); +int timer_expired(struct timer *t); + +#endif /* __TIMER_H__ */ + +/** @} */ +/** @} */ diff --git a/cpu/6502/Makefile.cc65 b/cpu/6502/Makefile.cc65 new file mode 100644 index 000000000..7f29239e1 --- /dev/null +++ b/cpu/6502/Makefile.cc65 @@ -0,0 +1,76 @@ +-include *.u + +.SECONDARY: + +CONTIKI_CPU=$(CONTIKI)/cpu/6502 + +INCLUDES=-I. -I$(CONTIKI_CPU) \ + ${addprefix -I$(CONTIKI)/platform/$(TARGET)/, . apps ctk lib loader net} \ + ${addprefix -I,$(APPDIRS)} -I$(CONTIKI)/core + + +CCDEP=gcc +CDEPFLAGS=$(INCLUDES) + +CC=cc65 +AS=ca65 +LD=ld65 +CL=cl65 + +PORTDIRS=apps conf ctk lib loader net +CONTIKICC65DIRS=${addprefix $(CONTIKI_CPU)/, apps lib loader net} + +CFLAGSCC65=$(INCLUDES) \ + -DWITH_PETSCII \ + -t $(SYS) --add-source --create-dep + +CLFLAGS=-Ln contiki-labels + +OPT=-Or + +#%.o: %.c + +#%.s: %.c +# $(CC) $(CFLAGS) $(OPT) -o $(notdir $@) $< + +#%.o: %.s +# $(AS) $(AFLAGS) -o $@ $< + +#%.o: %.S +# $(AS) $(AFLAGS) -o $@ $< + +$(OBJECTDIR)/%.o: %.c + $(CC) $(CFLAGS) $< -o $@ + +CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \ + $(CONTIKI_TARGET_DIRS)} + +vpath %.c $(PROJECTDIRS) \ + $(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ + $(CONTIKI_CPU) + +vpath %.S $(PORTDIRS) $(CONTIKICC65DIRS) $(CONTIKIDIRS) + +%.sav: %.o contiki-labels.o + cl65 --module -t $(SYS) -o $@ loader-arch-module.o $^ + +%.prg: %.o contiki-labels.o + cl65 --module -t $(SYS) -o $@ loader-arch-module.o $^ + +%.drv: %-drv.o contiki-labels.o + cl65 --module -t $(SYS) -o $@ loader-arch-module.o $^ + +%.drv: %.o contiki-labels.o + cl65 --module -t $(SYS) -o $@ loader-arch-module.o $^ + +%.dsc: %-dsc.o contiki-labels.o + cl65 --module -t $(SYS) -o $@ loader-arch-module-dsc.o $^ + +contiki-labels.s: contiki + ./$(CONTIKI)/tools/cc65-make-labels + +#clean: +# rm -f *.o *~ *core contiki *.map *.s *.u *.dsc *.prg *.drv *.sav contiki-labels + +codesize: + od65 --dump-segsize *.o | egrep '\.o|CODE' diff --git a/cpu/6502/Makefile.common b/cpu/6502/Makefile.common new file mode 100644 index 000000000..36f74a683 --- /dev/null +++ b/cpu/6502/Makefile.common @@ -0,0 +1,27 @@ +UIP=uip.o uip_arch.o uiplib.o resolv.o tcpip.o + +DHCP=dhcp.o dhcpc.o + +DIRECTORY=directory.o loader-arch-dsc.o + +EDITOR=editor.o memb.o ctk-filedialog.o + +EMAIL=email.o smtp-socket.o smtp-strings.o ctk-textentry-multiline.o psock.o uipbuf.o memb.o + +FTP=ftp.o ftpc.o memb.o + +IRC=irc.o ircc.o psock.o uipbuf.o ircc-strings.o ctk-textentry-cmdline.o + +SHELL_=shell-gui.o shell.o ctk-textentry-cmdline.o + +TELNET=simpletelnet.o telnet.o + +TELNETD=telnetd.o shell.o memb.o telnetd-gui.o + +VNCVIEWER=vnc.o vnc-viewer.o vnc-draw.o + +WEBSERVER=webserver.o httpd.o http-strings.o psock.o uipbuf.o memb.o httpd-fs.o + +WGET=wget.o webclient.o http-strings.o http-user-agent-string.o + +WWW=www.o webclient.o http-strings.o http-user-agent-string.o htmlparser.o html-strings.o diff --git a/cpu/6502/apps/memstat-dsc.c b/cpu/6502/apps/memstat-dsc.c new file mode 100644 index 000000000..3d9ab7ef1 --- /dev/null +++ b/cpu/6502/apps/memstat-dsc.c @@ -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: memstat-dsc.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon memstat_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(memstat_dsc, + "Memory stats", + "memstat.prg", + memstat_init, + &memstat_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char memstaticon_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 memstaticon_textmap[9] = { + '0', '0', '1', + '0', '1', '0', + '1', '0', '1' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon memstat_icon = + {CTK_ICON("Memory stats", memstaticon_bitmap, memstaticon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/6502/apps/memstat-dsc.h b/cpu/6502/apps/memstat-dsc.h new file mode 100644 index 000000000..6ff1ba1af --- /dev/null +++ b/cpu/6502/apps/memstat-dsc.h @@ -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: memstat-dsc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __MEMSTAT_DSC_H__ +#define __MEMSTAT_DSC_H__ + +#include "sys/dsc.h" + +DSC_HEADER(memstat_dsc); + +#endif /* __MEMSTAT_DSC_H__ */ diff --git a/cpu/6502/apps/memstat.c b/cpu/6502/apps/memstat.c new file mode 100644 index 000000000..23bad0b59 --- /dev/null +++ b/cpu/6502/apps/memstat.c @@ -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: memstat.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ + +#include + +#include "contiki.h" +#include "ctk/ctk.h" + +static struct ctk_window window; +static struct ctk_label freemsg = + {CTK_LABEL(2, 0, 12, 1, "Free memory:")}; +static char freemem[6]; +static struct ctk_label freenum = + {CTK_LABEL(18, 0, 5, 1, freemem)}; + +static struct ctk_label lblockmsg = + {CTK_LABEL(2, 2, 14, 1, "Largest block:")}; +static char lblock[6]; +static struct ctk_label lblocknum = + {CTK_LABEL(18, 2, 5, 1, lblock)}; + +static struct ctk_button updatebutton = + {CTK_BUTTON(0, 4, 6, "Update")}; +static struct ctk_button closebutton = + {CTK_BUTTON(17, 4, 5, "Close")}; + +PROCESS(memstat_process, "Memory statistics"); + +/*-----------------------------------------------------------------------------------*/ +static void +update(void) +{ + int mem; + + mem = _heapmemavail(); + freemem[0] = (mem/10000) % 10 + '0'; + freemem[1] = (mem/1000) % 10 + '0'; + freemem[2] = (mem/100) % 10 + '0'; + freemem[3] = (mem/10) % 10 + '0'; + freemem[4] = (mem) % 10 + '0'; + + mem = _heapmaxavail(); + lblock[0] = (mem/10000) % 10 + '0'; + lblock[1] = (mem/1000) % 10 + '0'; + lblock[2] = (mem/100) % 10 + '0'; + lblock[3] = (mem/10) % 10 + '0'; + lblock[4] = (mem) % 10 + '0'; + +} +/*-----------------------------------------------------------------------------------*/ +PROCESS_THREAD(memstat_process, ev, data) +{ + PROCESS_BEGIN(); + + ctk_window_new(&window, 24, 5, "Memory stats"); + /* ctk_window_move(&window, 0, 1);*/ + + CTK_WIDGET_ADD(&window, &freemsg); + CTK_WIDGET_ADD(&window, &freenum); + + CTK_WIDGET_ADD(&window, &lblockmsg); + CTK_WIDGET_ADD(&window, &lblocknum); + + CTK_WIDGET_ADD(&window, &updatebutton); + CTK_WIDGET_ADD(&window, &closebutton); + + CTK_WIDGET_FOCUS(&window, &updatebutton); + + update(); + + ctk_window_open(&window); + + while(1) { + + PROCESS_WAIT_EVENT(); + + if(ev == ctk_signal_button_activate) { + if(data == &updatebutton) { + update(); + ctk_window_redraw(&window); + } else if(data == &closebutton) { + ctk_window_close(&window); + break; + } + } else if((ev == ctk_signal_window_close && + data == &window) || + ev == PROCESS_EVENT_EXIT) { + break; + } + } + + PROCESS_END(); + +} +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/6502/lib/clock.c b/cpu/6502/lib/clock.c new file mode 100644 index 000000000..6d12d2bc7 --- /dev/null +++ b/cpu/6502/lib/clock.c @@ -0,0 +1,41 @@ +/* + * 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 + * + * $Id: clock.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +#include + +clock_time_t +clock_time(void) +{ + return clock(); +} diff --git a/cpu/6502/lib/lc-asm.S b/cpu/6502/lib/lc-asm.S new file mode 100644 index 000000000..327a20a02 --- /dev/null +++ b/cpu/6502/lib/lc-asm.S @@ -0,0 +1,30 @@ +;--------------------------------------------------------------------- + .importzp ptr1 + .export _lc_set + .export _lc_resume +;--------------------------------------------------------------------- +_lc_set: + sta ptr1 + stx ptr1+1 + tsx + lda $0102,x + ldy #$01 + sta (ptr1),y + lda $0101,x + dey + sta (ptr1),y + rts +;--------------------------------------------------------------------- +_lc_resume: + sta ptr1 + stx ptr1+1 + ldy #$01 + lda (ptr1),y + beq :+ + tsx + sta $0102,x + dey + lda (ptr1),y + sta $0101,x +: rts +;--------------------------------------------------------------------- diff --git a/cpu/6502/lib/lc-cc65.h b/cpu/6502/lib/lc-cc65.h new file mode 100644 index 000000000..6e5799d28 --- /dev/null +++ b/cpu/6502/lib/lc-cc65.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2004, Adam Dunkels and Oliver Schmidt + * 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 , Oliver Schmidt + * + * $Id: lc-cc65.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +/* Local continuations: a form of continuation that only works locally + within a function. +*/ + +#ifndef __LC_CC65_H__ +#define __LC_CC65_H__ + +typedef void * lc_t; + +void __fastcall__ lc_set(lc_t *lc); +void __fastcall__ lc_resume(lc_t *lc); + +#define LC_SET(lc) lc_set(&(lc)) +#define LC_RESUME(lc) lc_resume(&(lc)) +#define LC_INIT(lc) (lc) = NULL +#define LC_END(lc) + +#endif /* __LC_CC65_H__ */ diff --git a/cpu/6502/lib/lc.h b/cpu/6502/lib/lc.h new file mode 100644 index 000000000..a94f21dd3 --- /dev/null +++ b/cpu/6502/lib/lc.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2004, Adam Dunkels and Oliver Schmidt + * 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 , Oliver Schmidt + * + * $Id: lc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + */ +/* Local continuations: a form of continuation that only works locally + within a function. +*/ + +#ifndef __LC_H__ +#define __LC_H__ + +typedef void * lc_t; + +void __fastcall__ lc_set(lc_t *lc); +void __fastcall__ lc_resume(lc_t *lc); + +#define LC_SET(lc) lc_set(&(lc)) +#define LC_RESUME(lc) lc_resume(&(lc)) +#define LC_INIT(lc) (lc) = NULL +#define LC_END(lc) + +#endif /* __LC_H__ */ diff --git a/cpu/6502/loader/loader-arch-dsc.c b/cpu/6502/loader/loader-arch-dsc.c new file mode 100644 index 000000000..7e9549c38 --- /dev/null +++ b/cpu/6502/loader/loader-arch-dsc.c @@ -0,0 +1,57 @@ +/* + * 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: loader-arch-dsc.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ + +#include +#include + +#include "sys/loader.h" + +extern struct mod_ctrl ctrl; + +unsigned char load(const char *name); + +/*-----------------------------------------------------------------------------------*/ +struct dsc * +loader_arch_load_dsc(const char *name) +{ + unsigned char r; + + r = load(name); + if(r == MLOAD_OK) { + return (struct dsc *)ctrl.module; + } + return NULL; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/6502/loader/loader-arch-dsc.h b/cpu/6502/loader/loader-arch-dsc.h new file mode 100644 index 000000000..e72f9e705 --- /dev/null +++ b/cpu/6502/loader/loader-arch-dsc.h @@ -0,0 +1,46 @@ +/* + * 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: loader-arch-dsc.h,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ +#ifndef __LOADER_ARCH_DSC_H__ +#define __LOADER_ARCH_DSC_H__ + +#include "sys/dsc.h" +#include + +struct dsc *loader_arch_load_dsc(const char *name); + +#define LOADER_LOAD_DSC(name) loader_arch_load_dsc(name) +#define LOADER_UNLOAD_DSC(dsc) mod_free(dsc) + +#endif /* __LOADER_ARCH_DSC_H__ */ diff --git a/cpu/6502/loader/loader-arch-module-dsc.S b/cpu/6502/loader/loader-arch-module-dsc.S new file mode 100644 index 000000000..dd82301c2 --- /dev/null +++ b/cpu/6502/loader/loader-arch-module-dsc.S @@ -0,0 +1 @@ +.segment "JUMPTABLE" diff --git a/cpu/6502/loader/loader-arch-module.S b/cpu/6502/loader/loader-arch-module.S new file mode 100644 index 000000000..0746bf750 --- /dev/null +++ b/cpu/6502/loader/loader-arch-module.S @@ -0,0 +1,8 @@ +.segment "JUMPTABLE" + .import _loader_appinit + .export _loader_arch_loadaddr +_loader_arch_loadaddr: +arch: .byte 0,0,0,0,0,0,0,0 +version: .byte 0,0,0,0,0,0,0,0 +; jmp _loader_appinit + diff --git a/cpu/6502/loader/loader-arch.c b/cpu/6502/loader/loader-arch.c new file mode 100644 index 000000000..4505720d3 --- /dev/null +++ b/cpu/6502/loader/loader-arch.c @@ -0,0 +1,117 @@ +/* + * 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: loader-arch.c,v 1.1 2006/06/17 22:41:20 adamdunkels Exp $ + * + */ + +#include +#include +#include +#include + +#include "loader.h" + +struct mod_ctrl ctrl = { + read /* Read from disk */ +}; + +struct loader_arch_hdr { + char arch[8]; + char version[8]; + + char initfunc[1]; +}; + +/*-----------------------------------------------------------------------------------*/ +/* load(name) + * + * Loads a program from disk and executes it. Code originally written by + * Ullrich von Bassewitz. + */ +/*-----------------------------------------------------------------------------------*/ +unsigned char +load(const char *name) +{ + unsigned char res; + + /* Now open the file */ + ctrl.callerdata = open(name, O_RDONLY); + if(ctrl.callerdata < 0) { + /* Could not open the file, display an error and return */ + /* ### */ + return LOADER_ERR_OPEN; + } + + /* Load the module */ + res = mod_load(&ctrl); + + /* Close the input file */ + close(ctrl.callerdata); + + /* Check the return code */ + if(res != MLOAD_OK) { + /* Wrong module, out of memory or whatever. Print an error + * message and return. + */ + /* ### */ + return res; + } + + /* We've successfully loaded the module. */ + + return LOADER_OK; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +loader_arch_load(const char *name, char *arg) +{ + unsigned char r; + struct loader_arch_hdr *hdr; + + r = load(name); + if(r != MLOAD_OK) { + return r; + } + hdr = (struct loader_arch_hdr *)ctrl.module; + + /* Check the program header and see that version and architecture + matches. */ + + /* Call the init function. */ + + if(*hdr->initfunc == 0x4c) { + ((void (*)(char *))hdr->initfunc)(arg); + } + + return LOADER_OK; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/6502/loader/loader-arch.h b/cpu/6502/loader/loader-arch.h new file mode 100644 index 000000000..04fd33eae --- /dev/null +++ b/cpu/6502/loader/loader-arch.h @@ -0,0 +1,47 @@ +/* + * 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: loader-arch.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ +#ifndef __LOADER_ARCH_H__ +#define __LOADER_ARCH_H__ + +#include + +unsigned char loader_arch_load(const char *name, char *arg); + +extern void *loader_arch_loadaddr; + +#define LOADER_LOAD(name, arg) loader_arch_load(name, arg) +#define LOADER_UNLOAD() mod_free(&loader_arch_loadaddr) + +#endif /* __LOADER_ARCH_H__ */ diff --git a/cpu/6502/net/rs232dev.c b/cpu/6502/net/rs232dev.c new file mode 100644 index 000000000..76654ed61 --- /dev/null +++ b/cpu/6502/net/rs232dev.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2001, 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: rs232dev.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + +/* + * This is a generic implementation of the SLIP protocol over an RS232 + * (serial) device. While initially intented for the C64, the code can + * easily be ported to other platforms as well. + * + * Huge thanks to Ullrich von Bassewitz of cc65 fame for + * and endless supply of bugfixes, insightsful comments and + * suggestions, and improvements to this code! + */ + +#include +#include +#include + + /* This will include the system specific header files as well */ +#if defined(__CBM__) +# include +#elif defined(__ATARI__) +# include +#endif + +#include "net/uip.h" + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + + +#define SIO_RECV(c) while(ser_get(&c) == SER_ERR_NO_DATA) +#define SIO_POLL(c) (ser_get(&c) != SER_ERR_NO_DATA) +#define SIO_SEND(c) ser_put(c) + +#define MAX_SIZE (UIP_BUFSIZE - UIP_LLH_LEN) + +static u8_t slip_buf[MAX_SIZE + 2]; + +static u16_t len, tmplen; + +static char loaded = 0; + +#if 1 +#define printf(x) +#else +#include +#endif + + +/*-----------------------------------------------------------------------------------*/ +/*static void +rs232_err(char err) +{ + switch(err) { + case RS_ERR_OK: + printf("RS232 OK\n"); + break; + case RS_ERR_NOT_INITIALIZED: + printf("RS232 not initialized\n"); + break; + case RS_ERR_BAUD_TOO_FAST: + printf("RS232 baud too fast\n"); + break; + case RS_ERR_BAUD_NOT_AVAIL: + printf("RS232 baud rate not available\n"); + break; + case RS_ERR_NO_DATA: + printf("RS232 nothing to read\n"); + break; + case RS_ERR_OVERFLOW: + printf("RS232 overflow\n"); + break; + } +}*/ +/*-----------------------------------------------------------------------------------*/ +/* + * rs232dev_send(): + * + * Sends the packet in the uip_buf and uip_appdata buffers. The first + * 40 bytes of the packet (the IP and TCP headers) are read from the + * uip_buf buffer, and the following bytes (the application data) are + * read from the uip_appdata buffer. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +rs232dev_send(void) +{ + u16_t i; + u8_t *ptr; + u8_t c; + + SIO_SEND(SLIP_END); + + ptr = &uip_buf[UIP_LLH_LEN]; + for(i = 0; i < uip_len; ++i) { + if(i == UIP_TCPIP_HLEN) { + ptr = uip_appdata; + } + c = *ptr++; + switch(c) { + case SLIP_END: + SIO_SEND(SLIP_ESC); + SIO_SEND(SLIP_ESC_END); + break; + case SLIP_ESC: + SIO_SEND(SLIP_ESC); + SIO_SEND(SLIP_ESC_ESC); + break; + default: + SIO_SEND(c); + break; + } + } + SIO_SEND(SLIP_END); +} +/*-----------------------------------------------------------------------------------*/ +/* + * rs232dev_poll(): + * + * Read all avaliable bytes from the RS232 interface into the slip_buf + * buffer. If no more bytes are avaliable, it returns with 0 to + * indicate that no packet was immediately ready. When a full packet + * has been read into the buffer, the packet is copied into the + * uip_buf buffer and the length of the packet is returned. + * + */ +/*-----------------------------------------------------------------------------------*/ +u16_t +rs232dev_poll(void) +{ + u8_t c; + static u8_t lastc; + + if(loaded == 0) { + return 0; + } + + while(SIO_POLL(c)) { + + switch(c) { + case SLIP_ESC: + lastc = c; + break; + + case SLIP_END: + lastc = c; + /* End marker found, we copy our input buffer to the uip_buf + buffer and return the size of the packet we copied. */ + memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len); + tmplen = len; + len = 0; + return tmplen; + + default: + if(lastc == SLIP_ESC) { + lastc = c; + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + } else { + lastc = c; + } + + slip_buf[len] = c; + ++len; + + if(len > MAX_SIZE) { + len = 0; + } + + break; + } + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +/* + * rs232dev_init(): + * + * Initializes the RS232 device and sets the parameters of the device. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +rs232dev_init(void) +{ + char err; + struct ser_params p; + + err = ser_load_driver("c64-swlink.ser"); + + if(err != SER_ERR_OK) { + asm("inc $d020"); + return; + } + + p.baudrate = SER_BAUD_9600; + p.databits = SER_BITS_8; + p.stopbits = SER_STOP_1; + p.parity = SER_PAR_NONE; + p.handshake = SER_HS_HW; + + err = ser_open(&p); + + if(err != SER_ERR_OK) { + asm("inc $d020"); + return; + } + + + loaded = 1; + + /* err = rs232_init(0); */ + /* rs232_err(err);*/ + /* err = rs232_params(RS_BAUD_9600 | RS_BITS_8 | RS_STOP_1, RS_PAR_NONE);*/ + /* rs232_err(err);*/ + + len = 0; + + return; +} +/*-----------------------------------------------------------------------------------*/ +void +rs232dev_unload(void) +{ + if(loaded){ + ser_unload(); + } +} +/*-----------------------------------------------------------------------------------*/ + diff --git a/cpu/6502/net/rs232dev.h b/cpu/6502/net/rs232dev.h new file mode 100644 index 000000000..77dde7562 --- /dev/null +++ b/cpu/6502/net/rs232dev.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2001, 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: rs232dev.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + +#ifndef __RS232DEV_H__ +#define __RS232DEV_H__ + +#include "net/uip.h" + +void rs232dev_init(void); +u8_t rs232dev_read(void); +void rs232dev_send(void); + +u16_t rs232dev_poll(void); + +void rs232dev_unload(void); + +#endif /* __RS232DEV_H__ */ diff --git a/cpu/6502/net/slip-drv.c b/cpu/6502/net/slip-drv.c new file mode 100644 index 000000000..5d7c7c075 --- /dev/null +++ b/cpu/6502/net/slip-drv.c @@ -0,0 +1,81 @@ +/* + * 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 OS + * + * $Id: slip-drv.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + +#include "contiki-net.h" +#include "rs232dev.h" + +static u8_t output(void); + +SERVICE(slip_drv_service, packet_service, { output };); + +PROCESS(slip_drv_process, "SLIP driver"); + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + rs232dev_send(); + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ + uip_len = rs232dev_poll(); + if(uip_len > 0) { + tcpip_input(); + } + +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(slip_drv_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + PROCESS_EXITHANDLER(rs232dev_unload()); + + PROCESS_BEGIN(); + + rs232dev_init(); + + SERVICE_REGISTER(slip_drv_service); + + process_poll(&slip_drv_process); + + while(1) { + PROCESS_YIELD(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/6502/net/slip-dsc.c b/cpu/6502/net/slip-dsc.c new file mode 100644 index 000000000..c50349e3e --- /dev/null +++ b/cpu/6502/net/slip-dsc.c @@ -0,0 +1,72 @@ +/* + * 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: slip-dsc.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon slip_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(slip_dsc, + "SLIP driver", + "slip.drv", + slip_init, + &slip_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char slipicon_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 slipicon_textmap[9] = { + 'R', 'S', ' ', + '2', '3', '2', + '/', 'I', 'P' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon slip_icon = + {CTK_ICON("SLIP driver", slipicon_bitmap, slipicon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/6502/net/slip-dump-drv.c b/cpu/6502/net/slip-dump-drv.c new file mode 100644 index 000000000..cd2d3ddf2 --- /dev/null +++ b/cpu/6502/net/slip-dump-drv.c @@ -0,0 +1,120 @@ +/* + * 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 OS + * + * $Id: slip-dump-drv.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + +#include "contiki.h" +#include "rs232dev.h" + +#include "packet-service.h" + +#include "tcpdump.h" +#include +#include "ctk/ctk.h" + +static void output(u8_t *hdr, u16_t hdrlen, u8_t *data, u16_t datalen); + +static const struct packet_service_state state = + { + PACKET_SERVICE_VERSION, + output + }; + +EK_EVENTHANDLER(eventhandler, ev, data); +EK_POLLHANDLER(pollhandler); +EK_PROCESS(proc, PACKET_SERVICE_NAME ": SLIP", EK_PRIO_HIGH, + eventhandler, pollhandler, (void *)&state); + +#define DUMP_WIDTH 38 +#define DUMP_HEIGHT 20 +static struct ctk_window window; +static char dump[DUMP_WIDTH * DUMP_HEIGHT]; +static struct ctk_label dumplabel = + {CTK_LABEL(0, 0, DUMP_WIDTH, DUMP_HEIGHT, dump)}; +static void +dump_packet(void) +{ + memcpy(dump, &dump[DUMP_WIDTH], DUMP_WIDTH * (DUMP_HEIGHT - 1)); + tcpdump_print(&dump[DUMP_WIDTH * (DUMP_HEIGHT - 1)], DUMP_WIDTH); + CTK_WIDGET_REDRAW(&dumplabel); +} +/*---------------------------------------------------------------------------*/ +LOADER_INIT_FUNC(slip_service_init, arg) +{ + arg_free(arg); + ek_service_start(PACKET_SERVICE_NAME, &proc); +} +/*---------------------------------------------------------------------------*/ +static void +output(u8_t *hdr, u16_t hdrlen, u8_t *data, u16_t datalen) +{ + rs232dev_send(); + dump_packet(); +} +/*---------------------------------------------------------------------------*/ +EK_EVENTHANDLER(eventhandler, ev, data) +{ + switch(ev) { + case EK_EVENT_INIT: + case EK_EVENT_REPLACE: + ctk_window_new(&window, DUMP_WIDTH, DUMP_HEIGHT, "SLIP dump"); + CTK_WIDGET_ADD(&window, &dumplabel); + ctk_window_open(&window); + rs232dev_init(); + break; + case EK_EVENT_REQUEST_REPLACE: + ctk_window_close(&window); + ek_replace((struct ek_proc *)data, NULL); + rs232dev_unload(); + LOADER_UNLOAD(); + break; + case EK_EVENT_REQUEST_EXIT: + ctk_window_close(&window); + ek_exit(); + rs232dev_unload(); + LOADER_UNLOAD(); + break; + default: + break; + } +} +/*---------------------------------------------------------------------------*/ +EK_POLLHANDLER(pollhandler) +{ + uip_len = rs232dev_poll(); + if(uip_len > 0) { + dump_packet(); + tcpip_input(); + } + +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/6502/net/uip_arch.c b/cpu/6502/net/uip_arch.c new file mode 100644 index 000000000..d0a17833e --- /dev/null +++ b/cpu/6502/net/uip_arch.c @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2001, 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: uip_arch.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + + +#include "net/uip.h" +#include "net/uip_arch.h" + +#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) +#define IP_PROTO_TCP 6 +#define IP_PROTO_UDP 17 + +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +uip_add32(u8_t *op32, u16_t op16) +{ + asm("ldy #3"); + asm("jsr ldaxysp"); + asm("sta ptr1"); + asm("stx ptr1+1"); + asm("ldy #0"); + asm("lda (sp),y"); + asm("ldy #3"); + asm("clc"); + asm("adc (ptr1),y"); + asm("sta _uip_acc32+3"); + asm("dey"); + asm("lda (ptr1),y"); + asm("ldy #1"); + asm("adc (sp),y"); + asm("sta _uip_acc32+2"); + asm("ldy #1"); + asm("lda (ptr1),y"); + asm("adc #0"); + asm("sta _uip_acc32+1"); + asm("dey"); + asm("lda (ptr1),y"); + asm("adc #0"); + asm("sta _uip_acc32+0"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +static u16_t chksum_ptr, chksum_len, chksum_tmp; +static u8_t chksum_protocol; +static u16_t chksum(void); +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +u16_t +chksum(void) { + + asm("lda #0"); + asm("sta tmp1"); + asm("sta tmp1+1"); + asm("lda _chksum_ptr"); + asm("sta ptr1"); + asm("lda _chksum_ptr+1"); + asm("sta ptr1+1"); + + + asm("lda _chksum_len+1"); + asm("beq chksumlast"); + + + /* If checksum is > 256, do the first runs. */ + asm("ldy #0"); + asm("clc"); + asm("chksumloop_256:"); + asm("lda (ptr1),y"); + asm("adc tmp1"); + asm("sta tmp1"); + asm("iny"); + asm("lda (ptr1),y"); + asm("adc tmp1+1"); + asm("sta tmp1+1"); + asm("iny"); + asm("bne chksumloop_256"); + asm("inc ptr1+1"); + asm("dec _chksum_len+1"); + asm("bne chksumloop_256"); + + asm("chksum_endloop_256:"); + asm("lda tmp1"); + asm("adc #0"); + asm("sta tmp1"); + asm("lda tmp1+1"); + asm("adc #0"); + asm("sta tmp1+1"); + asm("bcs chksum_endloop_256"); + + asm("chksumlast:"); + asm("lda _chksum_len"); + asm("lsr"); + asm("bcc chksum_noodd"); + asm("ldy _chksum_len"); + asm("dey"); + asm("lda (ptr1),y"); + asm("clc"); + asm("adc tmp1"); + asm("sta tmp1"); + asm("bcc noinc1"); + asm("inc tmp1+1"); + asm("bne noinc1"); + asm("inc tmp1"); + asm("noinc1:"); + asm("dec _chksum_len"); + + asm("chksum_noodd:"); + asm("clc"); + asm("php"); + asm("ldy _chksum_len"); + asm("chksum_loop1:"); + asm("cpy #0"); + asm("beq chksum_loop1_end"); + asm("plp"); + asm("dey"); + asm("dey"); + asm("lda (ptr1),y"); + asm("adc tmp1"); + asm("sta tmp1"); + asm("iny"); + asm("lda (ptr1),y"); + asm("adc tmp1+1"); + asm("sta tmp1+1"); + asm("dey"); + asm("php"); + asm("jmp chksum_loop1"); + asm("chksum_loop1_end:"); + asm("plp"); + + asm("chksum_endloop:"); + asm("lda tmp1"); + asm("adc #0"); + asm("sta tmp1"); + asm("lda tmp1+1"); + asm("adc #0"); + asm("sta tmp1+1"); + asm("bcs chksum_endloop"); + + asm("lda tmp1"); + asm("ldx tmp1+1"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +u16_t +uip_chksum(u16_t *buf, u16_t len) +{ + /* unsigned long sum; + + sum = 0; + + chksum_ptr = (u16_t)buf; + while(len >= 256) { + chksum_len = 256; + sum += chksum(); + len -= 256; + chksum_ptr += 256; + } + + if(len < 256) { + chksum_len = len; + sum += chksum(); + } + + while((sum >> 16) != 0) { + sum = (sum >> 16) + (sum & 0xffff); + } + + return sum;*/ + + chksum_len = len; + chksum_ptr = (u16_t)buf; + return chksum(); +} +/*-----------------------------------------------------------------------------------*/ +u16_t +uip_ipchksum(void) +{ + chksum_ptr = (u16_t)uip_buf + UIP_LLH_LEN; + chksum_len = UIP_IPH_LEN; + return chksum(); +} +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static u16_t +transport_chksum(u8_t protocol) +{ + chksum_protocol = protocol; + chksum_ptr = (u16_t)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]; + chksum_len = UIP_TCPH_LEN; + chksum_tmp = chksum(); + + chksum_ptr = (u16_t)uip_appdata; + asm("lda _uip_buf+3+%b", UIP_LLH_LEN); + asm("sec"); + asm("sbc #%b", UIP_IPTCPH_LEN); + asm("sta _chksum_len"); + asm("lda _uip_buf+2+%b", UIP_LLH_LEN); + asm("sbc #0"); + asm("sta _chksum_len+1"); + + asm("jsr %v", chksum); + + asm("clc"); + asm("adc _chksum_tmp"); + asm("sta _chksum_tmp"); + asm("txa"); + asm("adc _chksum_tmp+1"); + asm("sta _chksum_tmp+1"); + + /* Fold carry */ + /* asm("bcc noinc"); + asm("inc _chksum_tmp"); + asm("noinc:");*/ + + asm("tcpchksum_loop1:"); + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #0"); + asm("sta _chksum_tmp+1"); + asm("bcs tcpchksum_loop1"); + + + asm("lda _uip_buf+3+%b", UIP_LLH_LEN); + asm("sec"); + asm("sbc #%b", UIP_IPH_LEN); + asm("sta _chksum_len"); + asm("lda _uip_buf+2+%b", UIP_LLH_LEN); + asm("sbc #0"); + asm("sta _chksum_len+1"); + + + asm("ldy #$0c"); + asm("clc"); + asm("php"); + asm("tcpchksum_loop2:"); + asm("plp"); + asm("lda _uip_buf+%b,y", UIP_LLH_LEN); + asm("adc _chksum_tmp"); + asm("sta _chksum_tmp"); + asm("iny"); + asm("lda _uip_buf+%b,y", UIP_LLH_LEN); + asm("adc _chksum_tmp+1"); + asm("sta _chksum_tmp+1"); + asm("iny"); + asm("php"); + asm("cpy #$14"); + asm("bne tcpchksum_loop2"); + + asm("plp"); + + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc %v", chksum_protocol); + asm("sta _chksum_tmp+1"); + + + asm("lda _chksum_tmp"); + asm("adc _chksum_len+1"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc _chksum_len"); + asm("sta _chksum_tmp+1"); + + + + asm("tcpchksum_loop3:"); + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #0"); + asm("sta _chksum_tmp+1"); + asm("bcs tcpchksum_loop3"); + + + return chksum_tmp; +} +#pragma optimize(pop) + +/*-----------------------------------------------------------------------------------*/ +u16_t +uip_tcpchksum(void) +{ + return transport_chksum(IP_PROTO_TCP); +#if 0 + chksum_ptr = (u16_t)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN]; + chksum_len = UIP_TCPH_LEN; + chksum_tmp = chksum(); + + chksum_ptr = (u16_t)uip_appdata; + asm("lda _uip_buf+3+%b", UIP_LLH_LEN); + asm("sec"); + asm("sbc #%b", UIP_IPTCPH_LEN); + asm("sta _chksum_len"); + asm("lda _uip_buf+2+%b", UIP_LLH_LEN); + asm("sbc #0"); + asm("sta _chksum_len+1"); + + asm("jsr %v", chksum); + + asm("clc"); + asm("adc _chksum_tmp"); + asm("sta _chksum_tmp"); + asm("txa"); + asm("adc _chksum_tmp+1"); + asm("sta _chksum_tmp+1"); + + /* Fold carry */ + /* asm("bcc noinc"); + asm("inc _chksum_tmp"); + asm("noinc:");*/ + + asm("tcpchksum_loop1:"); + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #0"); + asm("sta _chksum_tmp+1"); + asm("bcs tcpchksum_loop1"); + + + asm("lda _uip_buf+3+%b", UIP_LLH_LEN); + asm("sec"); + asm("sbc #%b", UIP_IPH_LEN); + asm("sta _chksum_len"); + asm("lda _uip_buf+2+%b", UIP_LLH_LEN); + asm("sbc #0"); + asm("sta _chksum_len+1"); + + + asm("ldy #$0c"); + asm("clc"); + asm("php"); + asm("tcpchksum_loop2:"); + asm("plp"); + asm("lda _uip_buf+%b,y", UIP_LLH_LEN); + asm("adc _chksum_tmp"); + asm("sta _chksum_tmp"); + asm("iny"); + asm("lda _uip_buf+%b,y", UIP_LLH_LEN); + asm("adc _chksum_tmp+1"); + asm("sta _chksum_tmp+1"); + asm("iny"); + asm("php"); + asm("cpy #$14"); + asm("bne tcpchksum_loop2"); + + asm("plp"); + + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #6"); /* IP_PROTO_TCP */ + asm("sta _chksum_tmp+1"); + + + asm("lda _chksum_tmp"); + asm("adc _chksum_len+1"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc _chksum_len"); + asm("sta _chksum_tmp+1"); + + + + asm("tcpchksum_loop3:"); + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #0"); + asm("sta _chksum_tmp+1"); + asm("bcs tcpchksum_loop3"); + + + return chksum_tmp; +#endif +} + +/*-----------------------------------------------------------------------------------*/ +#if UIP_UDP_CHECKSUMS +u16_t +uip_udpchksum(void) +{ + return transport_chksum(IP_PROTO_UDP); +#if 0 + chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN]; + chksum_len = 20; + chksum_tmp = chksum(); + + chksum_ptr = (u16_t)uip_appdata; + asm("lda _uip_buf+3+%b", UIP_LLH_LEN); + asm("sec"); + asm("sbc #40"); + asm("sta _chksum_len"); + asm("lda _uip_buf+2+%b", UIP_LLH_LEN); + asm("sbc #0"); + asm("sta _chksum_len+1"); + + asm("jsr %v", chksum); + + asm("clc"); + asm("adc _chksum_tmp"); + asm("sta _chksum_tmp"); + asm("txa"); + asm("adc _chksum_tmp+1"); + asm("sta _chksum_tmp+1"); + + /* Fold carry */ + /* asm("bcc noinc"); + asm("inc _chksum_tmp"); + asm("noinc:");*/ + + asm("tcpchksum_loop1:"); + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #0"); + asm("sta _chksum_tmp+1"); + asm("bcs tcpchksum_loop1"); + + + asm("lda _uip_buf+3+%b", UIP_LLH_LEN); + asm("sec"); + asm("sbc #20"); + asm("sta _chksum_len"); + asm("lda _uip_buf+2+%b", UIP_LLH_LEN); + asm("sbc #0"); + asm("sta _chksum_len+1"); + + + asm("ldy #$0c"); + asm("clc"); + asm("php"); + asm("tcpchksum_loop2:"); + asm("plp"); + asm("lda _uip_buf+%b,y", UIP_LLH_LEN); + asm("adc _chksum_tmp"); + asm("sta _chksum_tmp"); + asm("iny"); + asm("lda _uip_buf+%b,y", UIP_LLH_LEN); + asm("adc _chksum_tmp+1"); + asm("sta _chksum_tmp+1"); + asm("iny"); + asm("php"); + asm("cpy #$14"); + asm("bne tcpchksum_loop2"); + + asm("plp"); + + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #17"); /* IP_PROTO_UDP */ + asm("sta _chksum_tmp+1"); + + + asm("lda _chksum_tmp"); + asm("adc _chksum_len+1"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc _chksum_len"); + asm("sta _chksum_tmp+1"); + + + + asm("tcpchksum_loop3:"); + asm("lda _chksum_tmp"); + asm("adc #0"); + asm("sta _chksum_tmp"); + asm("lda _chksum_tmp+1"); + asm("adc #0"); + asm("sta _chksum_tmp+1"); + asm("bcs tcpchksum_loop3"); + + + return chksum_tmp; +#endif +} +#endif /* UIP_UDP_CHECKSUMS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/6502/net/uip_arch.h b/cpu/6502/net/uip_arch.h new file mode 100644 index 000000000..8e8c944c6 --- /dev/null +++ b/cpu/6502/net/uip_arch.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2001, 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: uip_arch.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + +#ifndef __UIP_ARCH_H__ +#define __UIP_ARCH_H__ + +#include "net/uip.h" + +void uip_add_rcv_nxt(u16_t n); +void uip_add32(u8_t *op32, u16_t op16); + +u16_t uip_chksum(u16_t *data, u16_t len); +u16_t uip_ipchksum(void); +u16_t uip_tcpchksum(void); + +#endif /* __UIP_ARCH_H__ */ diff --git a/cpu/avr/dev/clock.c b/cpu/avr/dev/clock.c new file mode 100644 index 000000000..e5f9bc13a --- /dev/null +++ b/cpu/avr/dev/clock.c @@ -0,0 +1,54 @@ + +#include "sys/clock.h" +#include "sys/etimer.h" + +#include +#include + +// Hack to see if this sets the blue led... +/* #include "hal_emwinet_demoboard.h" */ + +static unsigned short count; + + +/*---------------------------------------------------------------------------*/ +SIGNAL(SIG_OUTPUT_COMPARE0) +{ +/* if ((count % 10) > 5) SET_BLUE_LED(); */ +/* else CLEAR_BLUE_LED(); */ + + ++count; + if(etimer_pending()) { + etimer_request_poll(); + } +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ +#if 0 +#if __AVR_ENHANCED__ + outp(_BV(CS00) | _BV(CS02) | _BV(WGM01), TCCR0); +#else + outp(_BV(CS00) | _BV(CS02) | _BV(CTC0), TCCR0); +#endif + outp(0, TCNT0); + outp((NUT_CPU_FREQ / (128L * CLOCK_CONF_SECOND) + 0.5/*round*/), OCR0); + sbi(TIMSK, OCIE0); +#endif /* 0 */ + + + TCCR0 = _BV(CS00) | _BV(CS02) | _BV(WGM01); + TCNT0 = 0; + /* OCR0 = AVR_CLK_COUNT;*/ + TIMSK |= _BV(OCIE0); + + count = 0; +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + return count; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/avr/dev/compiler.h b/cpu/avr/dev/compiler.h new file mode 100644 index 000000000..5625752e8 --- /dev/null +++ b/cpu/avr/dev/compiler.h @@ -0,0 +1,39 @@ +#ifndef __COMPILER_H__ +#define __COMPILER_H__ + +#ifdef __IMAGECRAFT__ + + +// choose your AVR device here +#include + +#include + +#define outp(val, reg) (reg = val) +#define inp(reg) (reg) + +#define cli() CLI() +#define sei() SEI() +#define cbi(reg, bit) (reg &= ~BIT(bit)) +#define sbi(reg, bit) (reg |= BIT(bit)) + +#define SIGNAL(x) void x(void) + +#define nop() NOP() + + +#else /* --- GCC --- */ +#ifndef __AVR_ATmega128__ +#define __AVR_ATmega128__ +#endif +#include +#include +#include + +#define nop() asm volatile("nop\n\t"::); + +#endif /* Compiler Used */ + + + +#endif /* __COMPILER_H__ */ diff --git a/cpu/avr/dev/debug.c b/cpu/avr/dev/debug.c new file mode 100644 index 000000000..9e4fec4e7 --- /dev/null +++ b/cpu/avr/dev/debug.c @@ -0,0 +1,72 @@ + +#include "compiler.h" +#include "delay.h" + +#include + +/*-----------------------------------------------------------------------------------*/ +static void +delay(void) +{ + unsigned char i; + for(i = 0; i < 1; ++i) { + Delay_10ms(1); + } +} +/*-----------------------------------------------------------------------------------*/ +static char buffer[40]; +static prog_char hextab[] = + {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'}; +/*-----------------------------------------------------------------------------------*/ +static void +print_buffer(unsigned char len) +{ + unsigned char i; + + for(i = 0; i < len; ++i) { + delay(); + UDR0 = buffer[i]; + } +} +/*-----------------------------------------------------------------------------------*/ +void +debug_print8(unsigned char v) +{ + /* buffer[0] = v / 100 + '0'; + buffer[1] = (v / 10) % 10 + '0'; + buffer[2] = v % 10 + '0'; + buffer[3] = ' '; + buffer[4] = PRG_RDB(hextab + (v >> 4)); + buffer[5] = PRG_RDB(hextab + (v & 0x0f)); + buffer[6] = '\n'; + print_buffer(7);*/ +} +/*-----------------------------------------------------------------------------------*/ +void +debug_print16(unsigned short v) +{ + /* buffer[0] = v / 10000 + '0'; + buffer[1] = (v / 1000) % 10 + '0'; + buffer[2] = (v / 100) % 10 + '0'; + buffer[3] = (v / 10) % 10 + '0'; + buffer[4] = v % 10 + '0'; + buffer[5] = ' '; + buffer[6] = PRG_RDB(hextab + ((v & 0xf000) >> 12)); + buffer[7] = PRG_RDB(hextab + ((v & 0x0f00) >> 8)); + buffer[8] = PRG_RDB(hextab + ((v & 0xf0) >> 4)); + buffer[9] = PRG_RDB(hextab + (v & 0x0f)); + buffer[10] = '\n'; + print_buffer(11);*/ +} +/*-----------------------------------------------------------------------------------*/ +void +debug_print(prog_char *str) +{ + /* unsigned char i; + + for(i = 0; PRG_RDB(str + i) != 0; ++i) { + buffer[i] = PRG_RDB(str + i); + } + print_buffer(i);*/ +} +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/avr/dev/debug.h b/cpu/avr/dev/debug.h new file mode 100644 index 000000000..ec38942b1 --- /dev/null +++ b/cpu/avr/dev/debug.h @@ -0,0 +1,20 @@ +#ifndef __DEBUG_H__ +#define __DEBUG_H__ + +#if 0 +#define debug_print(x) +#define debug_print8(x) + +#else + +#include "avr/pgmspace.h" + +void debug_print(char *str); + +void debug_print8(unsigned char v); +void debug_print16(unsigned short v); +#endif + + + +#endif /* __DEBUG_H__ */ diff --git a/cpu/avr/dev/delay.c b/cpu/avr/dev/delay.c new file mode 100644 index 000000000..01cc3e4e2 --- /dev/null +++ b/cpu/avr/dev/delay.c @@ -0,0 +1,29 @@ +#include "delay.h" + +//---------------------------------------------------------------------------- +// Wait for a specific time in 100 uSec +// (15 + t*( ((K_DELAY_100us-1)*6)+5 )) +//---------------------------------------------------------------------------- +void Delay_100us(unsigned char t) { + unsigned int i; + if (t==0) return; + while (t--) for(i=0;i + * + * $Id: eeprom.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include "eeprom.h" + +#include +#include + +/*---------------------------------------------------------------------------*/ +void +eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size) +{ + while(!eeprom_is_ready()); + eeprom_write_block(buf, (unsigned short *)addr, size); +} +/*---------------------------------------------------------------------------*/ +void +eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size) +{ + while(!eeprom_is_ready()); + eeprom_read_block(buf, (unsigned short *)addr, size); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/avr/dev/flash.c b/cpu/avr/dev/flash.c new file mode 100644 index 000000000..cb5699167 --- /dev/null +++ b/cpu/avr/dev/flash.c @@ -0,0 +1,50 @@ + +#include "dev/flash.h" + +#include +#include +#include +#include + +/*---------------------------------------------------------------------------*/ +/* + * The following code was taken from the avr-libc manual: + */ +void +flash_write_page(uint32_t page, uint8_t *buf) +{ + uint16_t i; + uint8_t sreg; + + /* Disable interrupts. */ + + sreg = SREG; + cli(); + + eeprom_busy_wait(); + + boot_page_erase(page); + boot_spm_busy_wait(); /* Wait until the memory is erased. */ + + for(i = 0; i < SPM_PAGESIZE; i += 2) { + /* Set up little-endian word. */ + + uint16_t w = *buf++; + w += (*buf++) << 8; + + boot_page_fill(page + i, w); + } + + boot_page_write(page); /* Store buffer in flash page. */ + boot_spm_busy_wait(); /* Wait until the memory is written. */ + + /* Reenable RWW-section again. We need this if we want to jump back + * to the application after bootloading. */ + + boot_rww_enable(); + + /* Re-enable interrupts (if they were ever enabled). */ + + SREG = sreg; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/avr/dev/flash.h b/cpu/avr/dev/flash.h new file mode 100644 index 000000000..9e084d250 --- /dev/null +++ b/cpu/avr/dev/flash.h @@ -0,0 +1,8 @@ +#ifndef __FLASH_H__ +#define __FLASH_H__ + +#include + +void flash_write_page(uint32_t page, uint8_t *buf); + +#endif /* __FLASH_H__ */ diff --git a/cpu/avr/dev/lanc111.c b/cpu/avr/dev/lanc111.c new file mode 100644 index 000000000..fd372706a --- /dev/null +++ b/cpu/avr/dev/lanc111.c @@ -0,0 +1,1362 @@ +#define INLINE +#define CONST const +#define NETBUF char +/* + * Copyright (C) 2003-2005 by egnite Software GmbH. 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 copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + * + */ + +/* + * $Log: lanc111.c,v $ + * Revision 1.1 2006/06/17 22:41:21 adamdunkels + * Import of the contiki-2.x development code from the SICS internal CVS server + * + * Revision 1.1 2005/09/19 23:05:34 adam + * AVR device drivers + * + * Revision 1.1 2005/05/19 09:06:25 adam + * Very initial version of the LANC111 Ethernet driver, imported from Nut/OS code - does not work yet + * + * Revision 1.12 2005/02/02 19:55:34 haraldkipp + * If no Ethernet link was available on the LAN91C111, each outgoing packet + * took 15 seconds and, even worse, the ouput routine doesn't return an error. + * Now the first attempt to send a packet without Ethernet link will wait for + * 5 seconds and subsequent attempts take 0.5 seconds only, always returning + * an error. + * + * Revision 1.11 2005/01/24 21:11:49 freckle + * renamed NutEventPostFromIRQ into NutEventPostFromIrq + * + * Revision 1.10 2005/01/22 19:24:11 haraldkipp + * Changed AVR port configuration names from PORTx to AVRPORTx. + * + * Revision 1.9 2005/01/21 16:49:45 freckle + * Seperated calls to NutEventPostAsync between Threads and IRQs + * + * Revision 1.8 2004/09/22 08:14:48 haraldkipp + * Made configurable + * + * Revision 1.7 2004/03/08 11:14:17 haraldkipp + * Added quick hack for fixed mode. + * + * Revision 1.6 2004/02/25 16:22:33 haraldkipp + * Do not initialize MAC with all zeros + * + * Revision 1.5 2004/01/14 19:31:43 drsung + * Speed improvement to NicWrite applied. Thanks to Kolja Waschk + * + * Revision 1.4 2003/11/06 09:26:50 haraldkipp + * Removed silly line with hardcoded MAC, left over from testing + * + * Revision 1.3 2003/11/04 17:54:47 haraldkipp + * PHY configuration timing changed again for reliable linking + * + * Revision 1.2 2003/11/03 17:12:53 haraldkipp + * Allow linking with RTL8019 driver. + * Links more reliable to 10 MBit networks now. + * Reset MMU on allocation failures. + * Some optimizations. + * + * Revision 1.1 2003/10/13 10:13:49 haraldkipp + * First release + * + */ + +#include "contiki.h" + +#include + +#include + +/* + * Determine ports, which had not been explicitely configured. + */ +#ifndef LANC111_BASE_ADDR +#define LANC111_BASE_ADDR 0xC000 +#endif + +#ifndef LANC111_SIGNAL_IRQ +#define LANC111_SIGNAL_IRQ INT5 +#endif + +#ifdef LANC111_RESET_BIT + +#if (LANC111_RESET_AVRPORT == AVRPORTB) +#define LANC111_RESET_PORT PORTB +#define LANC111_RESET_DDR DDRB + +#elif (LANC111_RESET_AVRPORT == AVRPORTD) +#define LANC111_RESET_PORT PORTD +#define LANC111_RESET_DDR DDRD + +#elif (LANC111_RESET_AVRPORT == AVRPORTE) +#define LANC111_RESET_PORT PORTE +#define LANC111_RESET_DDR DDRE + +#elif (LANC111_RESET_AVRPORT == AVRPORTF) +#define LANC111_RESET_PORT PORTF +#define LANC111_RESET_DDR DDRF + +#endif /* LANC111_RESET_AVRPORT */ + +#endif /* LANC111_RESET_BIT */ + +/* + * Determine interrupt settings. + */ +#if (LANC111_SIGNAL_IRQ == INT0) +#define LANC111_SIGNAL sig_INTERRUPT0 +#define LANC111_SIGNAL_MODE() sbi(EICRA, ISC00); sbi(EICRA, ISC01) + +#elif (LANC111_SIGNAL_IRQ == INT1) +#define LANC111_SIGNAL sig_INTERRUPT1 +#define LANC111_SIGNAL_MODE() sbi(EICRA, ISC10); sbi(EICRA, ISC11) + +#elif (LANC111_SIGNAL_IRQ == INT2) +#define LANC111_SIGNAL sig_INTERRUPT2 +#define LANC111_SIGNAL_MODE() sbi(EICRA, ISC20); sbi(EICRA, ISC21) + +#elif (LANC111_SIGNAL_IRQ == INT3) +#define LANC111_SIGNAL sig_INTERRUPT3 +#define LANC111_SIGNAL_MODE() sbi(EICRA, ISC30); sbi(EICRA, ISC31) + +#elif (LANC111_SIGNAL_IRQ == INT4) +#define LANC111_SIGNAL sig_INTERRUPT4 +#define LANC111_SIGNAL_MODE() sbi(EICRB, ISC40); sbi(EICRB, ISC41) + +#elif (LANC111_SIGNAL_IRQ == INT6) +#define LANC111_SIGNAL sig_INTERRUPT6 +#define LANC111_SIGNAL_MODE() sbi(EICRB, ISC60); sbi(EICRB, ISC61) + +#elif (LANC111_SIGNAL_IRQ == INT7) +#define LANC111_SIGNAL sig_INTERRUPT7 +#define LANC111_SIGNAL_MODE() sbi(EICRB, ISC70); sbi(EICRB, ISC71) + +#else +#define LANC111_SIGNAL sig_INTERRUPT5 +#define LANC111_SIGNAL_MODE() sbi(EICRB, ISC50); sbi(EICRB, ISC51) + +#endif + +/*! + * \addtogroup xgSmscRegs + */ +/*@{*/ + +/*! + * \brief Bank select register. + */ +#define NIC_BSR (LANC111_BASE_ADDR + 0x0E) + +/*! + * \brief Bank 0 - Transmit control register. + */ +#define NIC_TCR (LANC111_BASE_ADDR + 0x00) + +#define TCR_SWFDUP 0x8000 /*!< \ref NIC_TCR bit mask, enables full duplex. */ +#define TCR_EPH_LOOP 0x2000 /*!< \ref NIC_TCR bit mask, enables internal loopback. */ +#define TCR_STP_SQET 0x1000 /*!< \ref NIC_TCR bit mask, enables transmission stop on SQET error. */ +#define TCR_FDUPLX 0x0800 /*!< \ref NIC_TCR bit mask, enables receiving own frames. */ +#define TCR_MON_CSN 0x0400 /*!< \ref NIC_TCR bit mask, enables carrier monitoring. */ +#define TCR_NOCRC 0x0100 /*!< \ref NIC_TCR bit mask, disables CRC transmission. */ +#define TCR_PAD_EN 0x0080 /*!< \ref NIC_TCR bit mask, enables automatic padding. */ +#define TCR_FORCOL 0x0004 /*!< \ref NIC_TCR bit mask, forces collision. */ +#define TCR_LOOP 0x0002 /*!< \ref NIC_TCR bit mask, enables PHY loopback. */ +#define TCR_TXENA 0x0001 /*!< \ref NIC_TCR bit mask, enables transmitter. */ + + +/*! + * \brief Bank 0 - EPH status register. + */ +#define NIC_EPHSR (LANC111_BASE_ADDR + 0x02) + +/*! + * \brief Bank 0 - Receive control register. + */ +#define NIC_RCR (LANC111_BASE_ADDR + 0x04) + +#define RCR_SOFT_RST 0x8000 /*!< \ref NIC_RCR bit mask, activates software reset. */ +#define RCR_FILT_CAR 0x4000 /*!< \ref NIC_RCR bit mask, enables carrier filter. */ +#define RCR_ABORT_ENB 0x2000 /*!< \ref NIC_RCR bit mask, enables receive abort on collision. */ +#define RCR_STRIP_CRC 0x0200 /*!< \ref NIC_RCR bit mask, strips CRC. */ +#define RCR_RXEN 0x0100 /*!< \ref NIC_RCR bit mask, enables receiver. */ +#define RCR_ALMUL 0x0004 /*!< \ref NIC_RCR bit mask, multicast frames accepted when set. */ +#define RCR_PRMS 0x0002 /*!< \ref NIC_RCR bit mask, enables promiscuous mode. */ +#define RCR_RX_ABORT 0x0001 /*!< \ref NIC_RCR bit mask, set when receive was aborted. */ + +/*! + * \brief Bank 0 - Counter register. + */ +#define NIC_ECR (LANC111_BASE_ADDR + 0x06) + +/*! + * \brief Bank 0 - Memory information register. + */ +#define NIC_MIR (LANC111_BASE_ADDR + 0x08) + +/*! + * \brief Bank 0 - Receive / PHY control register. + */ +#define NIC_RPCR (LANC111_BASE_ADDR + 0x0A) + +#define RPCR_SPEED 0x2000 /*!< \ref NIC_RPCR bit mask, PHY operates at 100 Mbps. */ +#define RPCR_DPLX 0x1000 /*!< \ref NIC_RPCR bit mask, PHY operates at full duplex mode. */ +#define RPCR_ANEG 0x0800 /*!< \ref NIC_RPCR bit mask, sets PHY in auto-negotiation mode. */ +#define RPCR_LEDA_PAT 0x0000 /*!< \ref NIC_RPCR bit mask for LEDA mode. */ +#define RPCR_LEDB_PAT 0x0010 /*!< \ref NIC_RPCR bit mask for LEDB mode. */ + +/*! + * \brief Bank 1 - Configuration register. + */ +#define NIC_CR (LANC111_BASE_ADDR + 0x00) + +#define CR_EPH_EN 0x8000 /*!< \ref NIC_CR bit mask, . */ + +/*! + * \brief Bank 1 - Base address register. + */ +#define NIC_BAR (LANC111_BASE_ADDR + 0x02) + +/*! + * \brief Bank 1 - Individual address register. + */ +#define NIC_IAR (LANC111_BASE_ADDR + 0x04) + +/*! + * \brief Bank 1 - General purpose register. + */ +#define NIC_GPR (LANC111_BASE_ADDR + 0x0A) + +/*! + * \brief Bank 1 - Control register. + */ +#define NIC_CTR (LANC111_BASE_ADDR + 0x0C) + +#define CTR_RCV_BAD 0x4000 /*!< \ref NIC_CTR bit mask. */ +#define CTR_AUTO_RELEASE 0x0800 /*!< \ref NIC_CTR bit mask, transmit packets automatically released. */ + +/*! + * \brief Bank 2 - MMU command register. + */ +#define NIC_MMUCR (LANC111_BASE_ADDR + 0x00) + +#define MMUCR_BUSY 0x0001 + +#define MMU_NOP 0 +#define MMU_ALO (1<<5) +#define MMU_RST (2<<5) +#define MMU_REM (3<<5) +#define MMU_TOP (4<<5) +#define MMU_PKT (5<<5) +#define MMU_ENQ (6<<5) +#define MMU_RTX (7<<5) + +/*! + * \brief Bank 2 - Packet number register. + * + * This byte register specifies the accessible transmit packet number. + */ +#define NIC_PNR (LANC111_BASE_ADDR + 0x02) + +/*! + * \brief Bank 2 - Allocation result register. + * + * This byte register is updated upon a \ref MMU_ALO command. + */ +#define NIC_ARR (LANC111_BASE_ADDR + 0x03) + +#define ARR_FAILED 0x80 + +/*! + * \brief Bank 2 - FIFO ports register. + */ +#define NIC_FIFO (LANC111_BASE_ADDR + 0x04) + +/*! + * \brief Bank 2 - Pointer register. + */ +#define NIC_PTR (LANC111_BASE_ADDR + 0x06) + +#define PTR_RCV 0x8000 /*! \ref NIC_PTR bit mask, specifies receive or transmit buffer. */ +#define PTR_AUTO_INCR 0x4000 /*! \ref NIC_PTR bit mask, enables automatic pointer increment. */ +#define PTR_READ 0x2000 /*! \ref NIC_PTR bit mask, indicates type of access. */ +#define PTR_ETEN 0x1000 /*! \ref NIC_PTR bit mask, enables early transmit underrun detection. */ +#define PTR_NOT_EMPTY 0x0800 /*! \ref NIC_PTR bit mask, set when write data fifo is not empty. */ + +/*! + * \brief Bank 2 - Data register. + */ +#define NIC_DATA (LANC111_BASE_ADDR + 0x08) + +/*! + * \brief Bank 2 - Interrupt status register. + */ +#define NIC_IST (LANC111_BASE_ADDR + 0x0C) + +/*! + * \brief Bank 2 - Interrupt acknowledge register. + */ +#define NIC_ACK (LANC111_BASE_ADDR + 0x0C) + +/*! + * \brief Bank 2 - Interrupt mask register. + */ +#define NIC_MSK (LANC111_BASE_ADDR + 0x0D) + +#define INT_MD 0x80 /*!< \ref PHY state change interrupt bit mask. */ +#define INT_ERCV 0x40 /*!< \ref Early receive interrupt bit mask. */ +#define INT_EPH 0x20 /*!< \ref Ethernet protocol interrupt bit mask. */ +#define INT_RX_OVRN 0x10 /*!< \ref Receive overrun interrupt bit mask. */ +#define INT_ALLOC 0x08 /*!< \ref Transmit allocation interrupt bit mask. */ +#define INT_TX_EMPTY 0x04 /*!< \ref Transmitter empty interrupt bit mask. */ +#define INT_TX 0x02 /*!< \ref Transmit complete interrupt bit mask. */ +#define INT_RCV 0x01 /*!< \ref Receive interrupt bit mask. */ + +/*! + * \brief Bank 3 - Multicast table register. + */ +#define NIC_MT (LANC111_BASE_ADDR + 0x00) + +/*! + * \brief Bank 3 - Management interface register. + */ +#define NIC_MGMT (LANC111_BASE_ADDR + 0x08) + +#define MGMT_MDOE 0x08 /*!< \ref NIC_MGMT bit mask, enables MDO pin. */ +#define MGMT_MCLK 0x04 /*!< \ref NIC_MGMT bit mask, drives MDCLK pin. */ +#define MGMT_MDI 0x02 /*!< \ref NIC_MGMT bit mask, reflects MDI pin status. */ +#define MGMT_MDO 0x01 /*!< \ref NIC_MGMT bit mask, drives MDO pin. */ + +/*! + * \brief Bank 3 - Revision register. + */ +#define NIC_REV (LANC111_BASE_ADDR + 0x0A) + +/*! + * \brief Bank 3 - Early RCV register. + */ +#define NIC_ERCV (LANC111_BASE_ADDR + 0x0C) + +/*! + * \brief PHY control register. + */ +#define NIC_PHYCR 0 + +#define PHYCR_RST 0x8000 /*!< \ref NIC_PHYCR bit mask, resets PHY. */ +#define PHYCR_LPBK 0x4000 /*!< \ref NIC_PHYCR bit mask, . */ +#define PHYCR_SPEED 0x2000 /*!< \ref NIC_PHYCR bit mask, . */ +#define PHYCR_ANEG_EN 0x1000 /*!< \ref NIC_PHYCR bit mask, . */ +#define PHYCR_PDN 0x0800 /*!< \ref NIC_PHYCR bit mask, . */ +#define PHYCR_MII_DIS 0x0400 /*!< \ref NIC_PHYCR bit mask, . */ +#define PHYCR_ANEG_RST 0x0200 /*!< \ref NIC_PHYCR bit mask, . */ +#define PHYCR_DPLX 0x0100 /*!< \ref NIC_PHYCR bit mask, . */ +#define PHYCR_COLST 0x0080 /*!< \ref NIC_PHYCR bit mask, . */ + + +/*! + * \brief PHY status register. + */ +#define NIC_PHYSR 1 + +#define PHYSR_CAP_T4 0x8000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-T4 capability. */ +#define PHYSR_CAP_TXF 0x4000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX full duplex capability. */ +#define PHYSR_CAP_TXH 0x2000 /*!< \ref NIC_PHYSR bit mask, indicates 100BASE-TX half duplex capability. */ +#define PHYSR_CAP_TF 0x1000 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T full duplex capability. */ +#define PHYSR_CAP_TH 0x0800 /*!< \ref NIC_PHYSR bit mask, indicates 10BASE-T half duplex capability. */ +#define PHYSR_CAP_SUPR 0x0040 /*!< \ref NIC_PHYSR bit mask, indicates preamble suppression capability. */ +#define PHYSR_ANEG_ACK 0x0020 /*!< \ref NIC_PHYSR bit mask, auto-negotiation completed. */ +#define PHYSR_REM_FLT 0x0010 /*!< \ref NIC_PHYSR bit mask, remote fault detected. */ +#define PHYSR_CAP_ANEG 0x0008 /*!< \ref NIC_PHYSR bit mask, indicates auto-negotiation capability. */ +#define PHYSR_LINK 0x0004 /*!< \ref NIC_PHYSR bit mask, valid link status. */ +#define PHYSR_JAB 0x0002 /*!< \ref NIC_PHYSR bit mask, jabber collision detected. */ +#define PHYSR_EXREG 0x0001 /*!< \ref NIC_PHYSR bit mask, extended capabilities available. */ + + +/*! + * \brief PHY identifier register 1. + */ +#define NIC_PHYID1 2 + +/*! + * \brief PHY identifier register 1. + */ +#define NIC_PHYID2 3 + +/*! + * \brief PHY auto-negotiation advertisement register. + */ +#define NIC_PHYANAD 4 + +#define PHYANAD_NP 0x8000 /*!< \ref NIC_PHYANAD bit mask, exchanging next page information. */ +#define PHYANAD_ACK 0x4000 /*!< \ref NIC_PHYANAD bit mask, acknowledged. */ +#define PHYANAD_RF 0x2000 /*!< \ref NIC_PHYANAD bit mask, remote fault. */ +#define PHYANAD_T4 0x0200 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-T4 capability. */ +#define PHYANAD_TX_FDX 0x0100 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX full duplex capability. */ +#define PHYANAD_TX_HDX 0x0080 /*!< \ref NIC_PHYANAD bit mask, indicates 100BASE-TX half duplex capability. */ +#define PHYANAD_10FDX 0x0040 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T full duplex capability. */ +#define PHYANAD_10_HDX 0x0020 /*!< \ref NIC_PHYANAD bit mask, indicates 10BASE-T half duplex capability. */ +#define PHYANAD_CSMA 0x0001 /*!< \ref NIC_PHYANAD bit mask, indicates 802.3 CSMA capability. */ + +/*! + * \brief PHY auto-negotiation remote end capability register. + */ +#define NIC_PHYANRC 5 + +/*! + * \brief PHY configuration register 1. + */ +#define NIC_PHYCFR1 16 + +/*! + * \brief PHY configuration register 2. + */ +#define NIC_PHYCFR2 17 + +/*! + * \brief PHY status output register. + */ +#define NIC_PHYSOR 18 + +#define PHYSOR_INT 0x8000 /*!< \ref NIC_PHYSOR bit mask, interrupt bits changed. */ +#define PHYSOR_LNKFAIL 0x4000 /*!< \ref NIC_PHYSOR bit mask, link failure detected. */ +#define PHYSOR_LOSSSYNC 0x2000 /*!< \ref NIC_PHYSOR bit mask, descrambler sync lost detected. */ +#define PHYSOR_CWRD 0x1000 /*!< \ref NIC_PHYSOR bit mask, code word error detected. */ +#define PHYSOR_SSD 0x0800 /*!< \ref NIC_PHYSOR bit mask, start of stream error detected. */ +#define PHYSOR_ESD 0x0400 /*!< \ref NIC_PHYSOR bit mask, end of stream error detected. */ +#define PHYSOR_RPOL 0x0200 /*!< \ref NIC_PHYSOR bit mask, reverse polarity detected. */ +#define PHYSOR_JAB 0x0100 /*!< \ref NIC_PHYSOR bit mask, jabber detected. */ +#define PHYSOR_SPDDET 0x0080 /*!< \ref NIC_PHYSOR bit mask, 100/10 speed detected. */ +#define PHYSOR_DPLXDET 0x0040 /*!< \ref NIC_PHYSOR bit mask, duplex detected. */ + +/*! + * \brief PHY mask register. + */ +#define NIC_PHYMSK 19 + +#define PHYMSK_MINT 0x8000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_INT interrupt. */ +#define PHYMSK_MLNKFAIL 0x4000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LNKFAIL interrupt. */ +#define PHYMSK_MLOSSSYN 0x2000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_LOSSSYNC interrupt. */ +#define PHYMSK_MCWRD 0x1000 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_CWRD interrupt. */ +#define PHYMSK_MSSD 0x0800 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SSD interrupt. */ +#define PHYMSK_MESD 0x0400 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_ESD interrupt. */ +#define PHYMSK_MRPOL 0x0200 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_RPOL interrupt. */ +#define PHYMSK_MJAB 0x0100 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_JAB interrupt. */ +#define PHYMSK_MSPDDT 0x0080 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_SPDDET interrupt. */ +#define PHYMSK_MDPLDT 0x0040 /*!< \ref NIC_PHYMSK bit mask, enables \ref PHYSOR_DPLXDET interrupt. */ + + + +#define MSBV(bit) (1 << ((bit) - 8)) + +#define nic_outlb(addr, val) (*(volatile u8_t *)(addr) = (val)) +#define nic_outhb(addr, val) (*(volatile u8_t *)((addr) + 1) = (val)) +#define nic_outwx(addr, val) (*(volatile u16_t *)(addr) = (val)) +#define nic_outw(addr, val) { \ + *(volatile u8_t *)(addr) = (u8_t)(val); \ + *((volatile u8_t *)(addr) + 1) = (u8_t)((val) >> 8); \ +} + +#define nic_inlb(addr) (*(volatile u8_t *)(addr)) +#define nic_inhb(addr) (*(volatile u8_t *)((addr) + 1)) +#define nic_inw(addr) (*(volatile u16_t *)(addr)) + +#define nic_bs(bank) nic_outlb(NIC_BSR, bank) + +/*! + * \struct _NICINFO lanc111.h dev/lanc111.h + * \brief Network interface controller information structure. + */ +/*@}*/ + +/*! + * \addtogroup xgNicLanc111 + */ +/*@{*/ + + + +/*! + * \brief Select specified PHY register for reading or writing. + * + * \note NIC interrupts must have been disabled before calling this routine. + * + * \param reg PHY register number. + * \param we Indicates type of access, 1 for write and 0 for read. + * + * \return Contents of the PHY interface rgister. + */ +static u8_t NicPhyRegSelect(u8_t reg, u8_t we) +{ + u8_t rs; + u8_t msk; + u8_t i; + + nic_bs(3); + rs = (nic_inlb(NIC_MGMT) & ~(MGMT_MCLK | MGMT_MDO)) | MGMT_MDOE; + + /* Send idle pattern. */ + for (i = 0; i < 33; i++) { + nic_outlb(NIC_MGMT, rs | MGMT_MDO); + nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK); + } + + /* Send start sequence. */ + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + nic_outlb(NIC_MGMT, rs | MGMT_MDO); + nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK); + + /* Write or read mode. */ + if (we) { + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + nic_outlb(NIC_MGMT, rs | MGMT_MDO); + nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK); + } else { + nic_outlb(NIC_MGMT, rs | MGMT_MDO); + nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK); + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + } + + /* Send PHY address. Zero is used for the internal PHY. */ + for (i = 0; i < 5; i++) { + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + } + + /* Send PHY register number. */ + for (msk = 0x10; msk; msk >>= 1) { + if (reg & msk) { + nic_outlb(NIC_MGMT, rs | MGMT_MDO); + nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK); + } else { + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + } + } + nic_outlb(NIC_MGMT, rs); + + return rs; +} + +/*! + * \brief Read contents of PHY register. + * + * \note NIC interrupts must have been disabled before calling this routine. + * + * \param reg PHY register number. + * + * \return Contents of the specified register. + */ +static u16_t NicPhyRead(u8_t reg) +{ + u16_t rc = 0; + u8_t rs; + u8_t i; + + /* Select register for reading. */ + rs = NicPhyRegSelect(reg, 0); + + /* Switch data direction. */ + rs &= ~MGMT_MDOE; + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + + /* Clock data in. */ + for (i = 0; i < 16; i++) { + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + rc <<= 1; + rc |= (nic_inlb(NIC_MGMT) & MGMT_MDI) != 0; + } + + /* This will set the clock line to low. */ + nic_outlb(NIC_MGMT, rs); + + return rc; +} + +/*! + * \brief Write value to PHY register. + * + * \note NIC interrupts must have been disabled before calling this routine. + * + * \param reg PHY register number. + * \param val Value to write. + */ +static void NicPhyWrite(u8_t reg, u16_t val) +{ + u16_t msk; + u8_t rs; + + /* Select register for writing. */ + rs = NicPhyRegSelect(reg, 1); + + /* Switch data direction dummy. */ + nic_outlb(NIC_MGMT, rs | MGMT_MDO); + nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK); + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + + /* Clock data out. */ + for (msk = 0x8000; msk; msk >>= 1) { + if (val & msk) { + nic_outlb(NIC_MGMT, rs | MGMT_MDO); + nic_outlb(NIC_MGMT, rs | MGMT_MDO | MGMT_MCLK); + } else { + nic_outlb(NIC_MGMT, rs); + nic_outlb(NIC_MGMT, rs | MGMT_MCLK); + } + } + + /* Set clock line low and output line int z-state. */ + nic_outlb(NIC_MGMT, rs & ~MGMT_MDOE); +} + +/*! + * \brief Configure the internal PHY. + * + * Reset the PHY and initiate auto-negotiation. + */ +static int NicPhyConfig(void) +{ + u16_t phy_sor; + u16_t phy_sr; + u16_t phy_to; + u16_t mode; + + /* + * Reset the PHY and wait until this self clearing bit + * becomes zero. We sleep 63 ms before each poll and + * give up after 3 retries. + */ + //printf("Reset PHY.."); + NicPhyWrite(NIC_PHYCR, PHYCR_RST); + for (phy_to = 0;; phy_to++) { + NutSleep(63); + if ((NicPhyRead(NIC_PHYCR) & PHYCR_RST) == 0) + break; + if (phy_to > 3) + return -1; + } + //printf("OK\n"); + + /* Store PHY status output. */ + phy_sor = NicPhyRead(NIC_PHYSOR); + + /* Enable PHY interrupts. */ + NicPhyWrite(NIC_PHYMSK, PHYMSK_MLOSSSYN | PHYMSK_MCWRD | PHYMSK_MSSD | + PHYMSK_MESD | PHYMSK_MRPOL | PHYMSK_MJAB | PHYMSK_MSPDDT | PHYMSK_MDPLDT); + + /* Set RPC register. */ + mode = RPCR_ANEG | RPCR_LEDA_PAT | RPCR_LEDB_PAT; + nic_bs(0); + nic_outw(NIC_RPCR, mode); + +#ifdef NIC_FIXED + /* Disable link. */ + phy_sr = NicPhyRead(NIC_PHYCFR1); + NicPhyWrite(NIC_PHYCFR1, phy_sr | 0x8000); + NutSleep(63); + + /* Set fixed capabilities. */ + NicPhyWrite(NIC_PHYCR, NIC_FIXED); + nic_bs(0); + nic_outw(NIC_RPCR, mode); + + /* Enable link. */ + phy_sr = NicPhyRead(NIC_PHYCFR1); + NicPhyWrite(NIC_PHYCFR1, phy_sr & ~0x8000); + phy_sr = NicPhyRead(NIC_PHYCFR1); + +#else + /* + * Advertise our capabilities, initiate auto negotiation + * and wait until this has been completed. + */ + //printf("Negotiate.."); + NicPhyWrite(NIC_PHYANAD, PHYANAD_TX_FDX | PHYANAD_TX_HDX | PHYANAD_10FDX | PHYANAD_10_HDX | PHYANAD_CSMA); + NutSleep(63); + for (phy_to = 0, phy_sr = 0;; phy_to++) { + /* Give up after 10 seconds. */ + if (phy_to >= 1024) + return -1; + /* Restart auto negotiation every 4 seconds or on failures. */ + if ((phy_to & 127) == 0 /* || (phy_sr & PHYSR_REM_FLT) != 0 */ ) { + NicPhyWrite(NIC_PHYCR, PHYCR_ANEG_EN | PHYCR_ANEG_RST); + //printf("Restart.."); + NutSleep(63); + } + /* Check if we are done. */ + phy_sr = NicPhyRead(NIC_PHYSR); + //printf("[SR %04X]", phy_sr); + if (phy_sr & PHYSR_ANEG_ACK) + break; + NutSleep(63); + } + //printf("OK\n"); +#endif + + return 0; +} + +/*! + * \brief Wait until MMU is ready. + * + * Poll the MMU command register until \ref MMUCR_BUSY + * is cleared. + * + * \param tmo Timeout in milliseconds. + * + * \return 0 on success or -1 on timeout. + */ +static INLINE int NicMmuWait(u16_t tmo) +{ + while (tmo--) { + if ((nic_inlb(NIC_MMUCR) & MMUCR_BUSY) == 0) + break; + NutDelay(1); + } + return tmo ? 0 : -1; +} + +/*! + * \brief Reset the Ethernet controller. + * + * \return 0 on success, -1 otherwise. + */ +static int NicReset(void) +{ +#ifdef LANC111_RESET_BIT + sbi(LANC111_RESET_DDR, LANC111_RESET_BIT); + sbi(LANC111_RESET_PORT, LANC111_RESET_BIT); + NutDelay(WAIT100); + cbi(LANC111_RESET_PORT, LANC111_RESET_BIT); + NutDelay(WAIT250); + NutDelay(WAIT250); +#endif + + /* Disable all interrupts. */ + nic_outlb(NIC_MSK, 0); + + /* MAC and PHY software reset. */ + nic_bs(0); + nic_outw(NIC_RCR, RCR_SOFT_RST); + + /* Enable Ethernet protocol handler. */ + nic_bs(1); + nic_outw(NIC_CR, CR_EPH_EN); + + NutDelay(10); + + /* Disable transmit and receive. */ + nic_bs(0); + nic_outw(NIC_RCR, 0); + nic_outw(NIC_TCR, 0); + + /* Enable auto release. */ + nic_bs(1); + nic_outw(NIC_CTR, CTR_AUTO_RELEASE); + + /* Reset MMU. */ + nic_bs(2); + nic_outlb(NIC_MMUCR, MMU_RST); + if (NicMmuWait(1000)) + return -1; + + return 0; +} + +/* + * Fires up the network interface. NIC interrupts + * should have been disabled when calling this + * function. + * + * \param mac Six byte unique MAC address. + */ +static int NicStart(CONST u8_t * mac) +{ + u8_t i; + + if (NicReset()) + return -1; + + /* Enable receiver. */ + nic_bs(3); + nic_outlb(NIC_ERCV, 7); + nic_bs(0); + nic_outw(NIC_RCR, RCR_RXEN); + + /* Enable transmitter and padding. */ + nic_outw(NIC_TCR, TCR_PAD_EN | TCR_TXENA); + + /* Configure the PHY. */ + if (NicPhyConfig()) + return -1; + + /* Set MAC address. */ + //printf("Set MAC %02X%02X%02X%02X%02X%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + nic_bs(1); + for (i = 0; i < 6; i++) + nic_outlb(NIC_IAR + i, mac[i]); + //printf("OK\n"); + + /* Enable interrupts. */ + nic_bs(2); + nic_outlb(NIC_MSK, INT_ERCV | INT_RCV | INT_RX_OVRN); + + return 0; +} + +/* + * NIC interrupt entry. + */ +#if 0 +static void NicInterrupt(void *arg) +{ + u8_t isr; + u8_t imr; + NICINFO *ni = (NICINFO *) ((NUTDEVICE *) arg)->dev_dcb; + + ni->ni_interrupts++; + + /* Read the interrupt mask and disable all interrupts. */ + nic_bs(2); + imr = nic_inlb(NIC_MSK); + nic_outlb(NIC_MSK, 0); + + /* Read the interrupt status and acknowledge all interrupts. */ + isr = nic_inlb(NIC_IST); + //printf("\n!%02X-%02X ", isr, imr); + isr &= imr; + + /* + * If this is a transmit interrupt, then a packet has been sent. + * So we can clear the transmitter busy flag and wake up the + * transmitter thread. + */ + if (isr & INT_TX_EMPTY) { + nic_outlb(NIC_ACK, INT_TX_EMPTY); + imr &= ~INT_TX_EMPTY; + NutEventPostFromIrq(&ni->ni_tx_rdy); + } + /* Transmit error. */ + else if (isr & INT_TX) { + /* re-enable transmit */ + nic_bs(0); + nic_outw(NIC_TCR, nic_inlb(NIC_TCR) | TCR_TXENA); + nic_bs(2); + nic_outlb(NIC_ACK, INT_TX); + /* kill the packet */ + nic_outlb(NIC_MMUCR, MMU_PKT); + + NutEventPostFromIrq(&ni->ni_tx_rdy); + } + + + /* + * If this is a receive interrupt, then wake up the receiver + * thread. + */ + if (isr & INT_RX_OVRN) { + nic_outlb(NIC_ACK, INT_RX_OVRN); + //nic_outlb(NIC_MMUCR, MMU_TOP); + } + if (isr & INT_ERCV) { + nic_outlb(NIC_ACK, INT_ERCV); + NutEventPostFromIrq(&ni->ni_rx_rdy); + } + if (isr & INT_RCV) { + nic_outlb(NIC_ACK, INT_RCV); + imr &= ~INT_RCV; + NutEventPostFromIrq(&ni->ni_rx_rdy); + } + + if (isr & INT_ALLOC) { + imr &= ~INT_ALLOC; + NutEventPostFromIrq(&maq); + } + //printf(" -%02X-%02X- ", nic_inlb(NIC_IST), inb(PINE) & 0x20); + nic_outlb(NIC_MSK, imr); +} +#endif /* 0 */ +/* + * Write data block to the NIC. + */ +static void NicWrite(u8_t * buf, u16_t len) +{ + register u16_t l = len - 1; + register u8_t ih = (u16_t) l >> 8; + register u8_t il = (u8_t) l; + + if (!len) + return; + + do { + do { + nic_outlb(NIC_DATA, *buf++); + } while (il-- != 0); + } while (ih-- != 0); +} + +/* + * Read data block from the NIC. + */ +static void NicRead(u8_t * buf, u16_t len) +{ + register u16_t l = len - 1; + register u8_t ih = (u16_t) l >> 8; + register u8_t il = (u8_t) l; + + if (!len) + return; + + do { + do { + *buf++ = nic_inlb(NIC_DATA); + } while (il-- != 0); + } while (ih-- != 0); +} + +/*! + * \brief Fetch the next packet out of the receive ring buffer. + * + * Nic interrupts must be disabled when calling this funtion. + * + * \return Pointer to an allocated ::NETBUF. If there is no + * no data available, then the function returns a + * null pointer. If the NIC's buffer seems to be + * corrupted, a pointer to 0xFFFF is returned. + */ +static NETBUF *NicGetPacket(void) +{ + NETBUF *nb = 0; + //u8_t *buf; + u16_t fsw; + u16_t fbc; + + /* Check the fifo empty bit. If it is set, then there is + nothing in the receiver fifo. */ + nic_bs(2); + if (nic_inw(NIC_FIFO) & 0x8000) { + return 0; + } + + /* Inialize pointer register. */ + nic_outw(NIC_PTR, PTR_READ | PTR_RCV | PTR_AUTO_INCR); + _NOP(); + _NOP(); + _NOP(); + _NOP(); + + /* Read status word and byte count. */ + fsw = nic_inw(NIC_DATA); + fbc = nic_inw(NIC_DATA); + //printf("[SW=%04X,BC=%04X]", fsw, fbc); + + /* Check for frame errors. */ + if (fsw & 0xAC00) { + nb = (NETBUF *) 0xFFFF; + } + /* Check the byte count. */ + else if (fbc < 66 || fbc > 1524) { + nb = (NETBUF *) 0xFFFF; + } + + else { + /* + * Allocate a NETBUF. + * Hack alert: Rev A chips never set the odd frame indicator. + */ + fbc -= 3; + /* nb = NutNetBufAlloc(0, NBAF_DATALINK, fbc);*/ + + /* Perform the read. */ +/* if (nb) + NicRead(nb->nb_dl.vp, fbc);*/ + } + + /* Release the packet. */ + nic_outlb(NIC_MMUCR, MMU_TOP); + + return nb; +} + +/*! + * \brief Load a packet into the nic's transmit ring buffer. + * + * Interupts must have been disabled when calling this function. + * + * \param nb Network buffer structure containing the packet to be sent. + * The structure must have been allocated by a previous + * call NutNetBufAlloc(). This routine will automatically + * release the buffer in case of an error. + * + * \return 0 on success, -1 in case of any errors. Errors + * will automatically release the network buffer + * structure. + */ +#if 0 +static int NicPutPacket(NETBUF * nb) +{ + u16_t sz; + u8_t odd = 0; + u8_t imsk; + + //printf("[P]"); + /* + * Calculate the number of bytes to be send. Do not send packets + * larger than the Ethernet maximum transfer unit. The MTU + * consist of 1500 data bytes plus the 14 byte Ethernet header + * plus 4 bytes CRC. We check the data bytes only. + */ + if ((sz = nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz) > ETHERMTU) + return -1; + + /* Disable all interrupts. */ + imsk = nic_inlb(NIC_MSK); + nic_outlb(NIC_MSK, 0); + + /* Allocate packet buffer space. */ + nic_bs(2); + nic_outlb(NIC_MMUCR, MMU_ALO); + if (NicMmuWait(100)) + return -1; + + /* Enable interrupts including allocation success. */ + nic_outlb(NIC_MSK, imsk | INT_ALLOC); + + /* The MMU needs some time. Use it to calculate the byte count. */ + sz += nb->nb_dl.sz; + sz += 6; + if (sz & 1) { + sz++; + odd++; + } + + /* Wait for allocation success. */ + while ((nic_inlb(NIC_IST) & INT_ALLOC) == 0) { + if (NutEventWait(&maq, 125)) { + nic_outlb(NIC_MMUCR, MMU_RST); + NicMmuWait(1000); + nic_outlb(NIC_MMUCR, MMU_ALO); + if (NicMmuWait(100) || (nic_inlb(NIC_IST) & INT_ALLOC) == 0) { + if (NutEventWait(&maq, 125)) { + return -1; + } + } + } + } + + /* Disable interrupts. */ + imsk = nic_inlb(NIC_MSK); + nic_outlb(NIC_MSK, 0); + + + nic_outlb(NIC_PNR, nic_inhb(NIC_PNR)); + + nic_outw(NIC_PTR, 0x4000); + + /* Transfer control word. */ + nic_outlb(NIC_DATA, 0); + nic_outlb(NIC_DATA, 0); + + /* Transfer the byte count. */ + nic_outw(NIC_DATA, sz); + + /* Transfer the Ethernet frame. */ + NicWrite(nb->nb_dl.vp, nb->nb_dl.sz); + NicWrite(nb->nb_nw.vp, nb->nb_nw.sz); + NicWrite(nb->nb_tp.vp, nb->nb_tp.sz); + NicWrite(nb->nb_ap.vp, nb->nb_ap.sz); + + if (odd) + nic_outlb(NIC_DATA, 0); + + /* Transfer the control word. */ + nic_outw(NIC_DATA, 0); + + /* Enqueue packet. */ + if (NicMmuWait(100)) + return -1; + nic_outlb(NIC_MMUCR, MMU_ENQ); + + /* Enable interrupts. */ + imsk |= INT_TX | INT_TX_EMPTY; + nic_outlb(NIC_MSK, imsk); + + return 0; +} +#endif + +/*! \fn NicRxLanc(void *arg) + * \brief NIC receiver thread. + * + */ +#if 1 +PROCESS_THREAD(lanc111_process, ev, data) + /*THREAD(NicRxLanc, arg)*/ +{ + /* NUTDEVICE *dev; + IFNET *ifn; + NICINFO *ni; + NETBUF *nb;*/ + u8_t imsk; + static struct etimer et; + + /* dev = arg; + ifn = (IFNET *) dev->dev_icb; + ni = (NICINFO *) dev->dev_dcb;*/ + + /* + * This is a temporary hack. Due to a change in initialization, + * we may not have got a MAC address yet. Wait until one has been + * set. + */ + + PROCESS_BEGIN(); + + /* while(*((u_long *) (ifn->if_mac)) && + *((u_long *) (ifn->if_mac)) != 0xFFFFFFFFUL) {*/ + while(0) { + etimer_set(&et, CLOCK_SECOND / 8); + PROCESS_WAIT_UNTIL(etimer_expired(&et)); + } + + /* + * Do not continue unless we managed to start the NIC. We are + * trapped here if the Ethernet link cannot be established. + * This happens, for example, if no Ethernet cable is plugged + * in. + */ + /* while(NicStart(ifn->if_mac)) {*/ + while(0) { + /*NutSleep(1000);*/ + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_UNTIL(etimer_expired(&et)); + } + + LANC111_SIGNAL_MODE(); + sbi(EIMSK, LANC111_SIGNAL_IRQ); + + /* NutEventPost(&mutex);*/ + + /* Run at high priority. */ + /* NutThreadSetPriority(9);*/ + + for (;;) { + + /* + * Wait for the arrival of new packets or + * check the receiver every two second. + */ + /* NutEventWait(&ni->ni_rx_rdy, 2000);*/ + PROCESS_WAIT_EVENT(); + + /* + * Fetch all packets from the NIC's internal + * buffer and pass them to the registered handler. + */ + imsk = nic_inlb(NIC_MSK); + nic_outlb(NIC_MSK, 0); + /* while ((nb = NicGetPacket()) != 0) { + if (nb != (NETBUF *) 0xFFFF) { + ni->ni_rx_packets++; + (*ifn->if_recv) (dev, nb); + } + }*/ + nic_outlb(NIC_MSK, imsk | INT_RCV | INT_ERCV); + } + + PROCESS_END(); +} +#endif /* 0 */ +/*! + * \brief Send Ethernet packet. + * + * \param dev Identifies the device to use. + * \param nb Network buffer structure containing the packet to be sent. + * The structure must have been allocated by a previous + * call NutNetBufAlloc(). + * + * \return 0 on success, -1 in case of any errors. + */ +#if 0 +int LancOutput(NUTDEVICE * dev, NETBUF * nb) +{ + static u_long mx_wait = 5000; + int rc = -1; + NICINFO *ni; + + /* + * After initialization we are waiting for a long time to give + * the PHY a chance to establish an Ethernet link. + */ + if (NutEventWait(&mutex, mx_wait) == 0) { + ni = (NICINFO *) dev->dev_dcb; + + if (NicPutPacket(nb) == 0) { + ni->ni_tx_packets++; + rc = 0; + /* Ethernet works. Set a long waiting time in case we + temporarly lose the link next time. */ + mx_wait = 5000; + } + NutEventPost(&mutex); + } + /* + * Probably no Ethernet link. Significantly reduce the waiting + * time, so following transmission will soon return an error. + */ + else { + mx_wait = 500; + } + return rc; +} +#endif +#if 0 +/*! + * \brief Initialize Ethernet hardware. + * + * Resets the LAN91C111 Ethernet controller, initializes all required + * hardware registers and starts a background thread for incoming + * Ethernet traffic. + * + * Applications should do not directly call this function. It is + * automatically executed during during device registration by + * NutRegisterDevice(). + * + * If the network configuration hasn't been set by the application + * before registering the specified device, this function will + * call NutNetLoadConfig() to get the MAC address. + * + * \param dev Identifies the device to initialize. + */ +int LancInit(NUTDEVICE * dev) +{ + /* Disable NIC interrupt and clear NICINFO structure. */ + cbi(EIMSK, LANC111_SIGNAL_IRQ); + memset(dev->dev_dcb, 0, sizeof(NICINFO)); + + /* Register interrupt handler and enable interrupts. */ + if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev)) + return -1; + + /* + * Start the receiver thread. + */ + NutThreadCreate("rxi5", NicRxLanc, dev, 640); + + //NutSleep(500); + + return 0; +} + +/*@}*/ + +/*! + * \addtogroup xgSmscDev + */ +/*@{*/ + +static NICINFO dcb_eth0; + +/*! + * \brief Network interface information structure. + * + * Used to call. + */ +static IFNET ifn_eth0 = { + IFT_ETHER, /*!< \brief Interface type. */ + {0, 0, 0, 0, 0, 0}, /*!< \brief Hardware net address. */ + 0, /*!< \brief IP address. */ + 0, /*!< \brief Remote IP address for point to point. */ + 0, /*!< \brief IP network mask. */ + ETHERMTU, /*!< \brief Maximum size of a transmission unit. */ + 0, /*!< \brief Packet identifier. */ + 0, /*!< \brief Linked list of arp entries. */ + NutEtherInput, /*!< \brief Routine to pass received data to, if_recv(). */ + LancOutput, /*!< \brief Driver output routine, if_send(). */ + NutEtherOutput /*!< \brief Media output routine, if_output(). */ +}; + +/*! + * \brief Device information structure. + * + * A pointer to this structure must be passed to NutRegisterDevice() + * to bind this Ethernet device driver to the Nut/OS kernel. + * An application may then call NutNetIfConfig() with the name \em eth0 + * of this driver to initialize the network interface. + * + */ +NUTDEVICE devSmsc111 = { + 0, /* Pointer to next device. */ + {'e', 't', 'h', '0', 0, 0, 0, 0, 0}, /* Unique device name. */ + IFTYP_NET, /* Type of device. */ + 0, /* Base address. */ + 0, /* First interrupt number. */ + &ifn_eth0, /* Interface control block. */ + &dcb_eth0, /* Driver control block. */ + LancInit, /* Driver initialization routine. */ + 0, /* Driver specific control function. */ + 0, /* Read from device. */ + 0, /* Write to device. */ + 0, /* Write from program space data to device. */ + 0, /* Open a device or file. */ + 0, /* Close a device or file. */ + 0 /* Request file size. */ +}; + +/*@}*/ +#endif + + +int +lanc111_init(void) +{ + /* Disable NIC interrupt and clear NICINFO structure. */ + cbi(EIMSK, LANC111_SIGNAL_IRQ); + + /* Register interrupt handler and enable interrupts. */ + /* if (NutRegisterIrqHandler(&LANC111_SIGNAL, NicInterrupt, dev)) + return -1;*/ + + /* + * Start the receiver thread. + */ + /* NutThreadCreate("rxi5", NicRxLanc, dev, 640);*/ + + //NutSleep(500); + + return 0; +} + diff --git a/cpu/avr/dev/rs232.c b/cpu/avr/dev/rs232.c new file mode 100644 index 000000000..adca2624e --- /dev/null +++ b/cpu/avr/dev/rs232.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: rs232.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include +#include +#include +#include + +#include "contiki.h" +#include "dev/slip.h" +#include "dev/serial.h" +#include "dev/rs232.h" + +static volatile unsigned char txwait; +/*static unsigned char slipmode;*/ + +static int (* input_handler)(unsigned char) = NULL; + +/*---------------------------------------------------------------------------*/ +SIGNAL(SIG_UART0_TRANS) +{ + txwait = 0; +} +/*---------------------------------------------------------------------------*/ +SIGNAL(SIG_UART0_RECV) +{ + unsigned char c; + + c = UDR0; + + if(input_handler != NULL) { + input_handler(c); + } + + /* if(slipmode) { + slip_input_byte(c); + } else { + serial_input_byte(c); + }*/ +} +/*---------------------------------------------------------------------------*/ +void +rs232_init(void) +{ + /* Enable transmit. */ + UCSR0B = _BV(RXCIE) | _BV(TXCIE) | _BV(RXEN) | _BV(TXEN); + /* Set baud rate (23 =~ 38400) */ + UBRR0H = 0; + UBRR0L = 23; + + /* slipmode = 0;*/ + txwait = 0; + + input_handler = NULL; +} +/*---------------------------------------------------------------------------*/ +/*void +rs232_init_slip(void) +{ + rs232_init(); + slipmode = 1; +}*/ +/*---------------------------------------------------------------------------*/ +void +rs232_print_p(prog_char *buf) +{ + while(pgm_read_byte(buf)) { + rs232_send(pgm_read_byte(buf)); + ++buf; + } +} +/*---------------------------------------------------------------------------*/ +void +rs232_print(char *buf) +{ + while(*buf) { + rs232_send(*buf++); + } +} +/*---------------------------------------------------------------------------*/ +void +rs232_send(unsigned char c) +{ + txwait = 1; + UDR0 = c; + while(txwait); +} +/*---------------------------------------------------------------------------*/ +void +rs232_set_input(int (*f)(unsigned char)) +{ + input_handler = f; +} +/*---------------------------------------------------------------------------*/ +void +slip_arch_writeb(unsigned char c) +{ + rs232_send(c); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/avr/dev/rs232.h b/cpu/avr/dev/rs232.h new file mode 100644 index 000000000..3c671b18a --- /dev/null +++ b/cpu/avr/dev/rs232.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: rs232.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#ifndef __RS232_H__ +#define __RS232_H__ + +#include + +/** + * \brief Initialize the RS232 module + * + * This function is called from the boot up code to + * initalize the RS232 module. + */ +void rs232_init(void); + +/** + * \brief Set an input handler for incoming RS232 data + * \param f A pointer to a byte input handler + * + * This function sets the input handler for incoming RS232 + * data. The input handler function is called for every + * incoming data byte. The function is called from the + * RS232 interrupt handler, so care must be taken when + * implementing the input handler to avoid race + * conditions. + * + * The return value of the input handler affects the sleep + * mode of the CPU: if the input handler returns non-zero + * (true), the CPU is awakened to let other processing + * take place. If the input handler returns zero, the CPU + * is kept sleeping. + */ +void rs232_set_input(int (* f)(unsigned char)); + + +/** + * \brief Print a text string from program memory on RS232 + * \param str A pointer to the string that is to be printed + * + * This function prints a string from program memory to + * RS232. The string must be terminated by a null + * byte. The RS232 module must be correctly initalized and + * configured for this function to work. + */ +void rs232_print_p(prog_char *buf); + + +/** + * \brief Print a text string on RS232 + * \param str A pointer to the string that is to be printed + * + * This function prints a string to RS232. The string must + * be terminated by a null byte. The RS232 module must be + * correctly initalized and configured for this function + * to work. + */ +void rs232_print(char *buf); + +/** + * \brief Print a character on RS232 + * \param c The character to be printed + * + * This function prints a character to RS232. The RS232 + * module must be correctly initalized and configured for + * this function to work. + */ +void rs232_send(unsigned char c); + +#endif /* __RS232_H__ */ diff --git a/cpu/avr/dev/rtl8019-drv.c b/cpu/avr/dev/rtl8019-drv.c new file mode 100644 index 000000000..b4daae613 --- /dev/null +++ b/cpu/avr/dev/rtl8019-drv.c @@ -0,0 +1,94 @@ +/*-----------------------------------------------------------------------------------*/ +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: rtl8019-drv.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ + +#include "net/packet-service.h" +#include "dev/rtl8019dev.h" +#include "net/uip_arp.h" + +#include + +static u8_t output(void); + +SERVICE(rtl8019_drv_service, packet_service, { output }); + +PROCESS(rtl8019_drv_process, "RTL8019 driver"); + +PROCESS_THREAD(rtl8019_drv_process, ev, data) +{ + PROCESS_BEGIN(); + + SERVICE_REGISTER(rtl8019_drv_service); + + RTL8019dev_init(); + + while(1) { + process_poll(&rtl8019_drv_process); + PROCESS_WAIT_EVENT(); + + uip_len = RTL8019dev_poll(); + + if(uip_len > 0) { + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + RTL8019dev_send(); + } + } + } + } + + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + uip_arp_out(); + RTL8019dev_send(); + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/avr/dev/rtl8019-drv.h b/cpu/avr/dev/rtl8019-drv.h new file mode 100644 index 000000000..c0740701c --- /dev/null +++ b/cpu/avr/dev/rtl8019-drv.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2001, 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. 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: rtl8019-drv.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + */ +#ifndef __RTL8019_DRV_H__ +#define __RTL8019_DRV_H__ + +#include "contiki.h" + +PROCESS_NAME(rtl8019_drv_process); + +#endif /* __RTL8019_DRV_H__ */ diff --git a/cpu/avr/dev/rtl8019.c b/cpu/avr/dev/rtl8019.c new file mode 100644 index 000000000..559eda53d --- /dev/null +++ b/cpu/avr/dev/rtl8019.c @@ -0,0 +1,936 @@ +#include "rtl8019.h" +#include "delay.h" +#include "debug.h" +#include "avr/pgmspace.h" +#include "rtlregs.h" + +#ifndef cbi +#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) +#endif + +#define outp(val, port) do { (port) = (val); } while(0) +#define inp(port) (port) + +/***************************************************************************** +* Module Name: Realtek 8019AS Driver +* +* Created By: Louis Beaudoin (www.embedded-creations.com) +* +* Original Release: September 21, 2002 +* +* Module Description: +* Provides functions to initialize the Realtek 8019AS, and send and retreive +* packets +* +* November 15, 2002 - Louis Beaudoin +* processRTL8019Interrupt() - bit mask mistake fixed +* +* September 30, 2002 - Louis Beaudoin +* Receive functions modified to handle errors encountered when receiving a +* fast data stream. Functions now manually retreive data instead of +* using the send packet command. Interface improved by checking for +* overruns and data in the buffer internally. +* Corrected the overrun function - overrun flag was not reset after overrun +* Added support for the Imagecraft Compiler +* Added support to communicate with the NIC using general I/O ports +* +*****************************************************************************/ + + +/***************************************************************************** +* writeRTL( RTL_ADDRESS, RTL_DATA ) +* Args: 1. unsigned char RTL_ADDRESS - register offset of RTL register +* 2. unsigned char RTL_DATA - data to write to register +* Created By: Louis Beaudoin +* Date: September 21, 2002 +* Description: Writes byte to RTL8019 register. +* +* Notes - If using the External SRAM Interface, performs a write to +* address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8) +* The address is sent in the non-multiplxed upper address port so +* no latch is required. +* +* If using general I/O ports, the data port is left in the input +* state with pullups enabled +* +*****************************************************************************/ +#if MEMORY_MAPPED_NIC == 1 +/*#define writeRTL(RTL_ADDRESS,RTL_DATA) do{ *(volatile unsigned char *) \ + (MEMORY_MAPPED_RTL8019_OFFSET \ + + (((unsigned char)(RTL_ADDRESS)) << 8)) = \ + (unsigned char)(RTL_DATA); } while(0)*/ +#define writeRTL nic_write +#else + + +void writeRTL(unsigned char address, unsigned char data) +{ + // put the address and data in the port registers - data port is output + outp( address, RTL8019_ADDRESS_PORT ); + outp( 0xFF, RTL8019_DATA_DDR ); + outp( data, RTL8019_DATA_PORT ); + + // toggle write pin + RTL8019_CLEAR_WRITE; + RTL8019_SET_WRITE; + + // set data port back to input with pullups enabled + outp( 0x00, RTL8019_DATA_DDR ); + outp( 0xFF, RTL8019_DATA_PORT ); +} + + + +#endif + +/***************************************************************************** +* readRTL(RTL_ADDRESS) +* Args: unsigned char RTL_ADDRESS - register offset of RTL register +* Created By: Louis Beaudoin +* Date: September 21, 2002 +* Description: Reads byte from RTL8019 register +* +* Notes - If using the External SRAM Interface, performs a read from +* address MEMORY_MAPPED_RTL8019_OFFSET + (RTL_ADDRESS<<8) +* The address is sent in the non-multiplxed upper address port so +* no latch is required. +* +* If using general I/O ports, the data port is assumed to already be +* an input, and is left as an input port when done +* +*****************************************************************************/ +#if MEMORY_MAPPED_NIC == 1 +/*#define readRTL(RTL_ADDRESS) (*(volatile unsigned char *) \ + (MEMORY_MAPPED_RTL8019_OFFSET \ + + (((unsigned char)(RTL_ADDRESS)) << 8)) )*/ +#define readRTL nic_read +#else + +unsigned char readRTL(unsigned char address) +{ + unsigned char byte; + + // drive the read address + outp( address, RTL8019_ADDRESS_PORT ); + + //nop(); + + // assert read + RTL8019_CLEAR_READ; + nop(); + + // read in the data + byte = inp( RTL8019_DATA_PIN ); + + // negate read + RTL8019_SET_READ; + + return byte; +} + +#endif + + + +/***************************************************************************** +* RTL8019setupPorts(void); +* +* Created By: Louis Beaudoin +* Date: September 21, 2002 +* Description: Sets up the ports used for communication with the RTL8019 NIC +* (data bus, address bus, read, write, and reset) +*****************************************************************************/ +void RTL8019setupPorts(void) +{ +volatile unsigned char *base = (unsigned char *)0x8300; + +#if MEMORY_MAPPED_NIC == 1 + // enable external SRAM interface - no wait states + outp(inp(MCUCR) | (1<=ETHERNET_MIN_PACKET_LENGTH) ? + packetLength : ETHERNET_MIN_PACKET_LENGTH ; + + //start the NIC + writeRTL(CR,0x22); + + // still transmitting a packet - wait for it to finish + while( readRTL(CR) & 0x04 ); + + //load beginning page for transmit buffer + writeRTL(TPSR,TXSTART_INIT); + + //set start address for remote DMA operation + writeRTL(RSAR0,0x00); + writeRTL(RSAR1,0x40); + + //clear the packet stored interrupt + writeRTL(ISR,(1<>8)); + + writeRTL(TBCR0, (unsigned char)(sendPacketLength)); + writeRTL(TBCR1, (unsigned char)((sendPacketLength)>>8)); + + //do remote write operation + writeRTL(CR,0x12); +} + + + +void RTL8019sendPacketData(unsigned char * localBuffer, unsigned int length) +{ + unsigned int i; + volatile unsigned char *base = (unsigned char *)0x8300; + for(i=0;i= RXSTOP_INIT) || (bnry < RXSTART_INIT) ) + { + writeRTL(BNRY, RXSTART_INIT); + writeRTL(CR, 0x62); + writeRTL(CURR, RXSTART_INIT); + writeRTL(CR, 0x22); + return 0; + } + + // initiate DMA to transfer the RTL8019 packet header + writeRTL(RBCR0, 4); + writeRTL(RBCR1, 0); + writeRTL(RSAR0, 0); + writeRTL(RSAR1, bnry); + writeRTL(CR, 0x0A); + /* debug_print(PSTR("Page header: "));*/ + + for(i=0;i<4;i++) { + pageheader[i] = readRTL(RDMAPORT); + /* debug_print8(pageheader[i]);*/ + } + + // end the DMA operation + writeRTL(CR, 0x22); + for(i = 0; i <= 20; i++) { + if(readRTL(ISR) & 1<<6) { + break; + } + } + writeRTL(ISR, 1<<6); + + + + rxlen = (pageheader[enetpacketLenH]<<8) + pageheader[enetpacketLenL]; + nextPage = pageheader[nextblock_ptr] ; + + currentRetreiveAddress = (bnry<<8) + 4; + + /* debug_print(PSTR("nextPage: ")); + debug_print8(nextPage);*/ + + // if the nextPage pointer is invalid, the packet is not ready yet - exit + if( (nextPage >= RXSTOP_INIT) || (nextPage < RXSTART_INIT) ) { + /* UDR0 = '0';*/ + return 0; + } + + return rxlen-4; +} + + +void RTL8019retreivePacketData(unsigned char * localBuffer, unsigned int length) +{ + unsigned int i; + volatile unsigned char *base = (unsigned char *)0x8300; + // initiate DMA to transfer the data + writeRTL(RBCR0, (unsigned char)length); + writeRTL(RBCR1, (unsigned char)(length>>8)); + writeRTL(RSAR0, (unsigned char)currentRetreiveAddress); + writeRTL(RSAR1, (unsigned char)(currentRetreiveAddress>>8)); + writeRTL(CR, 0x0A); + for(i=0;i= 0x6000 ) + currentRetreiveAddress = currentRetreiveAddress - (0x6000-0x4600) ; +} + + + +void RTL8019endPacketRetreive(void) +{ + volatile unsigned char *base = (unsigned char *)0x8300; + unsigned char i; + + // end the DMA operation + writeRTL(CR, 0x22); + for(i = 0; i <= 20; i++) + if(readRTL(ISR) & 1<<6) + break; + writeRTL(ISR, 1<<6); + + // set the boundary register to point to the start of the next packet + writeRTL(BNRY, nextPage); +} + + +void overrun(void) +{ + volatile unsigned char *base = (unsigned char *)0x8300; + unsigned char data_L, resend; + + data_L = readRTL(CR); + writeRTL(CR, 0x21); + Delay_1ms(2); + writeRTL(RBCR0, 0x00); + writeRTL(RBCR1, 0x00); + if(!(data_L & 0x04)) + resend = 0; + else if(data_L & 0x04) + { + data_L = readRTL(ISR); + if((data_L & 0x02) || (data_L & 0x08)) + resend = 0; + else + resend = 1; + } + + writeRTL(TCR, 0x02); + writeRTL(CR, 0x22); + writeRTL(BNRY, RXSTART_INIT); + writeRTL(CR, 0x62); + writeRTL(CURR, RXSTART_INIT); + writeRTL(CR, 0x22); + writeRTL(ISR, 0x10); + writeRTL(TCR, TCR_INIT); + + writeRTL(ISR, 0xFF); +} + + + + +/*! + * \brief Size of a single ring buffer page. + */ +#define NIC_PAGE_SIZE 0x100 + +/*! + * \brief First ring buffer page address. + */ +#define NIC_START_PAGE 0x40 + +/*! + * \brief Last ring buffer page address plus 1. + */ +#define NIC_STOP_PAGE 0x60 + +/*! + * \brief Number of pages in a single transmit buffer. + * + * This should be at least the MTU size. + */ +#define NIC_TX_PAGES 6 + +/*! + * \brief Number of transmit buffers. + */ +#define NIC_TX_BUFFERS 2 + +/*! + * \brief Controller memory layout: + * + * 0x4000 - 0x4bff 3k bytes transmit buffer + * 0x4c00 - 0x5fff 5k bytes receive buffer + */ +#define NIC_FIRST_TX_PAGE NIC_START_PAGE +#define NIC_FIRST_RX_PAGE (NIC_FIRST_TX_PAGE + NIC_TX_PAGES * NIC_TX_BUFFERS) + +/*! + * \brief Standard sizing information + */ +#define TX_PAGES 12 /* Allow for 2 back-to-back frames */ + +static unsigned char mac[6] = {0x00,0x06,0x98,0x01,0x02,0x29}; +void Delay(long nops) +{ + volatile long i; + + for(i = 0; i < nops; i++) +#ifdef __IMAGECRAFT__ + asm("nop\n"); +#else + asm volatile("nop\n\t"::); +#endif +} + +static int NicReset(void) +{ +volatile unsigned char *base = (unsigned char *)0x8300; + unsigned char i; + unsigned char j; + + for(j = 0; j < 20; j++) { + debug_print(PSTR("SW-Reset...")); + i = nic_read(NIC_RESET); + Delay(500); + nic_write(NIC_RESET, i); + for(i = 0; i < 20; i++) { + Delay(5000); + + /* + * ID detection added for version 1.1 boards. + */ + if((nic_read(NIC_PG0_ISR) & NIC_ISR_RST) != 0 && + nic_read(NIC_PG0_RBCR0) == 0x50 && + nic_read(NIC_PG0_RBCR1) == 0x70) { + debug_print(PSTR("OK\r\n")); + return 0; + } + } + debug_print(PSTR("failed\r\n\x07")); + + /* + * Toggle the hardware reset line. Since Ethernut version 1.3 the + * hardware reset pin of the nic is no longer connected to bit 4 + * on port E, but wired to the board reset line. + */ + if(j == 10) { + debug_print(PSTR("Ethernut 1.1 HW-Reset\r\n")); + sbi(DDRE, 4); + sbi(PORTE, 4); + Delay(100000); + cbi(PORTE, 4); + Delay(250000); + } + } + return -1; +} + +void initRTL8019(void) +{ + unsigned char i, rb; + volatile unsigned char *base = (unsigned char *)0x8300; + + RTL8019setupPorts(); + + /*#define nic_write writeRTL + #define nic_read readRTL*/ + /* + * Disable NIC interrupts. + */ + cbi(EIMSK, INT5); + + /* if(NicReset(base)) + return -1;*/ +#if 0 + /* + * Mask all interrupts and clear any interrupt status flag to set the + * INT pin back to low. + */ + nic_write(NIC_PG0_IMR, 0); + nic_write(NIC_PG0_ISR, 0xff); + + /* + * During reset the nic loaded its initial configuration from an + * external eeprom. On the ethernut board we do not have any + * configuration eeprom, but simply tied the eeprom data line to + * high level. So we have to clear some bits in the configuration + * register. Switch to register page 3. + */ + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); + + /* + * The nic configuration registers are write protected unless both + * EEM bits are set to 1. + */ + nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1); + + /* + * Disable sleep and power down. + */ + nic_write(NIC_PG3_CONFIG3, 0); + + /* + * Network media had been set to 10Base2 by the virtual EEPROM and + * will be set now to auto detect. This will initiate a link test. + * We don't force 10BaseT, because this would disable the link test. + */ + nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB); + + /* + * Reenable write protection of the nic configuration registers + * and wait for link test to complete. + */ + nic_write(NIC_PG3_EECR, 0); + /* NutSleep(WAIT500);*/ + Delay_10ms(50); + + /* + * Switch to register page 0 and set data configuration register + * to byte-wide DMA transfers, normal operation (no loopback), + * send command not executed and 8 byte fifo threshold. + */ + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); + nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1); + + /* + * Clear remote dma byte count register. + */ + nic_write(NIC_PG0_RBCR0, 0); + nic_write(NIC_PG0_RBCR1, 0); + + /* + * Temporarily set receiver to monitor mode and transmitter to + * internal loopback mode. Incoming packets will not be stored + * in the nic ring buffer and no data will be send to the network. + */ + nic_write(NIC_PG0_RCR, NIC_RCR_MON); + nic_write(NIC_PG0_TCR, NIC_TCR_LB0); + + /* + * Configure the nic's ring buffer page layout. + * NIC_PG0_BNRY: Last page read. + * NIC_PG0_PSTART: First page of receiver buffer. + * NIC_PG0_PSTOP: Last page of receiver buffer. + */ + nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE); + nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1); + nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE); + nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE); + + /* + * Once again clear interrupt status register. + */ + nic_write(NIC_PG0_ISR, 0xff); + + /* + * Switch to register page 1 and copy our MAC address into the nic. + * We are still in stop mode. + */ + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0); + for(i = 0; i < 6; i++) + nic_write(NIC_PG1_PAR0 + i, mac[i]); + + /* + * Clear multicast filter bits to disable all packets. + */ + for(i = 0; i < 8; i++) + nic_write(NIC_PG1_MAR0 + i, 0); + + /* + * Set current page pointer to one page after the boundary pointer. + */ + nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES); + + /* + * Switch back to register page 0, remaining in stop mode. + */ + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); + + /* + * Take receiver out of monitor mode and enable it for accepting + * broadcasts. + */ + nic_write(NIC_PG0_RCR, NIC_RCR_AB); + + /* + * Clear all interrupt status flags and enable interrupts. + */ + nic_write(NIC_PG0_ISR, 0xff); + nic_write(NIC_PG0_IMR, NIC_IMR_PRXE | NIC_IMR_PTXE | NIC_IMR_RXEE | + NIC_IMR_TXEE | NIC_IMR_OVWE); + + /* + * Fire up the nic by clearing the stop bit and setting the start bit. + * To activate the local receive dma we must also take the nic out of + * the local loopback mode. + */ + nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2); + nic_write(NIC_PG0_TCR, 0); + + /* NutSleep(WAIT500);*/ + Delay_10ms(50); + + +#endif /* 0 */ + + NicReset(); + + debug_print(PSTR("Init controller...")); + nic_write(NIC_PG0_IMR, 0); + nic_write(NIC_PG0_ISR, 0xff); + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); + nic_write(NIC_PG3_EECR, NIC_EECR_EEM0 | NIC_EECR_EEM1); + nic_write(NIC_PG3_CONFIG3, 0); + nic_write(NIC_PG3_CONFIG2, NIC_CONFIG2_BSELB); + nic_write(NIC_PG3_EECR, 0); + /* Delay(50000);*/ + Delay_10ms(200); + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); + nic_write(NIC_PG0_DCR, NIC_DCR_LS | NIC_DCR_FT1); + nic_write(NIC_PG0_RBCR0, 0); + nic_write(NIC_PG0_RBCR1, 0); + nic_write(NIC_PG0_RCR, NIC_RCR_MON); + nic_write(NIC_PG0_TCR, NIC_TCR_LB0); + nic_write(NIC_PG0_TPSR, NIC_FIRST_TX_PAGE); + nic_write(NIC_PG0_BNRY, NIC_STOP_PAGE - 1); + nic_write(NIC_PG0_PSTART, NIC_FIRST_RX_PAGE); + nic_write(NIC_PG0_PSTOP, NIC_STOP_PAGE); + nic_write(NIC_PG0_ISR, 0xff); + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2 | NIC_CR_PS0); + for(i = 0; i < 6; i++) + nic_write(NIC_PG1_PAR0 + i, mac[i]); + for(i = 0; i < 8; i++) + nic_write(NIC_PG1_MAR0 + i, 0); + nic_write(NIC_PG1_CURR, NIC_START_PAGE + TX_PAGES); + nic_write(NIC_CR, NIC_CR_STP | NIC_CR_RD2); + nic_write(NIC_PG0_RCR, NIC_RCR_AB); + nic_write(NIC_PG0_ISR, 0xff); + nic_write(NIC_PG0_IMR, 0); + nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2); + nic_write(NIC_PG0_TCR, 0); + /* Delay(1000000)*/ + Delay_10ms(200); + + + nic_write(NIC_CR, NIC_CR_STA | NIC_CR_RD2 | NIC_CR_PS0 | NIC_CR_PS1); + rb = nic_read(NIC_PG3_CONFIG0); + debug_print8(rb); + switch(rb & 0xC0) { + case 0x00: + debug_print(PSTR("RTL8019AS ")); + if(rb & 0x08) + debug_print(PSTR("jumper mode: ")); + if(rb & 0x20) + debug_print(PSTR("AUI ")); + if(rb & 0x10) + debug_print(PSTR("PNP ")); + break; + case 0xC0: + debug_print(PSTR("RTL8019 ")); + if(rb & 0x08) + debug_print(PSTR("jumper mode: ")); + break; + default: + debug_print(PSTR("Unknown chip ")); + debug_print8(rb); + break; + } + if(rb & 0x04) + debug_print(PSTR("BNC\x07 ")); + if(rb & 0x03) + debug_print(PSTR("Failed\x07 ")); + + /* rb = nic_read(NIC_PG3_CONFIG1); + debug_print8(rb);*/ + /* NutPrintFormat(0, "IRQ%u ", (rb >> 4) & 7);*/ + /* debug_print("IRQ "); + debug_print8((rb >> 4) & 7);*/ + + rb = nic_read(NIC_PG3_CONFIG2); + debug_print8(rb); + switch(rb & 0xC0) { + case 0x00: + debug_print(PSTR("Auto ")); + break; + case 0x40: + debug_print(PSTR("10BaseT ")); + break; + case 0x80: + debug_print(PSTR("10Base5 ")); + break; + case 0xC0: + debug_print(PSTR("10Base2 ")); + break; + } + + + return; + + /* HARD_RESET_RTL8019();*/ + + // do soft reset + writeRTL( ISR, readRTL(ISR) ) ; + Delay_10ms(5); + + writeRTL(CR,0x21); // stop the NIC, abort DMA, page 0 + Delay_1ms(2); // make sure nothing is coming in or going out + writeRTL(DCR, DCR_INIT); // 0x58 + writeRTL(RBCR0,0x00); + writeRTL(RBCR1,0x00); + writeRTL(RCR,0x04); + writeRTL(TPSR, TXSTART_INIT); + writeRTL(TCR,0x02); + writeRTL(PSTART, RXSTART_INIT); + writeRTL(BNRY, RXSTART_INIT); + writeRTL(PSTOP, RXSTOP_INIT); + writeRTL(CR, 0x61); + Delay_1ms(2); + writeRTL(CURR, RXSTART_INIT); + + writeRTL(PAR0+0, MYMAC_0); + writeRTL(PAR0+1, MYMAC_1); + writeRTL(PAR0+2, MYMAC_2); + writeRTL(PAR0+3, MYMAC_3); + writeRTL(PAR0+4, MYMAC_4); + writeRTL(PAR0+5, MYMAC_5); + + writeRTL(CR,0x21); + writeRTL(DCR, DCR_INIT); + writeRTL(CR,0x22); + writeRTL(ISR,0xFF); + writeRTL(IMR, IMR_INIT); + writeRTL(TCR, TCR_INIT); + + writeRTL(CR, 0x22); // start the NIC +} + + +void processRTL8019Interrupt(void) +{ + volatile unsigned char *base = (unsigned char *)0x8300; + unsigned char byte = readRTL(ISR); + + if( byte & (1< 0) { + uip_arp_out(); + rtl8019as_send(); + } + } + + for(i = 0; i < UIP_UDP_CONNS; i++) { + uip_udp_periodic(i); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + uip_arp_out(); + rtl8019as_send(); + } + } +} +/*-----------------------------------------------------------------------------------*/ +static void +rtl8019_drv_idle(void) +{ + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = rtl8019as_poll(); + if(uip_len > 0) { + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + /* debug_print16(uip_len);*/ + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + uip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + /* debug_print(PSTR("Sending packet\n"));*/ + uip_arp_out(); + rtl8019as_send(); + } + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + rtl8019as_send(); + } + } + } + /* Check the clock so see if we should call the periodic uIP + processing. */ + current = ek_clock(); + + if((current - start) >= CLK_TCK/2 || + (current - start) < 0) { + timer(); + start = current; + } +} +/*-----------------------------------------------------------------------------------*/ +LOADER_INIT_FUNC(rtl8019_drv_init) +{ + if(id == EK_ID_NONE) { + id = dispatcher_start(&p); + + arptimer = 0; + start = ek_clock(); + + rtl8019as_init(); + + dispatcher_listen(uip_signal_uninstall); + } +} +/*-----------------------------------------------------------------------------------*/ +static +DISPATCHER_SIGHANDLER(rtl8019_drv_sighandler, s, data) +{ + DISPATCHER_SIGHANDLER_ARGS(s, data); + + if(s == uip_signal_uninstall) { + dispatcher_exit(&p); + id = EK_ID_NONE; + LOADER_UNLOAD(); + } +} +/*-----------------------------------------------------------------------------------*/ diff --git a/cpu/avr/dev/rtl8019dev.c b/cpu/avr/dev/rtl8019dev.c new file mode 100644 index 000000000..50d96929a --- /dev/null +++ b/cpu/avr/dev/rtl8019dev.c @@ -0,0 +1,77 @@ +#include "net/uip.h" +#include "dev/rtl8019dev.h" + +/***************************************************************************** +* Module Name: Realtek 8019AS Driver Interface for uIP-AVR Port +* +* Created By: Louis Beaudoin (www.embedded-creations.com) +* +* Original Release: September 21, 2002 +* +* Module Description: +* Provides three functions to interface with the Realtek 8019AS driver +* These functions can be called directly from the main uIP control loop +* to send packets from uip_buf and uip_appbuf, and store incoming packets to +* uip_buf +* +* September 30, 2002 - Louis Beaudoin +* Modifications required to handle the packet receive function changes in +* rtl8019.c. There is no longer a need to poll for an empty buffer or +* an overflow. +* Added support for the Imagecraft Compiler +* +*****************************************************************************/ + + +#define IP_TCP_HEADER_LENGTH 40 +#define TOTAL_HEADER_LENGTH (IP_TCP_HEADER_LENGTH+ETHERNET_HEADER_LENGTH) + + + +void RTL8019dev_init(void) +{ + initRTL8019(); +} + + +void RTL8019dev_send(void) +{ + RTL8019beginPacketSend(uip_len); + + // send packet, using data in uip_appdata if over the IP+TCP header size + if( uip_len <= TOTAL_HEADER_LENGTH ) { + RTL8019sendPacketData(uip_buf, uip_len); + } else { + uip_len -= TOTAL_HEADER_LENGTH; + RTL8019sendPacketData(uip_buf, TOTAL_HEADER_LENGTH); + RTL8019sendPacketData((unsigned char *)uip_appdata, uip_len); + } + + RTL8019endPacketSend(); +} + + + +unsigned int RTL8019dev_poll(void) +{ + unsigned int packetLength; + + packetLength = RTL8019beginPacketRetreive(); + + // if there's no packet or an error - exit without ending the operation + if( !packetLength ) + return 0; + + // drop anything too big for the buffer + if( packetLength > UIP_BUFSIZE ) + { + RTL8019endPacketRetreive(); + return 0; + } + + // copy the packet data into the uIP packet buffer + RTL8019retreivePacketData( uip_buf, packetLength ); + RTL8019endPacketRetreive(); + + return packetLength; +} diff --git a/cpu/avr/dev/rtl8019dev.h b/cpu/avr/dev/rtl8019dev.h new file mode 100644 index 000000000..4442401d3 --- /dev/null +++ b/cpu/avr/dev/rtl8019dev.h @@ -0,0 +1,60 @@ +#ifndef __RTL8019DEV_H__ +#define __RTL8019DEV_H__ + +/***************************************************************************** +* Module Name: Realtek 8019AS Driver Interface for uIP-AVR Port +* +* Created By: Louis Beaudoin (www.embedded-creations.com) +* +* Original Release: September 21, 2002 +* +* Module Description: +* Provides three functions to interface with the Realtek 8019AS driver +* These functions can be called directly from the main uIP control loop +* to send packets from uip_buf and uip_appbuf, and store incoming packets to +* uip_buf +* +* September 30, 2002 - Louis Beaudoin +* Modifications required to handle the packet receive function changes in +* rtl8019.c. There is no longer a need to poll for an empty buffer or +* an overflow. +* Added support for the Imagecraft Compiler +* +*****************************************************************************/ + +#include "net/uip.h" +#include "dev/rtl8019.h" + +/***************************************************************************** +* RTL8019dev_init() +* Created By: Louis Beaudoin +* Date: September 21, 2002 +* Description: Power-up initialization of the RTL8019 +*****************************************************************************/ +void RTL8019dev_init(void); + + +/***************************************************************************** +* RTL8019dev_send() +* Created By: Louis Beaudoin +* Date: September 21, 2002 +* Description: Sends the packet contained in uip_buf and uip_appdata over +* the network +*****************************************************************************/ +void RTL8019dev_send(void); + + +/***************************************************************************** +* unsigned char/int RTL8019dev_poll() +* Returns: Length of the packet retreived, or zero if no packet retreived +* Created By: Louis Beaudoin +* Date: September 21, 2002 +* Description: Polls the RTL8019 looking for an overflow condition or a new +* packet in the receive buffer. If a new packet exists and +* will fit in uip_buf, it is retreived, and the length is +* returned. A packet bigger than the buffer is discarded +*****************************************************************************/ +unsigned int RTL8019dev_poll(void); + + +#endif /* __RTL8019DEV_H__ */ diff --git a/cpu/avr/dev/rtlregs.h b/cpu/avr/dev/rtlregs.h new file mode 100644 index 000000000..ae3d07d21 --- /dev/null +++ b/cpu/avr/dev/rtlregs.h @@ -0,0 +1,354 @@ +#ifndef _DEV_RTLREGS_H_ +#define _DEV_RTLREGS_H_ + +/* + * Copyright (C) 2001-2002 by egnite Software GmbH. 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. All advertising materials mentioning features or use of this + * software must display the following acknowledgement: + * + * This product includes software developed by egnite Software GmbH + * and its contributors. + * + * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH 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 EGNITE + * SOFTWARE GMBH 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. + * + * For additional information see http://www.ethernut.de/ + * + * - + * Portions Copyright (C) 2000 David J. Hudson + * + * This file is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You can redistribute this file and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software Foundation; + * either version 2 of the License, or (at your discretion) any later version. + * See the accompanying file "copying-gpl.txt" for more details. + * + * As a special exception to the GPL, permission is granted for additional + * uses of the text contained in this file. See the accompanying file + * "copying-liquorice.txt" for details. + * - + * Portions Copyright (c) 1983, 1993 by + * The Regents of the University of California. 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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. + */ + +/* + * $Log: rtlregs.h,v $ + * Revision 1.1 2006/06/17 22:41:21 adamdunkels + * Import of the contiki-2.x development code from the SICS internal CVS server + * + * Revision 1.1 2005/09/19 23:05:35 adam + * AVR device drivers + * + * Revision 1.1 2005/05/18 19:03:23 adam + * Initial import of Contiki AVR port + * + * Revision 1.1 2003/07/04 10:54:52 adamdunkels + * First version of the AVR port + * + * Revision 1.1 2003/02/05 20:49:07 adam + * *** empty log message *** + * + * Revision 1.6 2002/10/29 15:27:36 harald + * *** empty log message *** + * + * Revision 1.5 2002/06/26 17:29:08 harald + * First pre-release with 2.4 stack + * + */ + +/*! + * \brief Realtek 8019AS register definitions. + */ +/*@{*/ + +/* + * Register offset applicable to all register pages. + */ +#define NIC_CR 0x00 /*!< \brief Command register */ +#define NIC_IOPORT 0x10 /*!< \brief I/O data port */ +#define NIC_RESET 0x1f /*!< \brief Reset port */ + +/* + * Page 0 register offsets. + */ +#define NIC_PG0_CLDA0 0x01 /*!< \brief Current local DMA address 0 */ +#define NIC_PG0_PSTART 0x01 /*!< \brief Page start register */ +#define NIC_PG0_CLDA1 0x02 /*!< \brief Current local DMA address 1 */ +#define NIC_PG0_PSTOP 0x02 /*!< \brief Page stop register */ +#define NIC_PG0_BNRY 0x03 /*!< \brief Boundary pointer */ +#define NIC_PG0_TSR 0x04 /*!< \brief Transmit status register */ +#define NIC_PG0_TPSR 0x04 /*!< \brief Transmit page start address */ +#define NIC_PG0_NCR 0x05 /*!< \brief Number of collisions register */ +#define NIC_PG0_TBCR0 0x05 /*!< \brief Transmit byte count register 0 */ +#define NIC_PG0_FIFO 0x06 /*!< \brief FIFO */ +#define NIC_PG0_TBCR1 0x06 /*!< \brief Transmit byte count register 1 */ +#define NIC_PG0_ISR 0x07 /*!< \brief Interrupt status register */ +#define NIC_PG0_CRDA0 0x08 /*!< \brief Current remote DMA address 0 */ +#define NIC_PG0_RSAR0 0x08 /*!< \brief Remote start address register 0 + Low byte address to read from the buffer. */ +#define NIC_PG0_CRDA1 0x09 /*!< \brief Current remote DMA address 1 */ +#define NIC_PG0_RSAR1 0x09 /*!< \brief Remote start address register 1 + High byte address to read from the buffer. */ +#define NIC_PG0_RBCR0 0x0a /*!< \brief Remote byte count register 0 + Low byte of the number of bytes to read + from the buffer. */ +#define NIC_PG0_RBCR1 0x0b /*!< \brief Remote byte count register 1 + High byte of the number of bytes to read + from the buffer. */ +#define NIC_PG0_RSR 0x0c /*!< \brief Receive status register */ +#define NIC_PG0_RCR 0x0c /*!< \brief Receive configuration register */ +#define NIC_PG0_CNTR0 0x0d /*!< \brief Tally counter 0 (frame alignment errors) */ +#define NIC_PG0_TCR 0x0d /*!< \brief Transmit configuration register */ +#define NIC_PG0_CNTR1 0x0e /*!< \brief Tally counter 1 (CRC errors) */ +#define NIC_PG0_DCR 0x0e /*!< \brief Data configuration register */ +#define NIC_PG0_CNTR2 0x0f /*!< \brief Tally counter 2 (Missed packet errors) */ +#define NIC_PG0_IMR 0x0f /*!< \brief Interrupt mask register */ + +/* + * Page 1 register offsets. + */ +#define NIC_PG1_PAR0 0x01 /*!< \brief Physical address register 0 */ +#define NIC_PG1_PAR1 0x02 /*!< \brief Physical address register 1 */ +#define NIC_PG1_PAR2 0x03 /*!< \brief Physical address register 2 */ +#define NIC_PG1_PAR3 0x04 /*!< \brief Physical address register 3 */ +#define NIC_PG1_PAR4 0x05 /*!< \brief Physical address register 4 */ +#define NIC_PG1_PAR5 0x06 /*!< \brief Physical address register 5 */ +#define NIC_PG1_CURR 0x07 /*!< \brief Current page register + The next incoming packet will be stored + at this page address. */ +#define NIC_PG1_MAR0 0x08 /*!< \brief Multicast address register 0 */ +#define NIC_PG1_MAR1 0x09 /*!< \brief Multicast address register 1 */ +#define NIC_PG1_MAR2 0x0a /*!< \brief Multicast address register 2 */ +#define NIC_PG1_MAR3 0x0b /*!< \brief Multicast address register 3 */ +#define NIC_PG1_MAR4 0x0c /*!< \brief Multicast address register 4 */ +#define NIC_PG1_MAR5 0x0d /*!< \brief Multicast address register 5 */ +#define NIC_PG1_MAR6 0x0e /*!< \brief Multicast address register 6 */ +#define NIC_PG1_MAR7 0x0f /*!< \brief Multicast address register 7 */ + +/* + * Page 2 register offsets. + */ +#define NIC_PG2_PSTART 0x01 /*!< \brief Page start register */ +#define NIC_PG2_CLDA0 0x01 /*!< \brief Current local DMA address 0 */ +#define NIC_PG2_PSTOP 0x02 /*!< \brief Page stop register */ +#define NIC_PG2_CLDA1 0x02 /*!< \brief Current local DMA address 1 */ +#define NIC_PG2_RNP 0x03 /*!< \brief Remote next packet pointer */ +#define NIC_PG2_TSPR 0x04 /*!< \brief Transmit page start register */ +#define NIC_PG2_LNP 0x05 /*!< \brief Local next packet pointer */ +#define NIC_PG2_ACU 0x06 /*!< \brief Address counter (upper) */ +#define NIC_PG2_ACL 0x07 /*!< \brief Address counter (lower) */ +#define NIC_PG2_RCR 0x0c /*!< \brief Receive configuration register */ +#define NIC_PG2_TCR 0x0d /*!< \brief Transmit configuration register */ +#define NIC_PG2_DCR 0x0e /*!< \brief Data configuration register */ +#define NIC_PG2_IMR 0x0f /*!< \brief Interrupt mask register */ + +/* + * Page 3 register offsets. + */ +#define NIC_PG3_EECR 0x01 /*!< \brief EEPROM command register */ +#define NIC_PG3_BPAGE 0x02 /*!< \brief Boot-ROM page register */ +#define NIC_PG3_CONFIG0 0x03 /*!< \brief Configuration register 0 (r/o) */ +#define NIC_PG3_CONFIG1 0x04 /*!< \brief Configuration register 1 */ +#define NIC_PG3_CONFIG2 0x05 /*!< \brief Configuration register 2 */ +#define NIC_PG3_CONFIG3 0x06 /*!< \brief Configuration register 3 */ +#define NIC_PG3_CSNSAV 0x08 /*!< \brief CSN save register (r/o) */ +#define NIC_PG3_HLTCLK 0x09 /*!< \brief Halt clock */ +#define NIC_PG3_INTR 0x0b /*!< \brief Interrupt pins (r/o) */ + +/* + * Command register bits. + */ +#define NIC_CR_STP 0x01 /*!< \brief Stop */ +#define NIC_CR_STA 0x02 /*!< \brief Start */ +#define NIC_CR_TXP 0x04 /*!< \brief Transmit packet */ +#define NIC_CR_RD0 0x08 /*!< \brief Remote DMA command bit 0 */ +#define NIC_CR_RD1 0x10 /*!< \brief Remote DMA command bit 1 */ +#define NIC_CR_RD2 0x20 /*!< \brief Remote DMA command bit 2 */ +#define NIC_CR_PS0 0x40 /*!< \brief Page select bit 0 */ +#define NIC_CR_PS1 0x80 /*!< \brief Page select bit 1 */ + +/* + * Interrupt status register bits. + */ +#define NIC_ISR_PRX 0x01 /*!< \brief Packet received */ +#define NIC_ISR_PTX 0x02 /*!< \brief Packet transmitted */ +#define NIC_ISR_RXE 0x04 /*!< \brief Receive error */ +#define NIC_ISR_TXE 0x08 /*!< \brief Transmit error */ +#define NIC_ISR_OVW 0x10 /*!< \brief Overwrite warning */ +#define NIC_ISR_CNT 0x20 /*!< \brief Counter overflow */ +#define NIC_ISR_RDC 0x40 /*!< \brief Remote DMA complete */ +#define NIC_ISR_RST 0x80 /*!< \brief Reset status */ + +/* + * Interrupt mask register bits. + */ +#define NIC_IMR_PRXE 0x01 /*!< \brief Packet received interrupt enable */ +#define NIC_IMR_PTXE 0x02 /*!< \brief Packet transmitted interrupt enable */ +#define NIC_IMR_RXEE 0x04 /*!< \brief Receive error interrupt enable */ +#define NIC_IMR_TXEE 0x08 /*!< \brief Transmit error interrupt enable */ +#define NIC_IMR_OVWE 0x10 /*!< \brief Overwrite warning interrupt enable */ +#define NIC_IMR_CNTE 0x20 /*!< \brief Counter overflow interrupt enable */ +#define NIC_IMR_RCDE 0x40 /*!< \brief Remote DMA complete interrupt enable */ + +/* + * Data configuration register bits. + */ +#define NIC_DCR_WTS 0x01 /*!< \brief Word transfer select */ +#define NIC_DCR_BOS 0x02 /*!< \brief Byte order select */ +#define NIC_DCR_LAS 0x04 /*!< \brief Long address select */ +#define NIC_DCR_LS 0x08 /*!< \brief Loopback select */ +#define NIC_DCR_AR 0x10 /*!< \brief Auto-initialize remote */ +#define NIC_DCR_FT0 0x20 /*!< \brief FIFO threshold select bit 0 */ +#define NIC_DCR_FT1 0x40 /*!< \brief FIFO threshold select bit 1 */ + +/* + * Transmit configuration register bits. + */ +#define NIC_TCR_CRC 0x01 /*!< \brief Inhibit CRC */ +#define NIC_TCR_LB0 0x02 /*!< \brief Encoded loopback control bit 0 */ +#define NIC_TCR_LB1 0x04 /*!< \brief Encoded loopback control bit 1 */ +#define NIC_TCR_ATD 0x08 /*!< \brief Auto transmit disable */ +#define NIC_TCR_OFST 0x10 /*!< \brief Collision offset enable */ + +/* + * Transmit status register bits. + */ +#define NIC_TSR_PTX 0x01 /*!< \brief Packet transmitted */ +#define NIC_TSR_COL 0x04 /*!< \brief Transmit collided */ +#define NIC_TSR_ABT 0x08 /*!< \brief Transmit aborted */ +#define NIC_TSR_CRS 0x10 /*!< \brief Carrier sense lost */ +#define NIC_TSR_FU 0x20 /*!< \brief FIFO underrun */ +#define NIC_TSR_CDH 0x40 /*!< \brief CD heartbeat */ +#define NIC_TSR_OWC 0x80 /*!< \brief Out of window collision */ + +/* + * Receive configuration register bits. + */ +#define NIC_RCR_SEP 0x01 /*!< \brief Save errored packets */ +#define NIC_RCR_AR 0x02 /*!< \brief Accept runt packets */ +#define NIC_RCR_AB 0x04 /*!< \brief Accept broadcast */ +#define NIC_RCR_AM 0x08 /*!< \brief Accept multicast */ +#define NIC_RCR_PRO 0x10 /*!< \brief Promiscuous physical */ +#define NIC_RCR_MON 0x20 /*!< \brief Monitor mode */ + +/* + * Receive status register bits. + */ +#define NIC_RSR_PRX 0x01 /*!< \brief Packet received intact */ +#define NIC_RSR_CRC 0x02 /*!< \brief CRC error */ +#define NIC_RSR_FAE 0x04 /*!< \brief Frame alignment error */ +#define NIC_RSR_FO 0x08 /*!< \brief FIFO overrun */ +#define NIC_RSR_MPA 0x10 /*!< \brief Missed packet */ +#define NIC_RSR_PHY 0x20 /*!< \brief Physical/multicast address */ +#define NIC_RSR_DIS 0x40 /*!< \brief Receiver disabled */ +#define NIC_RSR_DFR 0x80 /*!< \brief Deferring */ + +/* + * EEPROM command register bits. + */ +#define NIC_EECR_EEM1 0x80 /*!< \brief EEPROM Operating Mode */ +#define NIC_EECR_EEM0 0x40 /*!< \brief EEPROM Operating Mode + - 0 0 Normal operation + - 0 1 Auto-load + - 1 0 9346 programming + - 1 1 Config register write enab */ +#define NIC_EECR_EECS 0x08 /*!< \brief EEPROM Chip Select */ +#define NIC_EECR_EESK 0x04 /*!< \brief EEPROM Clock */ +#define NIC_EECR_EEDI 0x02 /*!< \brief EEPROM Data In */ +#define NIC_EECR_EEDO 0x01 /*!< \brief EEPROM Data Out */ + +/* + * Configuration register 2 bits. + */ +#define NIC_CONFIG2_PL1 0x80 /*!< \brief Network media type */ +#define NIC_CONFIG2_PL0 0x40 /*!< \brief Network media type + - 0 0 TP/CX auto-detect + - 0 1 10baseT + - 1 0 10base5 + - 1 1 10base2 */ +#define NIC_CONFIG2_BSELB 0x20 /*!< \brief BROM disable */ +#define NIC_CONFIG2_BS4 0x10 /*!< \brief BROM size/base */ +#define NIC_CONFIG2_BS3 0x08 +#define NIC_CONFIG2_BS2 0x04 +#define NIC_CONFIG2_BS1 0x02 +#define NIC_CONFIG2_BS0 0x01 + +/* + * Configuration register 3 bits + */ +#define NIC_CONFIG3_PNP 0x80 /*!< \brief PnP Mode */ +#define NIC_CONFIG3_FUDUP 0x40 /*!< \brief Full duplex */ +#define NIC_CONFIG3_LEDS1 0x20 /*!< \brief LED1/2 pin configuration + - 0 LED1 == LED_RX, LED2 == LED_TX + - 1 LED1 == LED_CRS, LED2 == MCSB */ +#define NIC_CONFIG3_LEDS0 0x10 /*!< \brief LED0 pin configration + - 0 LED0 pin == LED_COL + - 1 LED0 pin == LED_LINK */ +#define NIC_CONFIG3_SLEEP 0x04 /*!< \brief Sleep mode */ +#define NIC_CONFIG3_PWRDN 0x02 /*!< \brief Power Down */ +#define NIC_CONFIG3_ACTIVEB 0x01 /*!< \brief inverse of bit 0 in PnP Act Reg */ + +/*@}*/ + +/*! + * \brief Read byte from controller register. + */ +#define nic_read(reg) *(base + (reg)) + +/*! + * \brief Write byte to controller register. + */ +#define nic_write(reg, data) *(base + (reg)) = data + +#endif diff --git a/cpu/msp430/Makefile.msp430 b/cpu/msp430/Makefile.msp430 new file mode 100644 index 000000000..5fa485716 --- /dev/null +++ b/cpu/msp430/Makefile.msp430 @@ -0,0 +1,128 @@ +# $Id: Makefile.msp430,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + +### Check if we are running under Windows + +ifndef WINDIR + ifdef OS + ifneq (,$(findstring Windows,$(OS))) + WINDIR := Windows + endif + endif +endif + +.SUFFIXES: + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/msp430 + +### Define the source files we have in the MSP430 port + +MSP430 = msp430.c eeprom.c flash.c clock.c leds.c leds-arch.c \ + watchdog.c lpm.c cfs-eeprom.c +UIPDRIVERS = me.c me_tabs.c slip.c crc16.c +#UIPDRIVERS = me.c me_tabs.c crc16.c ppp/ahdlc.c ppp/ipcp.c ppp/lcp.c ppp/pap.c ppp/ppp.c ppp/ppp_process.c +SYSAPPS = codeprop-tmp.c +APPDIRS += $(CONTIKI)/apps/codeprop +#ELFLOADER = loader-arch.c elfloader-tmp.c elfloader-msp430.c symtab.c +ELFLOADER = elfloader-tmp.c elfloader-msp430.c symtab.c +TARGETLIBS = random.c serial.c + +CONTIKI_TARGET_SOURCEFILES += $(MSP430) \ + $(SYSAPPS) $(ELFLOADER) \ + $(TARGETLIBS) $(UIPDRIVERS) + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + + +### Compiler definitions +CC = msp430-gcc +LD = msp430-ld +AS = msp430-as +AR = msp430-ar +OBJCOPY = msp430-objcopy +STRIP = msp430-strip +BSL = msp430-bsl +CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) \ + -I$(CONTIKI)/platform/$(TARGET) \ + ${addprefix -I,$(APPDIRS)} \ + -DWITH_UIP -DWITH_ASCII \ + -Wall -mmcu=$(MCU) -g +CFLAGS += $(CFLAGSNO) -Os +LDFLAGS = -mmcu=$(MCU) -Wl,-Map=contiki-$(TARGET).map + +PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)} + +### Setup directory search path for source files + +CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \ + $(CONTIKI_TARGET_DIRS)} + +vpath %.c $(PROJECTDIRS) \ + $(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ + $(CONTIKI_CPU) + +### Compilation rules + + +%-stripped.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + $(STRIP) --strip-unneeded -g -x $@ + +%.cm: %.co + $(LD) -i -r --unresolved-symbols=ignore-in-object-files -mmsp430x149 -o $@ $^ + $(STRIP) --strip-unneeded -g -x $@ + +%-stripped.o: %.o + $(STRIP) --strip-unneeded -g -x -o $@ $< + +%.o: ${CONTIKI_TARGET}/loader/%.S + $(AS) -o $(notdir $(<:.S=.o)) $< + +%.firmware: %.co $(PROJECT_OBJECTFILES) contiki-$(TARGET).a + $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(filter-out %.a,$^) $(filter %.a,$^) + + +# %.firmware: %.o contiki-esb-main.o contikiesb.a +# $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(filter-out %.a,$^) $(filter %.a,$^) + +%.ihex: %.firmware + $(OBJCOPY) $^ -O ihex $@ + +core-labels.o: core.firmware + ${CONTIKI}/tools/msp430-make-labels core.firmware > core-labels.S + $(AS) -o $@ core-labels.S +# cp core-labels.o app/ + +core-globals.o: core.firmware + ${CONTIKI}/tools/msp430-make-globals core.firmware > core-globals.S + $(AS) -o $@ core-globals.S + +loader-init.o: ${CONTIKI_TARGET}/loader/loader-init.S + $(AS) -o $(notdir $(<:.S=.o)) $< +# cp loader-init.o build-app/ + +.PHONY: symbols.c +symbols.c: + ${CONTIKI}/tools/msp430-make-symbols core.firmware > symbols.c + +### System dependent Makefile + +ifndef WINDIR + # settings for unix + -include ${CONTIKI}/cpu/msp430/buildscripts/Makefile.unix +else + # settings for windows + -include ${CONTIKI}/cpu/msp430/buildscripts/Makefile.win +endif + + +### Node id ### + +.PHONY: node-id.c +ifndef $(nodeid) + nodeid := 0 +endif +node-id.c: + @-rm -f $@ + @echo >$@ "const unsigned short node_id = $(nodeid);" + @echo ">>>> NODE ID SET TO $(nodeid)!" diff --git a/cpu/msp430/button.c b/cpu/msp430/button.c new file mode 100644 index 000000000..65764af72 --- /dev/null +++ b/cpu/msp430/button.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: button.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include +#include + +#include "contiki.h" + +#include "dev/lpm.h" + +#include "dev/button.h" + +#define BUTTON_PORT 2 +#define BUTTON_PIN 7 + +static struct button_msg button_msg; + +static struct process *selecting_proc; + +void +button_init(struct process *proc) +{ + button_msg.type = BUTTON_MSG_TYPE; + + P2DIR &= ~BV(BUTTON_PIN); + P2SEL &= ~BV(BUTTON_PIN); + + P2IES |= BV(BUTTON_PIN); + P2IFG &= ~BV(BUTTON_PIN); + + selecting_proc = proc; + if(proc != NULL) + P2IE |= BV(BUTTON_PIN); + else + P2IE &= ~BV(BUTTON_PIN); +} + +interrupt(PORT2_VECTOR) +__button_interrupt(void) +{ + static struct timer debouncetimer; + + P2IFG &= ~BV(BUTTON_PIN); + if(timer_expired(&debouncetimer)) { + button_msg.value = P2IN & BV(BUTTON_PIN); + timer_set(&debouncetimer, CLOCK_SECOND/4); + if(selecting_proc != NULL) { + process_post(selecting_proc, PROCESS_EVENT_MSG, &button_msg); + } + LPM_AWAKE(); + } +} diff --git a/cpu/msp430/cc2420_uart0.c b/cpu/msp430/cc2420_uart0.c new file mode 100644 index 000000000..d828b907c --- /dev/null +++ b/cpu/msp430/cc2420_uart0.c @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: cc2420_uart0.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include +#include + +#include "contiki.h" +#include "contiki-net.h" + +#include "dev/lpm.h" +#include "dev/spi.h" +#include "dev/cc2420.h" + +interrupt(PORT1_VECTOR) +__fifop_interrupt(void) +{ + if(__cc2420_intr()) + LPM_AWAKE(); +} + +void +__cc2420_arch_init(void) +{ + spi_init(); + + P4DIR |= BV(CSN) | BV(VREG_EN) | BV(RESET_N); + + SPI_DISABLE(); /* Unselect radio. */ +} diff --git a/cpu/msp430/clock.c b/cpu/msp430/clock.c new file mode 100644 index 000000000..2abdee65a --- /dev/null +++ b/cpu/msp430/clock.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: clock.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + + +#include +#include + +#include "contiki-conf.h" + +#include "dev/lpm.h" + +#include "sys/clock.h" +#include "sys/etimer.h" + +/* 38400 cycles @ 2.4576MHz with divisor 8 ==> 1/8 s */ +/* #define INTERVAL (307200ULL / CLOCK_SECOND) */ +#define INTERVAL (4096ULL / CLOCK_SECOND) + +static volatile clock_time_t count = 0; +/*---------------------------------------------------------------------------*/ +interrupt(TIMERA1_VECTOR) timera1 (void) { + if(TAIV == 2) { + TACCR1 += INTERVAL; + ++count; + + if(etimer_pending() && count >= etimer_next_expiration_time()) { +/* if(etimer_pending()) { */ + etimer_request_poll(); + LPM_AWAKE(); + } + } +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + return count; +} +/*---------------------------------------------------------------------------*/ +void +clock_set(clock_time_t clock, clock_time_t fclock) +{ + TAR = fclock; + TACCR1 = fclock + INTERVAL; + count = clock; +} +/*---------------------------------------------------------------------------*/ +void +clock_init(void) +{ + dint(); + + /* Select SMCLK (2.4576MHz), clear TAR */ +/* TACTL = TASSEL1 | TACLR | ID_3; */ + TACTL = TASSEL0 | TACLR | ID_3; + + /* Initialize ccr1 to create the X ms interval. */ + /* CCR1 interrupt enabled, interrupt occurs when timer equals CCR1. */ + TACCTL1 = CCIE; + + /* Interrupt after X ms. */ + TACCR1 = INTERVAL; + + /* Start Timer_A in continuous mode. */ + TACTL |= MC1; + + count = 0; + + BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */ + + /* Enable interrupts. */ + eint(); + +} +/*---------------------------------------------------------------------------*/ +/** + * Delay the CPU for a multiple of 2.83 us. + */ +void +clock_delay(unsigned int i) +{ + asm("add #-1, r15"); + asm("jnz $-2"); + /* + * This means that delay(i) will delay the CPU for CONST + 3x + * cycles. On a 2.4756 CPU, this means that each i adds 1.22us of + * delay. + * + * do { + * --i; + * } while(i > 0); + */ +} +/*---------------------------------------------------------------------------*/ +/** + * Wait for a multiple of 10 ms. + * + */ +void +clock_wait(int i) +{ + clock_time_t start; + + start = clock_time(); + while(clock_time() - start < (clock_time_t)i); +} +/*---------------------------------------------------------------------------*/ +void +clock_set_seconds(unsigned long sec) +{ + +} +unsigned long +clock_seconds(void) +{ + return count / CLOCK_SECOND; +} diff --git a/cpu/msp430/dev/button.h b/cpu/msp430/dev/button.h new file mode 100644 index 000000000..840d0176c --- /dev/null +++ b/cpu/msp430/dev/button.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: button.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#ifndef BUTTON_H +#define BUTTON_H + +#define BUTTON_MSG_TYPE 1 + +struct button_msg { + u8_t type; + u8_t value; +}; + +void button_init(struct process *proc); + +#endif /* BUTTON_H */ diff --git a/cpu/msp430/dev/flash.h b/cpu/msp430/dev/flash.h new file mode 100644 index 000000000..447c87793 --- /dev/null +++ b/cpu/msp430/dev/flash.h @@ -0,0 +1,78 @@ +/** + * \file + * Functions for reading and writing MSP430 flash ROM. + * \author Adam Dunkels + */ + +/* Copyright (c) 2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * $Id: flash.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + * Author: Adam Dunkels + * + */ + +#ifndef __FLASH_H__ +#define __FLASH_H__ + +/** + * Setup function to be called before any of the flash programming functions. + * + */ +void flash_setup(void); + +/** + * Function that is to be called after flashing is done. + */ +void flash_done(void); + +/** + * Write a 16-bit word to flash ROM. + * + * This function writes a 16-bit word to flash ROM. The function + * flash_setup() must have been called first. + * + * \param addr A pointer to the address in flash ROM which is to be + * written. + * + * \param word The 16-bit word that is to be written. + */ +void flash_write(unsigned short *addr, unsigned short word); + +/** + * Clear a 16-bit word in flash ROM. + * + * This function clears a 16-bit word in flash ROM. The function + * flash_setup() must have been called first. + * + * \param addr A pointer to the address in flash ROM which is to be + * cleared. + */ +void flash_clear(unsigned short *addr); + +#endif /* __FLASH_H__ */ diff --git a/cpu/msp430/dev/hwconf.h b/cpu/msp430/dev/hwconf.h new file mode 100644 index 000000000..8272984b1 --- /dev/null +++ b/cpu/msp430/dev/hwconf.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: hwconf.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ +#ifndef __HWCONF_H__ +#define __HWCONF_H__ + +#include "sys/cc.h" + +#include + +#define HWCONF_PIN(name, port, bit) \ +static CC_INLINE void name##_SELECT() {P##port##SEL &= ~(1 << bit);} \ +static CC_INLINE void name##_SET() {P##port##OUT |= 1 << bit;} \ +static CC_INLINE void name##_CLEAR() {P##port##OUT &= ~(1 << bit);} \ +static CC_INLINE int name##_READ() {return (P##port##IN & (1 << bit));} \ +static CC_INLINE void name##_MAKE_OUTPUT() {P##port##DIR |= 1 << bit;} \ +static CC_INLINE void name##_MAKE_INPUT() {P##port##DIR &= ~(1 << bit);} + +#define HWCONF_IRQ(name, port, bit) \ +static CC_INLINE void name##_ENABLE_IRQ() {P##port##IE |= 1 << bit;} \ +static CC_INLINE void name##_DISABLE_IRQ() {P##port##IE &= ~(1 << bit);} \ +static CC_INLINE int name##_IRQ_ENABLED() {return P##port##IE & (1 << bit);} \ +static CC_INLINE void name##_IRQ_EDGE_SELECTD() {P##port##IES |= 1 << bit;} \ +static CC_INLINE void name##_IRQ_EDGE_SELECTU() {P##port##IES &= ~(1 << bit);}\ +static CC_INLINE int name##_CHECK_IRQ() {return P##port##IFG & (1 << bit);} \ +static CC_INLINE int name##_IRQ_PORT() {return IRQ_PORT##port;} + +#endif /* __HWCONF_H__ */ diff --git a/cpu/msp430/dev/lpm.h b/cpu/msp430/dev/lpm.h new file mode 100644 index 000000000..b921aaf59 --- /dev/null +++ b/cpu/msp430/dev/lpm.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: lpm.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ +#ifndef __LPM_H__ +#define __LPM_H__ + +#include +#include "contiki-conf.h" + +#ifdef LPM_CONF_ON +#define LPM_ON LPM_CONF_ON +#else +#define LPM_ON LPM1 +#endif /* LPM_CONF_ON */ + +#ifdef LPM_CONF_OFF +#define LPM_OFF LPM_CONF_OFF +#else +#define LPM_OFF LPM1_EXIT +#endif /* LPM_CONF_OFF */ + +#define LPM_SLEEP() do { if(lpm_status == LPM_STATUS_ON) LPM_ON; } while(0) +#define LPM_AWAKE() do { if(lpm_status == LPM_STATUS_ON) LPM_OFF; } while(0) + +extern unsigned char lpm_status; + +void lpm_on(void); +void lpm_off(void); + +#define LPM_STATUS_OFF 0 +#define LPM_STATUS_ON 1 + + +#endif /* __LPM_H__ */ diff --git a/cpu/msp430/flash.c b/cpu/msp430/flash.c new file mode 100644 index 000000000..f579ac0a1 --- /dev/null +++ b/cpu/msp430/flash.c @@ -0,0 +1,109 @@ +/** + * \file + * Functions for reading and writing flash ROM. + * \author Adam Dunkels + */ + +/* Copyright (c) 2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * $Id: flash.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + * Author: Adam Dunkels + * + */ + +#include +#include +#include + +#include "dev/flash.h" + +#define FLASH_TIMEOUT 30 +#define FLASH_REQ_TIMEOUT 150 + +static unsigned short ie1, ie2; + +/*---------------------------------------------------------------------------*/ +void +flash_setup(void) +{ + + /* Disable all interrupts. */ + + /* Clear interrupt flag1. */ + IFG1 = 0; + + /* Stop watchdog. */ + WDTCTL = 0x5A80; + + /* DCO(SMCLK) is 2,4576MHz, /6 = 409600 Hz + select SMCLK for flash timing, divider 5+1 */ + FCTL2 = 0xA5C5; + + /* disable all interrupts to protect CPU + during programming from system crash */ + _DINT(); + + /* disable all NMI-Interrupt sources */ + ie1 = IE1; + ie2 = IE2; + IE1 = 0x00; + IE2 = 0x00; +} +/*---------------------------------------------------------------------------*/ +void +flash_done(void) +{ + /* Enable interrupts. */ + IE1 = ie1; + IE2 = ie2; + _EINT(); +} +/*---------------------------------------------------------------------------*/ +void +flash_clear(unsigned short *ptr) +{ + FCTL3 = 0xA500; /* Lock = 0 */ + while(FCTL3 & 0x0001) nop(); /* Wait for BUSY = 0, not needed + unless run from RAM */ + FCTL1 = 0xA502; /* ERASE = 1 */ + *ptr = 0; /* erase Flash segment */ + FCTL1 = 0xA500; /* ERASE = 0 automatically done?! */ + FCTL3 = 0xA510; /* Lock = 1 */ +} +/*---------------------------------------------------------------------------*/ +void +flash_write(unsigned short *ptr, unsigned short word) +{ + FCTL3 = 0xA500; /* Lock = 0 */ + while(FCTL3 & 0x0001) nop(); /* Wait for BUSY = 0, not needed unless + run from RAM */ + FCTL1 = 0xA540; /* WRT = 1 */ + *ptr = word; /* program Flash word */ + FCTL1 = 0xA500; /* WRT = 0 */ + FCTL3 = 0xA510; /* Lock = 1 */ +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/leds-arch.c b/cpu/msp430/leds-arch.c new file mode 100644 index 000000000..1b244cc45 --- /dev/null +++ b/cpu/msp430/leds-arch.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: leds-arch.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-03 + * Updated : $Date: 2006/06/17 22:41:21 $ + * $Revision: 1.1 $ + */ + +#include "contiki-conf.h" +#include "dev/leds.h" + +#include + +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + LEDS_PxDIR |= (LEDS_CONF_RED | LEDS_CONF_GREEN | LEDS_CONF_YELLOW); + LEDS_PxOUT |= (LEDS_CONF_RED | LEDS_CONF_GREEN | LEDS_CONF_YELLOW); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return ((LEDS_PxOUT & LEDS_CONF_RED) ? 0 : LEDS_RED) + | ((LEDS_PxOUT & LEDS_CONF_GREEN) ? 0 : LEDS_GREEN) + | ((LEDS_PxOUT & LEDS_CONF_YELLOW) ? 0 : LEDS_YELLOW); +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + LEDS_PxOUT = (LEDS_PxOUT & ~(LEDS_CONF_RED|LEDS_CONF_GREEN|LEDS_CONF_YELLOW)) + | ((leds & LEDS_RED) ? 0 : LEDS_CONF_RED) + | ((leds & LEDS_GREEN) ? 0 : LEDS_CONF_GREEN) + | ((leds & LEDS_YELLOW) ? 0 : LEDS_CONF_YELLOW); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/loader-arch.c b/cpu/msp430/loader-arch.c new file mode 100644 index 000000000..fb3f0bc36 --- /dev/null +++ b/cpu/msp430/loader-arch.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: loader-arch.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include "contiki.h" +#include "sys/clock.h" + +#include "net/uip.h" + +#include "dev/leds.h" +#include "dev/eeprom.h" +#include "dev/flash.h" + +#include "loader/loader-arch.h" + +void *loader_arch_codeaddr, *loader_arch_dataaddr; + + +#define FLASHADDR ((char *)0x8000) +#define DATAADDR ((char *)0x900) +#define READSIZE 0x10 + +#define beep(n) do { } while (0) +#define beep_beep(n) do { } while (0) + +/*----------------------------------------------------------------------------------*/ +void +loader_arch_load(unsigned short startaddr) +{ + unsigned short tmp; + unsigned short codelen, datalen, sumlen; + int i, j; + unsigned short ptr; + unsigned short *flashptr; + void (* init)(void *); + unsigned char tmpdata[READSIZE]; + unsigned char sum; + + /* Read the magic word and version number from the first four bytes + in EEPROM. */ + eeprom_read(startaddr, (char *)&tmp, 2); + if(tmp != HTONS(LOADER_ARCH_MAGIC)) { + beep_beep(60000); + return; + } + + eeprom_read(startaddr + 2, (char *)&tmp, 2); + if(tmp != HTONS(LOADER_ARCH_VERSION)) { + return; + } + + startaddr += 4; + + /* Read the total lenghth that the checksum covers. */ + eeprom_read(startaddr, (char *)&sumlen, 2); + + sumlen = htons(sumlen); + + sum = 0; + + for(i = 0; sumlen - i > READSIZE; i += READSIZE) { + eeprom_read(startaddr + 2 + i, tmpdata, READSIZE); + + for(j = 0; j < READSIZE; ++j) { + sum += tmpdata[j]; + if(sum < tmpdata[j]) { + ++sum; + } + } + } + if(sumlen - i > 0) { + eeprom_read(startaddr + 2 + i, tmpdata, READSIZE); + + for(j = 0; j < sumlen - i; ++j) { + sum += tmpdata[j]; + if(sum < tmpdata[j]) { + ++sum; + } + } + } + + /* If the checksum was wrong, we beep. The number of beeps indicate + the numerival value of the calculated checksum. */ + if(sum != 0xff) { + leds_red(LEDS_ON); + + for(i = 0; i < (sum >> 4); ++i) { + beep_beep(200); + for(j = 0; j < 2; ++j) { + clock_delay(60000); + } + } + + for(j = 0; j < 8; ++j) { + clock_delay(60000); + } + + for(i = 0; i < (sum & 0x0f); ++i) { + beep_beep(200); + for(j = 0; j < 2; ++j) { + clock_delay(60000); + } + } + + leds_red(LEDS_OFF); + + return; + + } else { + leds_green(LEDS_ON); + for(i = 0; i < 4; ++i) { + beep_beep(200); + for(j = 0; j < 2; ++j) { + clock_delay(60000); + } + } + leds_green(LEDS_OFF); + } + + + leds_yellow(LEDS_ON); + startaddr += 2; + + /* Read the size of the code segment from the next two bytes in EEPROM. */ + eeprom_read(startaddr, (char *)&codelen, 2); + /* Convert from network byte order to host byte order. */ + codelen = htons(codelen); + + + /* Flash program code into ROM. We use the available space in the + program's data memory to temporarily store the code before + flashing it into ROM. */ + flash_setup(); + + flashptr = (unsigned short *)FLASHADDR; + for(ptr = startaddr + 2; ptr < startaddr + 2 + codelen; ptr += READSIZE) { + + /* Read data from EEPROM into RAM. */ + eeprom_read(ptr, DATAADDR, READSIZE); + + /* Clear flash page on 512 byte boundary. */ + if((((unsigned short)flashptr) & 0x01ff) == 0) { + flash_clear(flashptr); + } + + /* Burn data from RAM into flash ROM. Flash is burned one 16-bit + word at a time, so we need to be careful when incrementing + pointers. The flashptr is already a short pointer, so + incrementing it by one will actually increment the address by + two. */ + for(i = 0; i < READSIZE / 2; ++i) { + flash_write(flashptr, ((unsigned short *)DATAADDR)[i]); + ++flashptr; + } + } + + flash_done(); + + leds_yellow(LEDS_OFF); + + leds_green(LEDS_ON); + + /* Read the size of the code segment from the first two bytes in EEPROM. */ + eeprom_read(startaddr + 2 + codelen, (char *)&datalen, 2); + + /* Convert from network byte order to host byte order. */ + datalen = htons(datalen); + + if(datalen > 0) { + /* Read the contents of the data memory into RAM. */ + eeprom_read(startaddr + 2 + codelen + 2, DATAADDR, datalen); + } + + for(i = 0; i < 4; ++i) { + beep_beep(2000); + clock_delay(20000); + } + + leds_green(LEDS_OFF); + + /* Execute the loaded program. */ + init = ((void (*)(void *))FLASHADDR); + init((void *)0); +} +/*----------------------------------------------------------------------------------*/ +void +loader_arch_free(void *code, void *data) +{ +} +/*----------------------------------------------------------------------------------*/ diff --git a/cpu/msp430/lpm.c b/cpu/msp430/lpm.c new file mode 100644 index 000000000..19507b726 --- /dev/null +++ b/cpu/msp430/lpm.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: lpm.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ +#include "dev/lpm.h" + +unsigned char lpm_status = LPM_STATUS_OFF; + +/*---------------------------------------------------------------------------*/ +void +lpm_on(void) +{ + lpm_status = LPM_STATUS_ON; +} +/*---------------------------------------------------------------------------*/ +void +lpm_off(void) +{ + lpm_status = LPM_STATUS_OFF; +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/msp430.c b/cpu/msp430/msp430.c new file mode 100644 index 000000000..d13ece846 --- /dev/null +++ b/cpu/msp430/msp430.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: msp430.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ +#include +#include + +#include "net/uip.h" + +/*---------------------------------------------------------------------------*/ +void +msp430_init_dco(void) +{ + /* This code taken from the FU Berlin sources and reformatted. */ +#define DELTA 600 + + unsigned int compare, oldcapture = 0; + unsigned int i; + + + BCSCTL1 = 0xa4; /* ACLK is devided by 4. RSEL=6 no division for MCLK + and SSMCLK. XT2 is off. */ + + BCSCTL2 = 0x00; /* Init FLL to desired frequency using the 32762Hz + crystal DCO frquenzy = 2,4576 MHz */ + + WDTCTL = WDTPW + WDTHOLD; /* Stop WDT */ + BCSCTL1 |= DIVA1 + DIVA0; /* ACLK = LFXT1CLK/8 */ + for(i = 0xffff; i > 0; i--); /* Delay for XTAL to settle */ + + CCTL2 = CCIS0 + CM0 + CAP; // Define CCR2, CAP, ACLK + TACTL = TASSEL1 + TACLR + MC1; // SMCLK, continous mode + + + while(1) { + + while((CCTL2 & CCIFG) != CCIFG); /* Wait until capture occured! */ + CCTL2 &= ~CCIFG; /* Capture occured, clear flag */ + compare = CCR2; /* Get current captured SMCLK */ + compare = compare - oldcapture; /* SMCLK difference */ + oldcapture = CCR2; /* Save current captured SMCLK */ + + if(DELTA == compare) { + break; /* if equal, leave "while(1)" */ + } else if(DELTA < compare) { /* DCO is too fast, slow it down */ + DCOCTL--; + if(DCOCTL == 0xFF) { /* Did DCO role under? */ + BCSCTL1--; + } + } else { /* -> Select next lower RSEL */ + DCOCTL++; + if(DCOCTL == 0x00) { /* Did DCO role over? */ + BCSCTL1++; + } + /* -> Select next higher RSEL */ + } + } + + CCTL2 = 0; /* Stop CCR2 function */ + TACTL = 0; /* Stop Timer_A */ + + BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */ +} +/*---------------------------------------------------------------------------*/ +static void +init_ports(void) +{ + /* Turn everything off, device drivers are supposed to enable what is + * really needed! + */ + + /* All configured for digital I/O */ +#ifdef P1SEL + P1SEL = 0; +#endif +#ifdef P2SEL + P2SEL = 0; +#endif +#ifdef P3SEL + P3SEL = 0; +#endif +#ifdef P4SEL + P4SEL = 0; +#endif +#ifdef P5SEL + P5SEL = 0; +#endif +#ifdef P6SEL + P6SEL = 0; +#endif + + /* All available inputs */ +#ifdef P1DIR + P1DIR = 0; + P1OUT = 0; +#endif +#ifdef P2DIR + P2DIR = 0; + P2OUT = 0; +#endif +#ifdef P3DIR + P3DIR = 0; + P3OUT = 0; +#endif +#ifdef P4DIR + P4DIR = 0; + P4OUT = 0; +#endif + +#ifdef P5DIR + P5DIR = 0; + P5OUT = 0; +#endif + +#ifdef P6DIR + P6DIR = 0; + P6OUT = 0; +#endif + + P1IE = 0; + P2IE = 0; +} +/*---------------------------------------------------------------------------*/ +void +msp430_cpu_init(void) +{ + dint(); + init_ports(); + msp430_init_dco(); + eint(); +} + +#define asmv(arg) __asm__ __volatile__(arg) + +/* + * Mask all interrupts that can be masked. + */ +int +splhigh_(void) +{ + /* Clear the GIE (General Interrupt Enable) flag. */ + int sr; + asmv("mov r2, %0" : "=r" (sr)); + asmv("bic %0, r2" : : "i" (GIE)); + return sr & GIE; /* Ignore other sr bits. */ +} + +/* + * Restore previous interrupt mask. + */ +void +splx_(int sr) +{ + /* If GIE was set, restore it. */ + asmv("bis %0, r2" : : "r" (sr)); +} + +#ifdef UIP_ARCH_IPCHKSUM +u16_t +uip_ipchksum(void) +{ + /* Assumes proper alignement of uip_buf. */ + u16_t *p = (u16_t *)&uip_buf[UIP_LLH_LEN]; + register u16_t sum; + + sum = p[0]; + asmv("add %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[1])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[2])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[3])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[4])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[5])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[6])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[7])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[8])); + asmv("addc %[p], %[sum]": [sum] "+r" (sum): [p] "m" (p[9])); + + /* Finally, add the remaining carry bit. */ + asmv("addc #0, %[sum]": [sum] "+r" (sum)); + + /* Return sum in network byte order. */ + return (sum == 0) ? 0xffff : sum; +} +#endif diff --git a/cpu/msp430/mtarch.c b/cpu/msp430/mtarch.c new file mode 100644 index 000000000..3340c0966 --- /dev/null +++ b/cpu/msp430/mtarch.c @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: mtarch.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include +#include "mt.h" + + +/*--------------------------------------------------------------------------*/ +void +mtarch_init(void) +{ + +} +/*--------------------------------------------------------------------------*/ +void +mtarch_start(struct mtarch_thread *t, + void (*function)(void *), void *data) +{ + + t->sp = &t->stack[MTARCH_STACKSIZE - 1]; + + *t->sp = (unsigned short)mt_exit; + --t->sp; + *t->sp = (unsigned short)function; + --t->sp; + + /* Space for registers. */ + t->sp -= 11; + +} +/*--------------------------------------------------------------------------*/ +static unsigned short *sptmp; +static struct mtarch_thread *running; + +static void +sw(void) +{ + + sptmp = running->sp; + + __asm__("push r4"); + __asm__("push r5"); + __asm__("push r6"); + __asm__("push r7"); + __asm__("push r8"); + __asm__("push r9"); + __asm__("push r10"); + __asm__("push r11"); + __asm__("push r12"); + __asm__("push r13"); + __asm__("push r14"); + __asm__("push r15"); + + __asm__("mov.w r1,%0" : "=r" (running->sp)); + __asm__("mov.w %0,r1" : : "m" (sptmp)); + + __asm__("pop r15"); + __asm__("pop r14"); + __asm__("pop r13"); + __asm__("pop r12"); + __asm__("pop r11"); + __asm__("pop r10"); + __asm__("pop r9"); + __asm__("pop r8"); + __asm__("pop r7"); + __asm__("pop r6"); + __asm__("pop r5"); + __asm__("pop r4"); +} +/*--------------------------------------------------------------------------*/ +void +mtarch_exec(struct mtarch_thread *t) +{ + running = t; + sw(); + running = NULL; +} +/*--------------------------------------------------------------------------*/ +void +mtarch_remove(void) +{ + +} +/*--------------------------------------------------------------------------*/ +void +mtarch_yield(void) +{ + sw(); +} +/*--------------------------------------------------------------------------*/ +void +mtarch_pstop(void) +{ + +} +/*--------------------------------------------------------------------------*/ +void +mtarch_pstart(void) +{ + +} +/*--------------------------------------------------------------------------*/ diff --git a/cpu/msp430/mtarch.h b/cpu/msp430/mtarch.h new file mode 100644 index 000000000..c4d70e3bb --- /dev/null +++ b/cpu/msp430/mtarch.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: mtarch.h,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ + +#define MTARCH_STACKSIZE 64 + +struct mtarch_thread { + unsigned short stack[MTARCH_STACKSIZE]; + unsigned short *sp; +}; + +#endif /* __MTARCH_H__ */ + diff --git a/cpu/msp430/rom.c b/cpu/msp430/rom.c new file mode 100644 index 000000000..7add158c6 --- /dev/null +++ b/cpu/msp430/rom.c @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: rom.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include + +#include "contiki.h" + +#include "dev/rom.h" + +struct ictx { + int s; + unsigned short ie1, ie2, wdtctl; +}; + +static void +mask_intr(struct ictx *c) +{ + /* Disable all interrupts. */ + c->s = splhigh(); + +#define WDTRPW 0x6900 /* Watchdog key returned by read */ + + /* Disable all NMI-Interrupt sources */ + c->wdtctl = WDTCTL; + c->wdtctl ^= (WDTRPW ^ WDTPW); + WDTCTL = WDTPW | WDTHOLD; + c->ie1 = IE1; + IE1 = 0x00; + c->ie2 = IE2; + IE2 = 0x00; + + /* MSP430F1611 257 < f < 476 kHz, 2.4576MHz/(5+1) = 409.6 kHz. */ + FCTL2 = FWKEY | FSSEL_SMCLK | (FN2 | FN1); + FCTL3 = FWKEY; /* Unlock flash. */ +} + +static void +rest_intr(struct ictx *c) +{ + FCTL1 = FWKEY; /* Disable erase or write. */ + FCTL3 = FWKEY | LOCK; /* Lock flash. */ + /* Restore interrupts. */ + IE2 = c->ie2; + IE1 = c->ie1; + WDTCTL = c->wdtctl; + splx(c->s); +} + +/* + * This helper routine must reside in RAM! + */ +static void +blkwrt(void *to, const void *from, const void *from_end) + // __attribute__ ((section(".data"))) + ; + +int +rom_erase(long nbytes, off_t offset) +{ + int nb = nbytes; + char *to = (char *)(uintptr_t)offset; + struct ictx c; + + if(nbytes % ROM_ERASE_UNIT_SIZE != 0) { + printf("rom_erase: bad size\n"); + return -1; + } + + if(offset % ROM_ERASE_UNIT_SIZE != 0) { + printf("rom_erase: bad offset\n"); + return -1; + } + + while (nbytes > 0) { + mask_intr(&c); + + FCTL1 = FWKEY | ERASE; /* Segment erase. */ + *to = 0; /* Erase segment containing to. */ + nbytes -= ROM_ERASE_UNIT_SIZE; + to += ROM_ERASE_UNIT_SIZE; + + rest_intr(&c); + } + + return nb; +} + +int +rom_pwrite(const void *buf, int nbytes, off_t offset) +{ + const char *from = buf; + int nb = nbytes; + char *to = (char *)(uintptr_t)offset; + struct ictx c; + + mask_intr(&c); + + while(nbytes > 0) { + int n = (nbytes > 64) ? 64 : nbytes; + FCTL1 = FWKEY | BLKWRT | WRT; /* Enable block write. */ + blkwrt(to, from, from + n); + while(FCTL3 & BUSY); + to += 64; + from += 64; + nbytes -= n; + } + + rest_intr(&c); + + return nb; +} + +/* + * This helper routine must reside in RAM! + */ +asm(".data"); +asm(".p2align 1,0"); +asm(".type blkwrt,@function"); +asm(".section .data"); + +static void +blkwrt(void *_to, const void *_from, const void *_from_end) +{ + unsigned short *to = _to; + const unsigned short *from = _from; + const unsigned short *from_end = _from_end; + do { + *to++ = *from++; + while(!(FCTL3 & WAIT)); + } while(from < from_end); + FCTL1 = FWKEY; /* Disable block write. */ + /* Now ROM is available again! */ +} diff --git a/cpu/msp430/slip_uart1.c b/cpu/msp430/slip_uart1.c new file mode 100644 index 000000000..aedd34e47 --- /dev/null +++ b/cpu/msp430/slip_uart1.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: slip_uart1.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +/* + * Machine dependent MSP430 SLIP routines for UART1. + */ + +#include +#include + +#include "contiki.h" + +#include "dev/lpm.h" +#include "dev/slip.h" + +void +slip_arch_writeb(unsigned char c) +{ + /* Loop until the transmission buffer is available. */ + while ((IFG2 & UTXIFG1) == 0); + + /* Transmit the data. */ + TXBUF1 = c; +} + +/* + * The serial line is used to transfer IP packets using slip. To make + * it possible to send debug output over the same line we send debug + * output as slip frames (i.e delimeted by SLIP_END). + * + */ +int +putchar(int c) +{ +#define SLIP_END 0300 + static char debug_frame = 0; + + if (!debug_frame) { /* Start of debug output */ + slip_arch_writeb(SLIP_END); + slip_arch_writeb('\r'); /* Type debug line == '\r' */ + debug_frame = 1; + } + + slip_arch_writeb((char)c); + + /* + * Line buffered output, a newline marks the end of debug output and + * implicitly flushes debug output. + */ + if (c == '\n') { + slip_arch_writeb(SLIP_END); + debug_frame = 0; + } + + return c; +} + +#define RS232_19200 1 +#define RS232_38400 2 +#define RS232_57600 3 +#define RS232_115200 3 + +#if 0 +void +rs232_set_speed(unsigned char speed) +{ + + if(speed == RS232_19200) { + /* Set RS232 to 19200 */ + UBR01 = 0x80; /* 2,457MHz/19200 = 128 -> 0x80 */ + UBR11 = 0x00; /* */ + UMCTL1 = 0x00; /* no modulation */ + } else if(speed == RS232_38400) { + /* Set RS232 to 38400 */ + UBR01 = 0x40; /* 2,457MHz/38400 = 64 -> 0x40 */ + UBR11 = 0x00; /* */ + UMCTL1 = 0x00; /* no modulation */ + } else if(speed == RS232_57600) { + UBR01 = 0x2a; /* 2,457MHz/57600 = 42.7 -> 0x2A */ + UBR11 = 0x00; /* */ + UMCTL1 = 0x5b; /* */ + } else if(speed == RS232_115200) { + UBR01 = 0x15; /* 2,457MHz/115200 = 21.4 -> 0x15 */ + UBR11 = 0x00; /* */ + UMCTL1 = 0x4a; /* */ + } else { + rs232_set_speed(RS232_57600); + } + +} +#endif + +/** + * Initalize the RS232 port and the SLIP driver. + * + */ +void +slip_arch_init(void) +{ + /* RS232 */ + P3DIR &= ~0x80; /* Select P37 for input (UART1RX) */ + P3DIR |= 0x40; /* Select P36 for output (UART1TX) */ + P3SEL |= 0xC0; /* Select P36,P37 for UART1{TX,RX} */ + + UCTL1 = SWRST | CHAR; /* 8-bit character, UART mode */ + +/* U1RCTL &= ~URXEIE; /\* even erroneous characters trigger interrupts *\/ */ + + UTCTL1 = SSEL1; /* UCLK = MCLK */ + + /* rs232_set_speed(RS232_57600); */ + UBR01 = 0x2a; + UBR11 = 0x00; + UMCTL1 = 0x5b; + + ME2 &= ~USPIE1; /* USART1 SPI module disable */ + ME2 |= (UTXE1 | URXE1); /* Enable USART1 TXD/RXD */ + + UCTL1 &= ~SWRST; + + /* XXX Clear pending interrupts before enable!!! */ + + IE2 |= URXIE1; /* Enable USART1 RX interrupt */ +} + +interrupt(UART1RX_VECTOR) +__uart1_intr() +{ + /* Check status register for receive errors. */ + if (URCTL1 & RXERR) { + volatile unsigned dummy; + dummy = RXBUF1; /* Clear error flags by forcing a dummy read. */ + } else { + if(slip_input_byte(RXBUF1)) + LPM_AWAKE(); + } +} diff --git a/cpu/msp430/spi.c b/cpu/msp430/spi.c new file mode 100644 index 000000000..7705f5164 --- /dev/null +++ b/cpu/msp430/spi.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)$Id: spi.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ + +#include + +#include "contiki-conf.h" + +/* + * On the Tmote sky access to I2C/SPI/UART0 must always be + * exclusive. Set spi_busy so that interrupt handlers can check if + * they are allowed to use the bus or not. Only the CC2420 radio needs + * this in practice. + * + */ +unsigned char spi_busy = 0; + +/* + * Initialize SPI bus. + */ +void +spi_init(void) +{ + static unsigned char spi_inited = 0; + + if (spi_inited) + return; + + /* Initalize ports for communication with SPI units. */ + + U0CTL = CHAR + SYNC + MM + SWRST; /* SW reset,8-bit transfer, SPI master */ + U0TCTL = CKPH + SSEL1 + STC; /* Data on Rising Edge, SMCLK, 3-wire. */ + + U0BR0 = 0x02; /* SPICLK set baud. */ + U0BR1 = 0; /* Dont need baud rate control register 2 - clear it */ + U0MCTL = 0; /* Dont need modulation control. */ + + P3SEL |= BV(SCK) | BV(MOSI) | BV(MISO); /* Select Peripheral functionality */ + P3DIR |= BV(SCK) | BV(MISO); /* Configure as outputs(SIMO,CLK). */ + + ME1 |= USPIE0; /* Module enable ME1 --> U0ME? xxx/bg */ + U0CTL &= ~SWRST; /* Remove RESET */ +} diff --git a/cpu/msp430/watchdog.c b/cpu/msp430/watchdog.c new file mode 100644 index 000000000..b33984323 --- /dev/null +++ b/cpu/msp430/watchdog.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: watchdog.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $ + */ +#include +#include "dev/watchdog.h" + +/*------------------------------------------------------------------------------*/ +void +watchdog_init(void) +{ + WDTCTL = WDT_ARST_1000 + WDTNMI + WDTNMIES; +} +/*------------------------------------------------------------------------------*/ +void +watchdog_restart(void) +{ + WDTCTL = WDT_ARST_1000 + WDTNMI + WDTNMIES; +} +/*------------------------------------------------------------------------------*/ +void +watchdog_stop(void) +{ + WDTCTL = WDTPW + WDTHOLD + WDTNMI + WDTNMIES; +} +/*------------------------------------------------------------------------------*/ diff --git a/cpu/x86/Makefile.x86 b/cpu/x86/Makefile.x86 new file mode 100644 index 000000000..b14102c35 --- /dev/null +++ b/cpu/x86/Makefile.x86 @@ -0,0 +1,33 @@ +CONTIKI_SOURCEFILES += mtarch.c + +### Compiler definitions +CC = gcc +LD = ld +AS = as +OBJCOPY = objcopy +STRIP = strip +CFLAGSNO = -I. -I$(CONTIKI) -I$(CONTIKI)/core -I$(CONTIKI_CPU) \ + -I$(CONTIKI)/platform/$(TARGET) \ + ${addprefix -I,$(APPDIRS)} $(APP_INCLUDES) \ + -DWITH_UIP -DWITH_ASCII \ + -Wall -g -I. -I/usr/local/include +CFLAGS += $(CFLAGSNO) +LDFLAGS = -Wl,-Map=contiki.map,-export-dynamic + +### Compilation rules + +# $(OBJECTDIR)/%.o: %.c +# $(CC) $(CFLAGS) -c $< -o $@ + +%.so: $(OBJECTDIR)/%.o + $(LD) -shared -o $@ $^ + +# %.ce: %.co +# $(LD) -shared -o $@ $^ + +# %.co: %.c +# $(CC) $(CFLAGS) -DPROCESS_LOADABLE -c $< -o $@ +# $(STRIP) --strip-unneeded -g -x $@ + +# %: %.co $(CONTIKI_TARGET_MAIN) $(PROJECT_OBJECTFILES) contiki-$(TARGET).a +# $(CC) $(CFLAGS) -o $@.$(TARGET) $^ $(LDFLAGS) diff --git a/cpu/x86/mtarch.c b/cpu/x86/mtarch.c new file mode 100644 index 000000000..cd6f55a47 --- /dev/null +++ b/cpu/x86/mtarch.c @@ -0,0 +1,101 @@ + +#include +#include "sys/mt.h" + +struct frame { + unsigned long flags; + unsigned long ebp; + unsigned long edi; + unsigned long esi; + unsigned long edx; + unsigned long ecx; + unsigned long ebx; + unsigned long eax; + unsigned long retaddr; + unsigned long retaddr2; + unsigned long data; +}; + +/*--------------------------------------------------------------------------*/ +void +mtarch_init(void) +{ + +} +/*--------------------------------------------------------------------------*/ +void +mtarch_start(struct mtarch_thread *t, + void (*function)(void *), void *data) +{ + struct frame *f = (struct frame *)&t->stack[MTARCH_STACKSIZE - sizeof(struct frame)/4]; + memset(f, 0, sizeof(struct frame)); + f->retaddr = (unsigned long)function; + f->data = (unsigned long)data; + t->sp = (unsigned long)&f->flags; + f->ebp = (unsigned long)&f->eax; +} +/*--------------------------------------------------------------------------*/ +static unsigned long spsave, sptmp; +static struct mtarch_thread *running_thread; + +static void +sw(void) +{ + + asm("pushl %eax"); + asm("pushl %ebx"); + asm("pushl %ecx"); + asm("pushl %edx"); + asm("pushl %esi"); + asm("pushl %edi"); + asm("pushl %ebp"); + asm("pushl %ebp"); /* XXX: should push FPU flags here. */ + asm("movl %esp, spsave"); + + sptmp = running_thread->sp; + running_thread->sp = spsave; + + asm("movl sptmp, %esp"); + asm("popl %ebp"); /* XXX: should pop FPU flags here. */ + asm("popl %ebp"); + asm("popl %edi"); + asm("popl %esi"); + asm("popl %edx"); + asm("popl %ecx"); + asm("popl %ebx"); + asm("popl %eax"); +} + +/*--------------------------------------------------------------------------*/ +void +mtarch_exec(struct mtarch_thread *t) +{ + running_thread = t; + sw(); + running_thread = NULL; +} +/*--------------------------------------------------------------------------*/ +void +mtarch_remove(void) +{ + +} +/*--------------------------------------------------------------------------*/ +void +mtarch_yield(void) +{ + sw(); +} +/*--------------------------------------------------------------------------*/ +void +mtarch_pstop(void) +{ + +} +/*--------------------------------------------------------------------------*/ +void +mtarch_pstart(void) +{ + +} +/*--------------------------------------------------------------------------*/ diff --git a/cpu/x86/mtarch.h b/cpu/x86/mtarch.h new file mode 100644 index 000000000..3a1fefa3f --- /dev/null +++ b/cpu/x86/mtarch.h @@ -0,0 +1,43 @@ +/* + * 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. + * + */ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ + +#define MTARCH_STACKSIZE 1024 + +struct mtarch_thread { + /* Note: stack must be aligned on 4-byte boundary. */ + unsigned long stack[MTARCH_STACKSIZE]; + unsigned long sp; +}; + +#endif /* __MTARCH_H__ */ + diff --git a/doc/Doxyfile b/doc/Doxyfile new file mode 100644 index 000000000..146a055f6 --- /dev/null +++ b/doc/Doxyfile @@ -0,0 +1,301 @@ +# Doxyfile 1.4.1 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = "Contiki 2.x" +PROJECT_NUMBER = +OUTPUT_DIRECTORY = . +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = ../ +STRIP_FROM_INC_PATH = +SHORT_NAMES = YES +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = YES +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= NO +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = contiki-mainpage.txt net.txt dev.txt \ + mem.txt \ + sys.txt \ + lib.txt \ + platform.txt \ + uip-doc.txt \ + code-style.txt \ + examples.txt \ + uip-doc.txt \ + ../apps/program-handler/program-handler.c \ + ../core/sys/process.c \ + ../core/sys/process.h \ + ../core/sys/cc.h \ + ../core/sys/etimer.c \ + ../core/sys/etimer.h \ + ../core/sys/service.h \ + ../core/sys/service.c \ + ../core/sys/procinit.h \ + ../core/sys/procinit.c \ + ../core/sys/arg.c \ + ../core/sys/dsc.h \ + ../core/sys/loader.h \ + ../core/sys/pt.h \ + ../core/sys/lc.h \ + ../core/sys/lc-switch.h \ + ../core/sys/lc-addrlabels.h \ + ../core/sys/pt-sem.h \ + ../core/sys/clock.h \ + ../core/sys/mt.h \ + ../core/sys/mt.c \ + ../core/dev/eeprom.h \ + ../core/dev/radio.h \ + ../core/loader/elfloader-tmp.h \ + ../core/loader/elfloader-arch.h \ + pt-doc.txt \ + ../core/cfs/cfs.h \ + ../core/ctk/ctk.h \ + ../core/ctk/ctk.c \ + ../core/ctk/ctk-draw.h \ + ../core/sys/timer.h \ + ../core/sys/timer.c \ + ../core/net/uip.h \ + ../core/net/uip.c \ + ../core/net/uipopt.h \ + ../core/net/uip_arp.h \ + ../core/net/uip_arp.c \ + ../core/net/uip-split.h \ + ../core/net/uip-split.c \ + ../core/net/uip-fw.h \ + ../core/net/uip-fw.c \ + ../core/net/uiplib.h \ + ../core/net/uiplib.c \ + ../core/net/resolv.h \ + ../core/net/resolv.c \ + ../core/net/psock.h \ + ../core/net/psock.c \ + ../core/net/tcpip.h \ + ../core/net/tcpip.c \ + ../core/lib/petsciiconv.h \ + ../core/lib/ctk-textedit.h \ + ../core/lib/ctk-textedit.c \ + ../core/lib/memb.h \ + ../core/lib/memb.c \ + ../core/lib/mmem.h \ + ../core/lib/mmem.c \ + ../core/lib/list.h \ + ../core/lib/list.c \ + ../core/lib/me.h \ + ../core/lib/me.c \ + ../core/lib/crc16.h \ + ../core/lib/crc16.c \ + ../platform/esb/doc/esb.txt \ + ../platform/esb/doc/slipintro.txt \ + ../platform/esb/doc/winintro.txt \ + ../platform/esb/dev/beep.h \ + ../platform/esb/dev/eeprom.c \ + ../platform/esb/dev/rs232.h \ + ../platform/esb/dev/rs232.c \ + ../platform/esb/dev/tr1001.c +FILE_PATTERNS = +RECURSIVE = NO +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = . +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = YES +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = YES +BINARY_TOC = YES +TOC_EXPAND = YES +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = YES +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = YES +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = CC_FUNCTION_POINTER_ARGS \ + UIP_UDP \ + WITH_LOADER_ARCH \ + DOXYGEN +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = NO +COLLABORATION_GRAPH = NO +GROUP_GRAPHS = NO +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DIRECTORY_GRAPH = NO +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 000000000..d06e31593 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,11 @@ +# This target requires and graphviz and doxygen +dox: + doxygen Doxyfile + + +pdf: + gmake -C latex refman.pdf + +upload: dox pdf + scp -C latex/refman.pdf adamdunkels@shell.sourceforge.net:/home/groups/c/co/contiki/htdocs/ + tar czfv - html | ssh adamdunkels@shell.sourceforge.net "cd /home/groups/c/co/contiki/htdocs/; tar xfz -" diff --git a/doc/code-style.c b/doc/code-style.c new file mode 100644 index 000000000..cc56a649c --- /dev/null +++ b/doc/code-style.c @@ -0,0 +1,116 @@ +/** + * \defgroup coding-style Coding style + * + * This is how a Doxygen module is documented - start with a \defgroup + * Doxygen keyword at the beginning of the file to define a module, + * and use the \addtogroup Doxygen keyword in all other files that + * belong to the same module. Typically, the \defgroup is placed in + * the .h file and \addtogroup in the .c file. + * + * @{ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + * + * Every file that is part of a documented module has to have + * a \file block, else it will not show up in the Doxygen + * "Modules" * section. + */ + +/* Single line comments look like this. */ + +/* + * Multi-line comments look like this. Comments should prefferably be + * full sentences, filled to look like real paragraphs. + */ + +#include "contiki.h" + +/* + * Make sure that non-global variables are all maked with the static + * keyword. This keeps the size of the symbol table down. + */ +static int flag; + +/* + * All variables and functions that are visible outside of the file + * should have the module name prepended to them. This makes it easy + * to know where to look for function and variable definitions. + * + * Put dividers (a single-line comment consisting only of dashes) + * between functions. + */ +/*---------------------------------------------------------------------------*/ +/** + * \brief Use Doxygen documentation for functions. + * \param c Briefly describe all parameters. + * \return Briefly describe the return value. + * \retval 0 Functions that return a few specified values + * \retval 1 can use the \retval keyword instead of \return. + * + * Put a longer description of what the function does + * after the preamble of Doxygen keywords. + * + * This template should always be used to document + * functions. The text following the introduction is used + * as the function's documentation. + * + * Function prototypes have the return type on one line, + * the name and arguments on one line (with no space + * between the name and the first parenthesis), followed + * by a single curly bracket on its own line. + */ +void +code_style_example_function(void) +{ + /* + * Local variables should always be declared at the start of the + * function. + */ + int i; /* Use short variable names for loop + counters. */ + + /* + * There should be no space between keywords and the first + * parenthesis. There should be spaces around binary operators, no + * spaces between a unary operator and its operand. + * + * Curly brackets following for(), if(), do, and case() statements + * should follow the statement on the same line. + */ + for(i = 0; i < 10; ++i) { + /* + * Always use full blocks (curly brackets) after if(), for(), and + * while() statements, even though the statement is a single line + * of code. This makes the code easier to read and modifications + * are less error prone. + */ + if(i == c) { + return c; /* No parentesis around return values. */ + } else { /* The else keyword is placed inbetween + curly brackers, always on its own line. */ + c++; + } + } +} +/*---------------------------------------------------------------------------*/ +/* + * Static (non-global) functions do not need Doxygen comments. The + * name should not be prepended with the module name - doing so would + * create confusion. + */ +static void +an_example_function(void) +{ + +} +/*---------------------------------------------------------------------------*/ + +/* The following stuff ends the \defgroup block at the beginning of + the file: */ + +/** @} */ diff --git a/doc/code-style.txt b/doc/code-style.txt new file mode 100644 index 000000000..921104152 --- /dev/null +++ b/doc/code-style.txt @@ -0,0 +1,3 @@ +/** + \example code-style.c + */ diff --git a/doc/contiki-mainpage.txt b/doc/contiki-mainpage.txt new file mode 100644 index 000000000..de7e0c99d --- /dev/null +++ b/doc/contiki-mainpage.txt @@ -0,0 +1,53 @@ +/** + +\mainpage The Contiki Operating System 2.x + +\author Adam Dunkels + +The Contiki operating system is a highly portable, minimalistic +operating system for a variety of constrained systems ranging from +modern 8-bit microcontrollers for embedded systems to old 8-bit +homecomputers. Contiki provides a simple event driven kernel with +optional preemptive multithreading, interprocess communication using +message passing signals, a dynamic process structure and support for +loading and unloading programs, native TCP/IP support using the uIP +TCP/IP stack, and a graphical subsystem with either direct graphic +support for directly connected terminals or networked virtual display +with VNC or Telnet. + +Contiki is written in the C programming language and is freely +available as open source under a BSD-style license. More information +about Contiki can be found at the Contiki home page: +http://www.sics.se/~adam/contiki/ + +\section contiki-mainpage-tcpip TCP/IP support + +Contiki includes the uIP TCP/IP stack (http://www.sics.se/~adam/uip/) +that provides Contiki with TCP/IP networking support. uIP provides the +protocols TCP, UDP, IP, and ARP. + +\sa \ref uip "The uIP TCP/IP stack documentation" +\sa \ref tcpip "The Contiki/uIP interface" +\sa \ref psock "Protosockets library" + +\section contiki-mainpage-threads Multi-threading and protothreads + +Contiki is based on an event-driven kernel but provides support for +both multi-threading and a lightweight stackless thread-like construct +called protothreads. + +\sa \ref process "Contiki processes" +\sa \ref pt "Protothreads" +\sa \ref etimer "Event timers" +\sa \ref mt "Optional multi-threading" + +\section contiki-mainpage-lib Libraries + +Contiki provides a set of convenience libraries for memory management +and linked list operations. + +\sa \ref timer "Simple timer library" +\sa \ref memb "Memory block management" +\sa \ref list "Linked list library" + +*/ \ No newline at end of file diff --git a/doc/dev.txt b/doc/dev.txt new file mode 100644 index 000000000..a831d3392 --- /dev/null +++ b/doc/dev.txt @@ -0,0 +1,5 @@ +/** +\defgroup dev Device driver APIs +@{ +*/ +/** @} */ diff --git a/doc/example-list.c b/doc/example-list.c new file mode 100644 index 000000000..bb0fb648b --- /dev/null +++ b/doc/example-list.c @@ -0,0 +1,27 @@ +#include "list.h" + +struct example_list_struct { + struct *next; + int number; +}; + +LIST(example_list); + +void +example_function(void) +{ + struct example_list_struct *s; + struct example_list_struct element1, element2; + + list_init(example_list); + + list_add(example_list, &element1); + list_add(example_list, &element2); + + for(s = list_head(example_list); + s != NULL; + s = s->next) { + printf("List element number %d\n", s->number); + } + +} diff --git a/doc/example-packet-service.c b/doc/example-packet-service.c new file mode 100644 index 000000000..dfe6ce2c9 --- /dev/null +++ b/doc/example-packet-service.c @@ -0,0 +1,141 @@ +/* + * This is an example of how to write a network device driver ("packet + * service") for Contiki. A packet service is a regular Contiki + * service that does two things: + * # Checks for incoming packets and delivers those to the TCP/IP stack + * # Provides an output function that transmits packets + * + * The output function is registered with the Contiki service + * mechanism, whereas incoming packets must be checked inside a + * Contiki process. We use the same process for checking for incoming + * packets and for registering the service. + * + * NOTE: This example does not work with the uip-fw module (packet + * forwarding with multiple interfaces). It only works with a single + * interface. + */ + +/* + * We include the "contiki-net.h" file to get all the network + * functions. + */ +#include "contiki-net.h" + +/*---------------------------------------------------------------------------*/ +/* + * We declare the process that we use to register the service, and to + * check for incoming packets. + */ +PROCESS(example_packet_service_process, "Example packet service process"); +/*---------------------------------------------------------------------------*/ +/* + * This is the poll handler function in the process below. This poll + * handler function checks for incoming packets and delivers them to + * the TCP/IP stack. + */ +static void +pollhandler(void) +{ + /* + * We assume that we have some hardware device that notifies us when + * a new packet has arrived. We also assume that we have a function + * that pulls out the new packet (here called + * check_and_copy_packet()) and puts it in the uip_buf[] buffer. The + * function returns the length of the incoming packet, and we store + * it in the global uip_len variable. If the packet is longer than + * zero bytes, we hand it over to the TCP/IP stack. + */ + uip_len = check_and_copy_packet(); + + /* + * The function tcpip_input() delivers the packet in the uip_buf[] + * buffer to the TCP/IP stack. + */ + if(uip_len > 0) { + tcpip_input(); + } + + /* + * Now we'll make sure that the poll handler is executed + * repeatedly. We do this by calling process_poll() with this + * process as its argument. + * + * In many cases, the hardware will cause an interrupt to be + * executed when a new packet arrives. For such hardware devices, + * the interrupt handler calls process_poll() (which is safe to use + * in an interrupt context) instead. + */ + process_poll(&example_packet_service_process); +} +/*---------------------------------------------------------------------------*/ +/* + * Next, we define the function that transmits packets. This function + * is called from the TCP/IP stack when a packet is to be + * transmitted. The packet is located in the uip_buf[] buffer, and the + * length of the packet is in the uip_len variable. + */ +static void +send_packet(void) +{ + let_the_hardware_send_the_packet(uip_buf, uip_len); +} +/*---------------------------------------------------------------------------*/ +/* + * Now we declare the service. We call the service + * example_packet_service because of the name of this file. The + * service should be an instance of the "packet service" service, so + * we give packet_service as the second argument. Finally we give our + * send_packet() function as the last argument, because of how the + * packet_service interface is defined. + * + * We'll register this service with the Contiki system in the process + * defined below. + */ +SERVICE(example_packet_service, packet_service, { send_packet }); +/*---------------------------------------------------------------------------*/ +/* + * Finally, we define the process that does the work. + */ +PROCESS_THREAD(example_packet_service_process, ev, data) +{ + /* + * This process has a poll handler, so we declare it here. Note that + * the PROCESS_POLLHANDLER() macro must come before the + * PROCESS_BEGIN() macro. + */ + PROCESS_POLLHANDLER(pollhandler()); + + /* + * The process begins here. + */ + PROCESS_BEGIN(); + + /* + * We start with initializing the hardware. + */ + initialize_the_hardware(); + + /* + * Register the service. This will cause any other instances of the + * same service to be removed. + */ + SERVICE_REGISTER(example_packet_service); + + /* + * And we wait for either the process to exit, or for the service to + * be removed (by someone else). + */ + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT || + ev == PROCESS_EVENT_SERVICE_REMOVED); + + /* + * And we always end with explicitly removing the service. + */ + SERVICE_REMOVE(example_packet_service); + + /* + * Here endeth the process. + */ + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/example-pollhandler.c b/doc/example-pollhandler.c new file mode 100644 index 000000000..1126c201e --- /dev/null +++ b/doc/example-pollhandler.c @@ -0,0 +1,30 @@ +#include "contiki.h" + +PROCESS(example_pollhandler, "Pollhandler example"); + +static void +exithandler(void) +{ + printf("Process exited\n"); +} + +static void +pollhandler(void) +{ + printf("Process polled\n"); +} + +PROCESS_THREAD(example_pollhandler, ev, data) +{ + + PROCESS_POLLHANDLER(pollhandler()); + PROCESS_EXITHANDLER(exithandler()); + + PROCESS_BEGIN(); + + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} diff --git a/doc/example-program.c b/doc/example-program.c new file mode 100644 index 000000000..19f03d45c --- /dev/null +++ b/doc/example-program.c @@ -0,0 +1,89 @@ +/* + * This file contains an example of how a Contiki program looks. + * + * The program opens a UDP broadcast connection and sends one packet + * every second. + */ + +#include "contiki.h" +#include "contiki-net.h" + +/* + * All Contiki programs must have a process, and we declare it here. + */ +PROCESS(example_program_process, "Example process"); + +/* + * To make the program send a packet once every second, we use an + * event timer (etimer). + */ +static struct etimer timer; + +/*---------------------------------------------------------------------------*/ +/* + * Here we implement the process. The process is run whenever an event + * occurs, and the parameters "ev" and "data" will we set to the event + * type and any data that may be passed along with the event. + */ +PROCESS_THREAD(example_program_process, ev, data) +{ + /* + * Declare the UDP connection. Note that this *MUST* be declared + * static, or otherwise the contents may be destroyed. The reason + * for this is that the process runs as a protothread, and + * protothreads do not support stack variables. + */ + static struct uip_udp_conn *c; + + /* + * A process thread starts with PROCESS_BEGIN() and ends with + * PROCESS_END(). + */ + PROCESS_BEGIN(); + + /* + * We create the UDP connection to port 4321. We don't want to + * attach any special data to the connection, so we pass it a NULL + * parameter. + */ + c = udp_broadcast_new(HTONS(4321), NULL); + + /* + * Loop for ever. + */ + while(1) { + + /* + * We set a timer that wakes us up once every second. + */ + etimer_set(&timer, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer)); + + /* + * Now, this is a the tricky bit: in order for us to send a UDP + * packet, we must call upon the uIP TCP/IP stack process to call + * us. (uIP works under the Hollywood principle: "Don't call us, + * we'll call you".) We use the function tcpip_poll_udp() to tell + * uIP to call us, and then we wait for the uIP event to come. + */ + tcpip_poll_udp(c); + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + + /* + * We can now send our packet. + */ + uip_send("Hello", 5); + + /* + * We're done now, so we'll just loop again. + */ + } + + /* + * The process ends here. Even though our program sits is a while(1) + * loop, we must put the PROCESS_END() at the end of the process, or + * else the program won't compile. + */ + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/example-psock-client.c b/doc/example-psock-client.c new file mode 100644 index 000000000..5557cc1d0 --- /dev/null +++ b/doc/example-psock-client.c @@ -0,0 +1,57 @@ + +#include "contiki-net.h" + +static struct psock ps; +static char buffer[100]; + +PROCESS(example_psock_client_process, "Example protosocket client"); + +/*---------------------------------------------------------------------------*/ +static int +handle_connection(struct psock *p) +{ + PSOCK_BEGIN(p); + + PSOCK_SEND_STR(p, "GET / HTTP/1.0\r\n"); + PSOCK_SEND_STR(p, "Server: Contiki example protosocket client\r\n"); + PSOCK_SEND_STR(p, "\r\n"); + + while(1) { + PSOCK_READTO(p, '\n'); + printf("Got: %s", buffer); + } + + PSOCK_END(p); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(example_psock_client_process, ev, data) +{ + uip_ipaddr_t addr; + + printf("%d\n", TEST); + + PROCESS_BEGIN(); + + uip_ipaddr(addr, 192,168,2,1); + tcp_connect(addr, HTONS(80), NULL); + + printf("Connecting...\n"); + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + + if(uip_aborted() || uip_timedout() || uip_closed()) { + printf("Could not establish connection\n"); + } else if(uip_connected()) { + printf("Connected\n"); + + PSOCK_INIT(&ps, buffer, sizeof(buffer)); + + do { + handle_connection(&ps); + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + } while(!(uip_closed() || uip_aborted() || uip_timedout())); + + printf("\nConnection closed.\n"); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/example-psock-server.c b/doc/example-psock-server.c new file mode 100644 index 000000000..f297a43e0 --- /dev/null +++ b/doc/example-psock-server.c @@ -0,0 +1,165 @@ +/* + * This is a small example of how to write a TCP server using + * Contiki's protosockets. It is a simple server that accepts one line + * of text from the TCP connection, and echoes back the first 10 bytes + * of the string, and then closes the connection. + * + * The server only handles one connection at a time. + * + */ + +#include + +/* + * We include "contiki-net.h" to get all network definitions and + * declarations. + */ +#include "contiki-net.h" + +/* + * We define one protosocket since we've decided to only handle one + * connection at a time. If we want to be able to handle more than one + * connection at a time, each parallell connection needs its own + * protosocket. + */ +static struct psock ps; + +/* + * We must have somewhere to put incoming data, and we use a 10 byte + * buffer for this purpose. + */ +static char buffer[10]; + +/*---------------------------------------------------------------------------*/ +/* + * A protosocket always requires a protothread. The protothread + * contains the code that uses the protosocket. We define the + * protothread here. + */ +static +PT_THREAD(handle_connection(struct psock *p)) +{ + /* + * A protosocket's protothread must start with a PSOCK_BEGIN(), with + * the protosocket as argument. + * + * Remember that the same rules as for protothreads apply: do NOT + * use local variables unless you are very sure what you are doing! + * Local (stack) variables are not preserved when the protothread + * blocks. + */ + PSOCK_BEGIN(p); + + /* + * We start by sending out a welcoming message. The message is sent + * using the PSOCK_SEND_STR() function that sends a null-terminated + * string. + */ + PSOCK_SEND_STR(p, "Welcome, please type something and press return.\n"); + + /* + * Next, we use the PSOCK_READTO() function to read incoming data + * from the TCP connection until we get a newline character. The + * number of bytes that we actually keep is dependant of the length + * of the input buffer that we use. Since we only have a 10 byte + * buffer here (the buffer[] array), we can only remember the first + * 10 bytes received. The rest of the line up to the newline simply + * is discarded. + */ + PSOCK_READTO(p, '\n'); + + /* + * And we send back the contents of the buffer. The PSOCK_DATALEN() + * function provides us with the length of the data that we've + * received. Note that this length will not be longer than the input + * buffer we're using. + */ + PSOCK_SEND_STR(p, "Got the following data: "); + PSOCK_SEND(p, buffer, PSOCK_DATALEN(p)); + PSOCK_SEND_STR(p, "Good bye!\r\n"); + + /* + * We close the protosocket. + */ + PSOCK_CLOSE(p); + + /* + * And end the protosocket's protothread. + */ + PSOCK_END(p); +} +/*---------------------------------------------------------------------------*/ +/* + * We declare the process. + */ +PROCESS(example_psock_server_process, "Example protosocket server"); +/*---------------------------------------------------------------------------*/ +/* + * The definition of the process. + */ +PROCESS_THREAD(example_psock_server_process, ev, data) +{ + /* + * The process begins here. + */ + PROCESS_BEGIN(); + + /* + * We start with setting up a listening TCP port. Note how we're + * using the HTONS() macro to convert the port number (1010) to + * network byte order as required by the tcp_listen() function. + */ + tcp_listen(HTONS(1010)); + + /* + * We loop for ever, accepting new connections. + */ + while(1) { + + /* + * We wait until we get the first TCP/IP event, which probably + * comes because someone connected to us. + */ + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + + /* + * If a peer connected with us, we'll initialize the protosocket + * with PSOCK_INIT(). + */ + if(uip_connected()) { + + /* + * The PSOCK_INIT() function initializes the protosocket and + * binds the input buffer to the protosocket. + */ + PSOCK_INIT(&ps, buffer, sizeof(buffer)); + + /* + * We loop until the connection is aborted, closed, or times out. + */ + while(!(uip_aborted() || uip_closed() || uip_timedout())) { + + /* + * We wait until we get a TCP/IP event. Remember that we + * always need to wait for events inside a process, to let + * other processes run while we are waiting. + */ + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + + /* + * Here is where the real work is taking place: we call the + * handle_connection() protothread that we defined above. This + * protothread uses the protosocket to receive the data that + * we want it to. + */ + handle_connection(&ps); + } + } + } + + /* + * We must always declare the end of a process. + */ + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/example-service.c b/doc/example-service.c new file mode 100644 index 000000000..41ee4f7ab --- /dev/null +++ b/doc/example-service.c @@ -0,0 +1,115 @@ +/* + * This file is an example of how to implement a service in + * Contiki. The header file example-service.h defines a service called + * "example_service", which we implement in this file. + * + * This example shows how to define an instance of a service, and how + * to write the service's controlling process. + * + * See the file example-use-service.c for an example of how to call a + * service. + */ + +#include + +#include "example-service.h" +#include "contiki.h" + +/*---------------------------------------------------------------------------*/ +/* + * We start by implementing all the functions that the service + * offers. In this case, there is only a single function (called + * example_function()) and we implement it here. We give it the name + * example() and declare it with the "static" keyword to keep the + * scope local to this file. + */ +static void +example(void) { + printf("Example service called\n"); +} +/*---------------------------------------------------------------------------*/ +/* + * This is the instantiation of the service called + * "example_service". The service interface is defined in the header + * file example-service.h. + * + * This statement defines the name of this implementation of the + * service - example_service_implementation - and defines the + * functions that actually implement the functions offered by the + * service. In this example, the service consists of a single function + * called "example_function()". We implement this function in the + * function called "example()" defined above. + * + */ +SERVICE(example_service_implementation, /* The name of this instance + of the service - used with + SERVICE_REGISTER(). */ + example_service, /* The name of the serivce + that is instantiated. */ + { example }); /* The list of functions + required by the + service. In this case, we + only have one function. */ + +/* + * All services needs a controlling process. The controlling process + * registers the service with the system when it starts, and is also + * notified if the service is removed or replaced. + * + * We simply call the process "example_service_process" and gives it a + * similar textual name. + */ +PROCESS(example_service_process, "Example service process"); + +/* + * For this example, we use a timer to remove the service after a + * certain time. We declare the timer here. + */ +static struct etimer timer; + +/* + * Finally, we implement the controlling process. + */ +PROCESS_THREAD(example_service_process, ev, data) +{ + + /* + * A process thread starts with PROCESS_BEGIN() and ends with + * PROCESS_END(). + */ + PROCESS_EXITHANDLER(goto exit); + PROCESS_BEGIN(); + + /* + * We register the service instance with a SERVICE_REGISTER() + * statement. + */ + printf("Registering example service\n"); + SERVICE_REGISTER(example_service_implementation); + + /* + * We set a timer for four seconds and wait for it to expire - or + * for the process to receive an event which requests it to exit. + * + * The only purpose for the timer is to demonstrate how a service is + * removed - it is not something that is commonly done. + */ + etimer_set(&timer, 4 * CLOCK_SECOND); + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_SERVICE_REMOVED || + etimer_expired(&timer)); + + /* + * And we remove the service before the process ends. This is a + * *very* important step - if the process exits and is unloaded + * without first removing its services, the system may crash! + */ + printf("Removing example service\n"); + + /* + * And finally the process ends. + */ + exit: + SERVICE_REMOVE(example_service_implementation); + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/example-service.h b/doc/example-service.h new file mode 100644 index 000000000..0f9806425 --- /dev/null +++ b/doc/example-service.h @@ -0,0 +1,33 @@ +/* + * This file is an example of how to define a service in Contiki. The + * example shows how to define a service interface, and how to give + * the service a name. + */ +#ifndef __EXAMPLE_SERVICE_H__ +#define __EXAMPLE_SERVICE_H__ + +#include "sys/service.h" + +/* + * This is how we define the service interface, and give the service a + * name. The name of this particular service is "example_service" and + * the interface consists of a single function, called + * example_function(). + */ +SERVICE_INTERFACE(example_service, +{ + void (* example_function)(void); + /* More functions can be added here, line by line. */ +}); + +/* + * We must also give the service a textual name. We do this by using a + * special #define statment - we define a macro with the same name as + * the service, but postfixed with "_name". + * + * The textual name is used when looking up services. The name must be + * unique within the system. + */ +#define example_service_name "Example service" + +#endif /* __EXAMPLE_SERVICE_H__ */ diff --git a/doc/example-use-service.c b/doc/example-use-service.c new file mode 100644 index 000000000..003f7a310 --- /dev/null +++ b/doc/example-use-service.c @@ -0,0 +1,65 @@ +/* + * This file contains an example of how to call a service. + * + * This program implements a process that calls the service defined in + * example-service.h every second. + */ + +#include + +#include "contiki.h" + +/* + * We must include the header file for the service. + */ +#include "example-service.h" + +/* + * All Contiki programs must have a process, and we declare it here. + */ +PROCESS(example_use_service_process, "Use example"); + +/* + * The program is to call the service once every second, so we use an + * event timer in order to run every second. + */ +static struct etimer timer; + +/*---------------------------------------------------------------------------*/ +/* + * Here we implement the process. + */ +PROCESS_THREAD(example_use_service_process, ev, data) +{ + /* + * A process thread starts with PROCESS_BEGIN() and ends with + * PROCESS_END(). + */ + PROCESS_BEGIN(); + + /* + * We loop for ever, calling the service once every second. + */ + while(1) { + + /* + * We set a timer that wakes us up once every second. + */ + etimer_set(&timer, CLOCK_SECOND); + PROCESS_YIELD_UNTIL(etimer_expired(&timer)); + + /* + * We call the service. If the service is not registered, the + * SERVICE_CALL() statement does nothing. If we need to know if + * the service exists, we can use the SERVICE_FIND() function. + */ + printf("use example: calling example\n"); + SERVICE_CALL(example_service, example_function()); + } + + /* + * And finally the process ends. + */ + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/examples.txt b/doc/examples.txt new file mode 100644 index 000000000..e3f68c10a --- /dev/null +++ b/doc/examples.txt @@ -0,0 +1,8 @@ +/** \example example-program.c */ +/** \example example-service.c */ +/** \example example-service.h */ +/** \example example-use-service.c */ +/** \example example-pollhandler.c */ +/** \example example-list.c */ +/** \example example-packet-service.c */ +/** \example example-psock-server.c */ diff --git a/doc/html/.cvsignore b/doc/html/.cvsignore new file mode 100644 index 000000000..7d3624922 --- /dev/null +++ b/doc/html/.cvsignore @@ -0,0 +1 @@ +*.html *.png *.md5 *.css *.dot index.* diff --git a/doc/html/img/esb/cygwin0.jpg b/doc/html/img/esb/cygwin0.jpg new file mode 100644 index 000000000..3be685286 Binary files /dev/null and b/doc/html/img/esb/cygwin0.jpg differ diff --git a/doc/html/img/esb/cygwin1.jpg b/doc/html/img/esb/cygwin1.jpg new file mode 100644 index 000000000..dd6df5bba Binary files /dev/null and b/doc/html/img/esb/cygwin1.jpg differ diff --git a/doc/html/img/esb/cygwin2.jpg b/doc/html/img/esb/cygwin2.jpg new file mode 100644 index 000000000..3a6e2467c Binary files /dev/null and b/doc/html/img/esb/cygwin2.jpg differ diff --git a/doc/html/img/esb/cygwin3.jpg b/doc/html/img/esb/cygwin3.jpg new file mode 100644 index 000000000..757eb106a Binary files /dev/null and b/doc/html/img/esb/cygwin3.jpg differ diff --git a/doc/html/img/esb/cygwin4.jpg b/doc/html/img/esb/cygwin4.jpg new file mode 100644 index 000000000..d739ead60 Binary files /dev/null and b/doc/html/img/esb/cygwin4.jpg differ diff --git a/doc/html/img/esb/cygwin5.jpg b/doc/html/img/esb/cygwin5.jpg new file mode 100644 index 000000000..0de97af6c Binary files /dev/null and b/doc/html/img/esb/cygwin5.jpg differ diff --git a/doc/html/img/esb/cygwin6.jpg b/doc/html/img/esb/cygwin6.jpg new file mode 100644 index 000000000..f4059f58c Binary files /dev/null and b/doc/html/img/esb/cygwin6.jpg differ diff --git a/doc/html/img/esb/cygwin6b.jpg b/doc/html/img/esb/cygwin6b.jpg new file mode 100644 index 000000000..053f2646a Binary files /dev/null and b/doc/html/img/esb/cygwin6b.jpg differ diff --git a/doc/html/img/esb/esb.jpg b/doc/html/img/esb/esb.jpg new file mode 100644 index 000000000..97a1682f9 Binary files /dev/null and b/doc/html/img/esb/esb.jpg differ diff --git a/doc/html/img/esb/slip01.jpg b/doc/html/img/esb/slip01.jpg new file mode 100644 index 000000000..40d3fb63f Binary files /dev/null and b/doc/html/img/esb/slip01.jpg differ diff --git a/doc/html/img/esb/slip02.jpg b/doc/html/img/esb/slip02.jpg new file mode 100644 index 000000000..ea7236c02 Binary files /dev/null and b/doc/html/img/esb/slip02.jpg differ diff --git a/doc/html/img/esb/slip03.jpg b/doc/html/img/esb/slip03.jpg new file mode 100644 index 000000000..db63a3192 Binary files /dev/null and b/doc/html/img/esb/slip03.jpg differ diff --git a/doc/html/img/esb/slip04.jpg b/doc/html/img/esb/slip04.jpg new file mode 100644 index 000000000..a8dcd48c4 Binary files /dev/null and b/doc/html/img/esb/slip04.jpg differ diff --git a/doc/html/img/esb/slip05.jpg b/doc/html/img/esb/slip05.jpg new file mode 100644 index 000000000..d2b0dd06f Binary files /dev/null and b/doc/html/img/esb/slip05.jpg differ diff --git a/doc/html/img/esb/slip06.jpg b/doc/html/img/esb/slip06.jpg new file mode 100644 index 000000000..760be7db5 Binary files /dev/null and b/doc/html/img/esb/slip06.jpg differ diff --git a/doc/html/img/esb/slip07.jpg b/doc/html/img/esb/slip07.jpg new file mode 100644 index 000000000..16c846bd0 Binary files /dev/null and b/doc/html/img/esb/slip07.jpg differ diff --git a/doc/html/img/esb/slip08.jpg b/doc/html/img/esb/slip08.jpg new file mode 100644 index 000000000..b168848be Binary files /dev/null and b/doc/html/img/esb/slip08.jpg differ diff --git a/doc/html/img/esb/slip09.jpg b/doc/html/img/esb/slip09.jpg new file mode 100644 index 000000000..e30162206 Binary files /dev/null and b/doc/html/img/esb/slip09.jpg differ diff --git a/doc/html/img/esb/slip10.jpg b/doc/html/img/esb/slip10.jpg new file mode 100644 index 000000000..4de9bfa8d Binary files /dev/null and b/doc/html/img/esb/slip10.jpg differ diff --git a/doc/html/img/esb/slip11.jpg b/doc/html/img/esb/slip11.jpg new file mode 100644 index 000000000..6ee764926 Binary files /dev/null and b/doc/html/img/esb/slip11.jpg differ diff --git a/doc/html/img/esb/slip12.jpg b/doc/html/img/esb/slip12.jpg new file mode 100644 index 000000000..3d6a27b93 Binary files /dev/null and b/doc/html/img/esb/slip12.jpg differ diff --git a/doc/html/img/esb/slip13.jpg b/doc/html/img/esb/slip13.jpg new file mode 100644 index 000000000..3effc3308 Binary files /dev/null and b/doc/html/img/esb/slip13.jpg differ diff --git a/doc/html/img/esb/slip14b.jpg b/doc/html/img/esb/slip14b.jpg new file mode 100644 index 000000000..5c6e663ee Binary files /dev/null and b/doc/html/img/esb/slip14b.jpg differ diff --git a/doc/html/img/esb/slip15.jpg b/doc/html/img/esb/slip15.jpg new file mode 100644 index 000000000..aece50816 Binary files /dev/null and b/doc/html/img/esb/slip15.jpg differ diff --git a/doc/html/img/esb/slip16.jpg b/doc/html/img/esb/slip16.jpg new file mode 100644 index 000000000..743677054 Binary files /dev/null and b/doc/html/img/esb/slip16.jpg differ diff --git a/doc/lib.txt b/doc/lib.txt new file mode 100644 index 000000000..d1250f902 --- /dev/null +++ b/doc/lib.txt @@ -0,0 +1,5 @@ +/** +\defgroup lib Libraries +@{ +*/ +/** @} */ diff --git a/doc/mem.txt b/doc/mem.txt new file mode 100644 index 000000000..cce1d536d --- /dev/null +++ b/doc/mem.txt @@ -0,0 +1,5 @@ +/** +\defgroup mem Memory functions +@{ +*/ +/** @} */ diff --git a/doc/net.txt b/doc/net.txt new file mode 100644 index 000000000..ebb79a756 --- /dev/null +++ b/doc/net.txt @@ -0,0 +1,5 @@ +/** +\defgroup net Network functions +@{ +*/ +/** @} */ diff --git a/doc/platform.txt b/doc/platform.txt new file mode 100644 index 000000000..13b1f0b13 --- /dev/null +++ b/doc/platform.txt @@ -0,0 +1,6 @@ +/** +\defgroup platform Contiki platforms + +@{ +*/ +/** @} */ diff --git a/doc/pt-doc.txt b/doc/pt-doc.txt new file mode 100644 index 000000000..0eeb6cf50 --- /dev/null +++ b/doc/pt-doc.txt @@ -0,0 +1,178 @@ +/** +\addtogroup sys +@{ +*/ + +/** +\defgroup pt Protothreads + +Protothreads are a type of lightweight stackless threads designed for +severly memory constrained systems such as deeply embedded systems or +sensor network nodes. Protothreads provides linear code execution for +event-driven systems implemented in C. Protothreads can be used with +or without an RTOS. + +Protothreads are a extremely lightweight, stackless type of threads +that provides a blocking context on top of an event-driven system, +without the overhead of per-thread stacks. The purpose of protothreads +is to implement sequential flow of control without complex state +machines or full multi-threading. Protothreads provides conditional +blocking inside C functions. + +The advantage of protothreads over a purely event-driven approach is +that protothreads provides a sequential code structure that allows for +blocking functions. In purely event-driven systems, blocking must be +implemented by manually breaking the function into two pieces - one +for the piece of code before the blocking call and one for the code +after the blocking call. This makes it hard to use control structures +such as if() conditionals and while() loops. + +The advantage of protothreads over ordinary threads is that a +protothread do not require a separate stack. In memory constrained +systems, the overhead of allocating multiple stacks can consume large +amounts of the available memory. In contrast, each protothread only +requires between two and twelve bytes of state, depending on the +architecture. + +\note Because protothreads do not save the stack context across a +blocking call, local variables are not preserved when the +protothread blocks. This means that local variables should be used +with utmost care - if in doubt, do not use local variables inside a +protothread! + + +Main features: + + - No machine specific code - the protothreads library is pure C + + - Does not use error-prone functions such as longjmp() + + - Very small RAM overhead - only two bytes per protothread + + - Can be used with or without an OS + + - Provides blocking wait without full multi-threading or + stack-switching + +Examples applications: + + - Memory constrained systems + + - Event-driven protocol stacks + + - Deeply embedded systems + + - Sensor network nodes + +The protothreads API consists of four basic operations: +initialization: PT_INIT(), execution: PT_BEGIN(), conditional +blocking: PT_WAIT_UNTIL() and exit: PT_END(). On top of these, two +convenience functions are built: reversed condition blocking: +PT_WAIT_WHILE() and protothread blocking: PT_WAIT_THREAD(). + +\sa \ref pt "Protothreads API documentation" + +The protothreads library is released under a BSD-style license that +allows for both non-commercial and commercial usage. The only +requirement is that credit is given. + +\section authors Authors + +The protothreads library was written by Adam Dunkels +with support from Oliver Schmidt . + +\section pt-desc Protothreads + +Protothreads are a extremely lightweight, stackless threads that +provides a blocking context on top of an event-driven system, without +the overhead of per-thread stacks. The purpose of protothreads is to +implement sequential flow of control without using complex state +machines or full multi-threading. Protothreads provides conditional +blocking inside a C function. + +In memory constrained systems, such as deeply embedded systems, +traditional multi-threading may have a too large memory overhead. In +traditional multi-threading, each thread requires its own stack, that +typically is over-provisioned. The stacks may use large parts of the +available memory. + +The main advantage of protothreads over ordinary threads is that +protothreads are very lightweight: a protothread does not require its +own stack. Rather, all protothreads run on the same stack and context +switching is done by stack rewinding. This is advantageous in memory +constrained systems, where a stack for a thread might use a large part +of the available memory. A protothread only requires only two bytes of +memory per protothread. Moreover, protothreads are implemented in pure +C and do not require any machine-specific assembler code. + +A protothread runs within a single C function and cannot span over +other functions. A protothread may call normal C functions, but cannot +block inside a called function. Blocking inside nested function calls +is instead made by spawning a separate protothread for each +potentially blocking function. The advantage of this approach is that +blocking is explicit: the programmer knows exactly which functions +that block that which functions the never blocks. + +Protothreads are similar to asymmetric co-routines. The main +difference is that co-routines uses a separate stack for each +co-routine, whereas protothreads are stackless. The most similar +mechanism to protothreads are Python generators. These are also +stackless constructs, but have a different purpose. Protothreads +provides blocking contexts inside a C function, whereas Python +generators provide multiple exit points from a generator function. + +\section pt-autovars Local variables + +\note +Because protothreads do not save the stack context across a blocking +call, local variables are not preserved when the protothread +blocks. This means that local variables should be used with utmost +care - if in doubt, do not use local variables inside a protothread! + +\section pt-scheduling Scheduling + +A protothread is driven by repeated calls to the function in which the +protothread is running. Each time the function is called, the +protothread will run until it blocks or exits. Thus the scheduling of +protothreads is done by the application that uses protothreads. + +\section pt-impl Implementation + +Protothreads are implemented using \ref lc "local continuations". A +local continuation represents the current state of execution at a +particular place in the program, but does not provide any call history +or local variables. A local continuation can be set in a specific +function to capture the state of the function. After a local +continuation has been set can be resumed in order to restore the state +of the function at the point where the local continuation was set. + + +Local continuations can be implemented in a variety of ways: + + -# by using machine specific assembler code, + -# by using standard C constructs, or + -# by using compiler extensions. + +The first way works by saving and restoring the processor state, +except for stack pointers, and requires between 16 and 32 bytes of +memory per protothread. The exact amount of memory required depends on +the architecture. + +The standard C implementation requires only two bytes of state per +protothread and utilizes the C switch() statement in a non-obvious way +that is similar to Duff's device. This implementation does, however, +impose a slight restriction to the code that uses protothreads in that +the code cannot use switch() statements itself. + +Certain compilers has C extensions that can be used to implement +protothreads. GCC supports label pointers that can be used for this +purpose. With this implementation, protothreads require 4 bytes of RAM +per protothread. + +@{ + + +*/ + +/** @} */ +/** @} */ \ No newline at end of file diff --git a/doc/sys.txt b/doc/sys.txt new file mode 100644 index 000000000..d44e56c34 --- /dev/null +++ b/doc/sys.txt @@ -0,0 +1,5 @@ +/** +\defgroup sys Contiki system +@{ +*/ +/** @} */ diff --git a/doc/uip-doc.txt b/doc/uip-doc.txt new file mode 100644 index 000000000..cecb6b89c --- /dev/null +++ b/doc/uip-doc.txt @@ -0,0 +1,1193 @@ +/** +\addtogroup net +@{ +*/ + + + +/** +\defgroup uip The uIP TCP/IP stack +@{ + +The uIP TCP/IP stack provides Internet communication abilities to +Contiki. + +\section uip-introduction uIP introduction + +The uIP TCP/IP stack is intended to make it possible to communicate +using the TCP/IP protocol suite even on small 8-bit +micro-controllers. Despite being small and simple, uIP do not require +their peers to have complex, full-size stacks, but can communicate +with peers running a similarly light-weight stack. The code size is on +the order of a few kilobytes and RAM usage can be configured to be as +low as a few hundred bytes. + +uIP can be found at the uIP web page: http://www.sics.se/~adam/uip/ + +\sa \ref tcpip +\sa \ref uipopt "uIP Compile-time configuration options" +\sa \ref uipconffunc "uIP Run-time configuration functions" +\sa \ref uipinit "uIP initialization functions" +\sa \ref uipdevfunc "uIP device driver interface" and + \ref uipdrivervars "uIP variables used by device drivers" +\sa \ref uipappfunc "uIP functions called from application programs" +(see below) and the \ref psock "protosockets API" and their underlying +\ref pt "protothreads" + +\section uIPIntroduction Introduction + +With the success of the Internet, the TCP/IP protocol suite has become +a global standard for communication. TCP/IP is the underlying protocol +used for web page transfers, e-mail transmissions, file transfers, and +peer-to-peer networking over the Internet. For embedded systems, being +able to run native TCP/IP makes it possible to connect the system +directly to an intranet or even the global Internet. Embedded devices +with full TCP/IP support will be first-class network citizens, thus +being able to fully communicate with other hosts in the network. + +Traditional TCP/IP implementations have required far too much +resources both in terms of code size and memory usage to be useful in +small 8 or 16-bit systems. Code size of a few hundred kilobytes and +RAM requirements of several hundreds of kilobytes have made it +impossible to fit the full TCP/IP stack into systems with a few tens +of kilobytes of RAM and room for less than 100 kilobytes of +code. + +The uIP implementation is designed to have only the absolute minimal +set of features needed for a full TCP/IP stack. It can only handle a +single network interface and contains the IP, ICMP, UDP and TCP +protocols. uIP is written in the C programming language. + +Many other TCP/IP implementations for small systems assume that the +embedded device always will communicate with a full-scale TCP/IP +implementation running on a workstation-class machine. Under this +assumption, it is possible to remove certain TCP/IP mechanisms that +are very rarely used in such situations. Many of those mechanisms are +essential, however, if the embedded device is to communicate with +another equally limited device, e.g., when running distributed +peer-to-peer services and protocols. uIP is designed to be RFC +compliant in order to let the embedded devices to act as first-class +network citizens. The uIP TCP/IP implementation that is not tailored +for any specific application. + + +\section uip-tcpip TCP/IP Communication + +The full TCP/IP suite consists of numerous protocols, ranging from low +level protocols such as ARP which translates IP addresses to MAC +addresses, to application level protocols such as SMTP that is used to +transfer e-mail. The uIP is mostly concerned with the TCP and IP +protocols and upper layer protocols will be referred to as "the +application". Lower layer protocols are often implemented in hardware +or firmware and will be referred to as "the network device" that are +controlled by the network device driver. + +TCP provides a reliable byte stream to the upper layer protocols. It +breaks the byte stream into appropriately sized segments and each +segment is sent in its own IP packet. The IP packets are sent out on +the network by the network device driver. If the destination is not on +the physically connected network, the IP packet is forwarded onto +another network by a router that is situated between the two +networks. If the maximum packet size of the other network is smaller +than the size of the IP packet, the packet is fragmented into smaller +packets by the router. If possible, the size of the TCP segments are +chosen so that fragmentation is minimized. The final recipient of the +packet will have to reassemble any fragmented IP packets before they +can be passed to higher layers. + +The formal requirements for the protocols in the TCP/IP stack is +specified in a number of RFC documents published by the Internet +Engineering Task Force, IETF. Each of the protocols in the stack is +defined in one more RFC documents and RFC1122 collects +all requirements and updates the previous RFCs. + +The RFC1122 requirements can be divided into two categories; those +that deal with the host to host communication and those that deal with +communication between the application and the networking stack. An +example of the first kind is "A TCP MUST be able to receive a TCP +option in any segment" and an example of the second kind is "There +MUST be a mechanism for reporting soft TCP error conditions to the +application." A TCP/IP implementation that violates requirements of +the first kind may not be able to communicate with other TCP/IP +implementations and may even lead to network failures. Violation of +the second kind of requirements will only affect the communication +within the system and will not affect host-to-host communication. + +In uIP, all RFC requirements that affect host-to-host communication +are implemented. However, in order to reduce code size, we have +removed certain mechanisms in the interface between the application +and the stack, such as the soft error reporting mechanism and +dynamically configurable type-of-service bits for TCP +connections. Since there are only very few applications that make use +of those features they can be removed without loss of generality. + +\section mainloop Main Control Loop + +The uIP stack can be run either as a task in a multitasking system, or +as the main program in a singletasking system. In both cases, the main +control loop does two things repeatedly: + + - Check if a packet has arrived from the network. + - Check if a periodic timeout has occurred. + +If a packet has arrived, the input handler function, uip_input(), +should be invoked by the main control loop. The input handler function +will never block, but will return at once. When it returns, the stack +or the application for which the incoming packet was intended may have +produced one or more reply packets which should be sent out. If so, +the network device driver should be called to send out these packets. + +Periodic timeouts are used to drive TCP mechanisms that depend on +timers, such as delayed acknowledgments, retransmissions and +round-trip time estimations. When the main control loop infers that +the periodic timer should fire, it should invoke the timer handler +function uip_periodic(). Because the TCP/IP stack may perform +retransmissions when dealing with a timer event, the network device +driver should called to send out the packets that may have been produced. + +\section arch Architecture Specific Functions + +uIP requires a few functions to be implemented specifically for the +architecture on which uIP is intended to run. These functions should +be hand-tuned for the particular architecture, but generic C +implementations are given as part of the uIP distribution. + +\subsection checksums Checksum Calculation + +The TCP and IP protocols implement a checksum that covers the data and +header portions of the TCP and IP packets. Since the calculation of +this checksum is made over all bytes in every packet being sent and +received it is important that the function that calculates the +checksum is efficient. Most often, this means that the checksum +calculation must be fine-tuned for the particular architecture on +which the uIP stack runs. + +While uIP includes a generic checksum function, it also leaves it open +for an architecture specific implementation of the two functions +uip_ipchksum() and uip_tcpchksum(). The checksum calculations in those +functions can be written in highly optimized assembler rather than +generic C code. + +\subsection longarith 32-bit Arithmetic + +The TCP protocol uses 32-bit sequence numbers, and a TCP +implementation will have to do a number of 32-bit additions as part of +the normal protocol processing. Since 32-bit arithmetic is not +natively available on many of the platforms for which uIP is intended, +uIP leaves the 32-bit additions to be implemented by the architecture +specific module and does not make use of any 32-bit arithmetic in the +main code base. + +While uIP implements a generic 32-bit addition, there is support for +having an architecture specific implementation of the uip_add32() +function. + + +\section memory Memory Management + +In the architectures for which uIP is intended, RAM is the most +scarce resource. With only a few kilobytes of RAM available for the +TCP/IP stack to use, mechanisms used in traditional TCP/IP cannot be +directly applied. + + +The uIP stack does not use explicit dynamic memory +allocation. Instead, it uses a single global buffer for holding +packets and has a fixed table for holding connection state. The global +packet buffer is large enough to contain one packet of maximum +size. When a packet arrives from the network, the device driver places +it in the global buffer and calls the TCP/IP stack. If the packet +contains data, the TCP/IP stack will notify the corresponding +application. Because the data in the buffer will be overwritten by the +next incoming packet, the application will either have to act +immediately on the data or copy the data into a secondary buffer for +later processing. The packet buffer will not be overwritten by new +packets before the application has processed the data. Packets that +arrive when the application is processing the data must be queued, +either by the network device or by the device driver. Most single-chip +Ethernet controllers have on-chip buffers that are large enough to +contain at least 4 maximum sized Ethernet frames. Devices that are +handled by the processor, such as RS-232 ports, can copy incoming +bytes to a separate buffer during application processing. If the +buffers are full, the incoming packet is dropped. This will cause +performance degradation, but only when multiple connections are +running in parallel. This is because uIP advertises a very small +receiver window, which means that only a single TCP segment will be in +the network per connection. + +In uIP, the same global packet buffer that is used for incoming +packets is also used for the TCP/IP headers of outgoing data. If the +application sends dynamic data, it may use the parts of the global +packet buffer that are not used for headers as a temporary storage +buffer. To send the data, the application passes a pointer to the data +as well as the length of the data to the stack. The TCP/IP headers are +written into the global buffer and once the headers have been +produced, the device driver sends the headers and the application data +out on the network. The data is not queued for +retransmissions. Instead, the application will have to reproduce the +data if a retransmission is necessary. + +The total amount of memory usage for uIP depends heavily on the +applications of the particular device in which the implementations are +to be run. The memory configuration determines both the amount of +traffic the system should be able to handle and the maximum amount of +simultaneous connections. A device that will be sending large e-mails +while at the same time running a web server with highly dynamic web +pages and multiple simultaneous clients, will require more RAM than a +simple Telnet server. It is possible to run the uIP implementation +with as little as 200 bytes of RAM, but such a configuration will +provide extremely low throughput and will only allow a small number of +simultaneous connections. + +\section api Application Program Interface (API) + + +The Application Program Interface (API) defines the way the +application program interacts with the TCP/IP stack. The most commonly +used API for TCP/IP is the BSD socket API which is used in most Unix +systems and has heavily influenced the Microsoft Windows WinSock +API. Because the socket API uses stop-and-wait semantics, it requires +support from an underlying multitasking operating system. Since the +overhead of task management, context switching and allocation of stack +space for the tasks might be too high in the intended uIP target +architectures, the BSD socket interface is not suitable for our +purposes. + +uIP provides two APIs to programmers: protosockets, a BSD socket-like +API without the overhead of full multi-threading, and a "raw" +event-based API that is nore low-level than protosockets but uses less +memory. + +\sa \ref psock +\sa \ref pt + + +\subsection rawapi The uIP raw API + +The "raw" uIP API uses an event driven interface where the application is +invoked in response to certain events. An application running on top +of uIP is implemented as a C function that is called by uIP in +response to certain events. uIP calls the application when data is +received, when data has been successfully delivered to the other end +of the connection, when a new connection has been set up, or when data +has to be retransmitted. The application is also periodically polled +for new data. The application program provides only one callback +function; it is up to the application to deal with mapping different +network services to different ports and connections. Because the +application is able to act on incoming data and connection requests as +soon as the TCP/IP stack receives the packet, low response times can +be achieved even in low-end systems. + +uIP is different from other TCP/IP stacks in that it requires help +from the application when doing retransmissions. Other TCP/IP stacks +buffer the transmitted data in memory until the data is known to be +successfully delivered to the remote end of the connection. If the +data needs to be retransmitted, the stack takes care of the +retransmission without notifying the application. With this approach, +the data has to be buffered in memory while waiting for an +acknowledgment even if the application might be able to quickly +regenerate the data if a retransmission has to be made. + +In order to reduce memory usage, uIP utilizes the fact that the +application may be able to regenerate sent data and lets the +application take part in retransmissions. uIP does not keep track of +packet contents after they have been sent by the device driver, and +uIP requires that the application takes an active part in performing +the retransmission. When uIP decides that a segment should be +retransmitted, it calls the application with a flag set indicating +that a retransmission is required. The application checks the +retransmission flag and produces the same data that was previously +sent. From the application's standpoint, performing a retransmission +is not different from how the data originally was sent. Therefore the +application can be written in such a way that the same code is used +both for sending data and retransmitting data. Also, it is important +to note that even though the actual retransmission operation is +carried out by the application, it is the responsibility of the stack +to know when the retransmission should be made. Thus the complexity of +the application does not necessarily increase because it takes an +active part in doing retransmissions. + +\subsubsection appevents Application Events + +The application must be implemented as a C function, UIP_APPCALL(), +that uIP calls whenever an event occurs. Each event has a corresponding +test function that is used to distinguish between different +events. The functions are implemented as C macros that will evaluate +to either zero or non-zero. Note that certain events can happen in +conjunction with each other (i.e., new data can arrive at the same +time as data is acknowledged). + +\subsubsection connstate The Connection Pointer + +When the application is called by uIP, the global variable uip_conn is +set to point to the uip_conn structure for the connection that +currently is handled, and is called the "current connection". The +fields in the uip_conn structure for the current connection can be +used, e.g., to distinguish between different services, or to check to +which IP address the connection is connected. One typical use would be +to inspect the uip_conn->lport (the local TCP port number) to decide +which service the connection should provide. For instance, an +application might decide to act as an HTTP server if the value of +uip_conn->lport is equal to 80 and act as a TELNET server if the value +is 23. + +\subsubsection recvdata Receiving Data + +If the uIP test function uip_newdata() is non-zero, the remote host of +the connection has sent new data. The uip_appdata pointer point to the +actual data. The size of the data is obtained through the uIP function +uip_datalen(). The data is not buffered by uIP, but will be +overwritten after the application function returns, and the +application will therefor have to either act directly on the incoming +data, or by itself copy the incoming data into a buffer for later +processing. + +\subsubsection senddata Sending Data + +When sending data, uIP adjusts the length of the data sent by the +application according to the available buffer space and the current +TCP window advertised by the receiver. The amount of buffer space is +dictated by the memory configuration. It is therefore possible that +all data sent from the application does not arrive at the receiver, +and the application may use the uip_mss() function to see how much +data that actually will be sent by the stack. + +The application sends data by using the uIP function uip_send(). The +uip_send() function takes two arguments; a pointer to the data to be +sent and the length of the data. If the application needs RAM space +for producing the actual data that should be sent, the packet buffer +(pointed to by the uip_appdata pointer) can be used for this purpose. + +The application can send only one chunk of data at a time on a +connection and it is not possible to call uip_send() more than once +per application invocation; only the data from the last call will be +sent. + +\subsubsection rexmitdata Retransmitting Data + +Retransmissions are driven by the periodic TCP timer. Every time the +periodic timer is invoked, the retransmission timer for each +connection is decremented. If the timer reaches zero, a retransmission +should be made. As uIP does not keep track of packet contents after they have +been sent by the device driver, uIP requires that the +application takes an active part in performing the +retransmission. When uIP decides that a segment should be +retransmitted, the application function is called with the +uip_rexmit() flag set, indicating that a retransmission is +required. + +The application must check the uip_rexmit() flag and produce the same +data that was previously sent. From the application's standpoint, +performing a retransmission is not different from how the data +originally was sent. Therefor, the application can be written in such +a way that the same code is used both for sending data and +retransmitting data. Also, it is important to note that even though +the actual retransmission operation is carried out by the application, +it is the responsibility of the stack to know when the retransmission +should be made. Thus the complexity of the application does not +necessarily increase because it takes an active part in doing +retransmissions. + +\subsubsection closing Closing Connections + +The application closes the current connection by calling the +uip_close() during an application call. This will cause the connection +to be cleanly closed. In order to indicate a fatal error, the +application might want to abort the connection and does so by calling +the uip_abort() function. + +If the connection has been closed by the remote end, the test function +uip_closed() is true. The application may then do any necessary +cleanups. + +\subsubsection errors Reporting Errors + +There are two fatal errors that can happen to a connection, either +that the connection was aborted by the remote host, or that the +connection retransmitted the last data too many times and has been +aborted. uIP reports this by calling the application function. The +application can use the two test functions uip_aborted() and +uip_timedout() to test for those error conditions. + +\subsubsection polling Polling + +When a connection is idle, uIP polls the application every time the +periodic timer fires. The application uses the test function +uip_poll() to check if it is being polled by uIP. + +The polling event has two purposes. The first is to let the +application periodically know that a connection is idle, which allows +the application to close connections that have been idle for too +long. The other purpose is to let the application send new data that +has been produced. The application can only send data when invoked by +uIP, and therefore the poll event is the only way to send data on an +otherwise idle connection. + +\subsubsection listen Listening Ports + +uIP maintains a list of listening TCP ports. A new port is opened for +listening with the uip_listen() function. When a connection request +arrives on a listening port, uIP creates a new connection and calls +the application function. The test function uip_connected() is true if +the application was invoked because a new connection was created. + +The application can check the lport field in the uip_conn structure to +check to which port the new connection was connected. + +\subsubsection connect Opening Connections + +New connections can be opened from within +uIP by the function uip_connect(). This function +allocates a new connection and sets a flag in the connection state +which will open a TCP connection to the specified IP address and port +the next time the connection is polled by uIP. The uip_connect() +function returns +a pointer to the uip_conn structure for the new +connection. If there are no free connection slots, the function +returns NULL. + +The function uip_ipaddr() may be used to pack an IP address into the +two element 16-bit array used by uIP to represent IP addresses. + +Two examples of usage are shown below. The first example shows how to +open a connection to TCP port 8080 of the remote end of the current +connection. If there are not enough TCP connection slots to allow a +new connection to be opened, the uip_connect() function returns NULL +and the current connection is aborted by uip_abort(). + +\code +void connect_example1_app(void) { + if(uip_connect(uip_conn->ripaddr, HTONS(8080)) == NULL) { + uip_abort(); + } +} +\endcode + +The second example shows how to open a new connection to a specific IP +address. No error checks are made in this example. + +\code +void connect_example2(void) { + uip_addr_t ipaddr; + + uip_ipaddr(ipaddr, 192,168,0,1); + uip_connect(ipaddr, HTONS(8080)); +} +\endcode + +\section examples Examples + +This section presents a number of very simple uIP applications. The +uIP code distribution contains several more complex applications. + +\subsection example1 A Very Simple Application + +This first example shows a very simple application. The application +listens for incoming connections on port 1234. When a connection has +been established, the application replies to all data sent to it by +saying "ok" + +The implementation of this application is shown below. The application +is initialized with the function called example1_init() and the uIP +callback function is called example1_app(). For this application, the +configuration variable UIP_APPCALL should be defined to be +example1_app(). + +\code +void example1_init(void) { + uip_listen(HTONS(1234)); +} + +void example1_app(void) { + if(uip_newdata() || uip_rexmit()) { + uip_send("ok\n", 3); + } +} +\endcode + +The initialization function calls the uIP function uip_listen() to +register a listening port. The actual application function +example1_app() uses the test functions uip_newdata() and uip_rexmit() +to determine why it was called. If the application was called because +the remote end has sent it data, it responds with an "ok". If the +application function was called because data was lost in the network +and has to be retransmitted, it also sends an "ok". Note that this +example actually shows a complete uIP application. It is not required +for an application to deal with all types of events such as +uip_connected() or uip_timedout(). + +\subsection example2 A More Advanced Application + +This second example is slightly more advanced than the previous one, +and shows how the application state field in the uip_conn structure is +used. + +This application is similar to the first application in that it +listens to a port for incoming connections and responds to data sent +to it with a single "ok". The big difference is that this application +prints out a welcoming "Welcome!" message when the connection has been +established. + +This seemingly small change of operation makes a big difference in how +the application is implemented. The reason for the increase in +complexity is that if data should be lost in the network, the +application must know what data to retransmit. If the "Welcome!" +message was lost, the application must retransmit the welcome and if +one of the "ok" messages is lost, the application must send a new +"ok". + +The application knows that as long as the "Welcome!" message has not +been acknowledged by the remote host, it might have been dropped in +the network. But once the remote host has sent an acknowledgment +back, the application can be sure that the welcome has been received +and knows that any lost data must be an "ok" message. Thus the +application can be in either of two states: either in the WELCOME-SENT +state where the "Welcome!" has been sent but not acknowledged, or in +the WELCOME-ACKED state where the "Welcome!" has been acknowledged. + +When a remote host connects to the application, the application sends +the "Welcome!" message and sets it's state to WELCOME-SENT. When the +welcome message is acknowledged, the application moves to the +WELCOME-ACKED state. If the application receives any new data from the +remote host, it responds by sending an "ok" back. + +If the application is requested to retransmit the last message, it +looks at in which state the application is. If the application is in +the WELCOME-SENT state, it sends a "Welcome!" message since it +knows that the previous welcome message hasn't been acknowledged. If +the application is in the WELCOME-ACKED state, it knows that the last +message was an "ok" message and sends such a message. + +The implementation of this application is seen below. This +configuration settings for the application is follows after its +implementation. + +\code +struct example2_state { + enum {WELCOME_SENT, WELCOME_ACKED} state; +}; + +void example2_init(void) { + uip_listen(HTONS(2345)); +} + +void example2_app(void) { + struct example2_state *s; + + s = (struct example2_state *)uip_conn->appstate; + + if(uip_connected()) { + s->state = WELCOME_SENT; + uip_send("Welcome!\n", 9); + return; + } + + if(uip_acked() && s->state == WELCOME_SENT) { + s->state = WELCOME_ACKED; + } + + if(uip_newdata()) { + uip_send("ok\n", 3); + } + + if(uip_rexmit()) { + switch(s->state) { + case WELCOME_SENT: + uip_send("Welcome!\n", 9); + break; + case WELCOME_ACKED: + uip_send("ok\n", 3); + break; + } + } +} +\endcode + +The configuration for the application: + +\code +#define UIP_APPCALL example2_app +#define UIP_APPSTATE_SIZE sizeof(struct example2_state) +\endcode + +\subsection example3 Differentiating Between Applications + +If the system should run multiple applications, one technique to +differentiate between them is to use the TCP port number of either the +remote end or the local end of the connection. The example below shows +how the two examples above can be combined into one application. + +\code +void example3_init(void) { + example1_init(); + example2_init(); +} + +void example3_app(void) { + switch(uip_conn->lport) { + case HTONS(1234): + example1_app(); + break; + case HTONS(2345): + example2_app(); + break; + } +} +\endcode + +\subsection example4 Utilizing TCP Flow Control + +This example shows a simple application that connects to a host, sends +an HTTP request for a file and downloads it to a slow device such a +disk drive. This shows how to use the flow control functions of uIP. + +\code +void example4_init(void) { + uip_ipaddr_t ipaddr; + uip_ipaddr(ipaddr, 192,168,0,1); + uip_connect(ipaddr, HTONS(80)); +} + +void example4_app(void) { + if(uip_connected() || uip_rexmit()) { + uip_send("GET /file HTTP/1.0\r\nServer:192.186.0.1\r\n\r\n", + 48); + return; + } + + if(uip_newdata()) { + device_enqueue(uip_appdata, uip_datalen()); + if(device_queue_full()) { + uip_stop(); + } + } + + if(uip_poll() && uip_stopped()) { + if(!device_queue_full()) { + uip_restart(); + } + } +} +\endcode + +When the connection has been established, an HTTP request is sent to +the server. Since this is the only data that is sent, the application +knows that if it needs to retransmit any data, it is that request that +should be retransmitted. It is therefore possible to combine these two +events as is done in the example. + +When the application receives new data from the remote host, it sends +this data to the device by using the function device_enqueue(). It is +important to note that this example assumes that this function copies +the data into its own buffers. The data in the uip_appdata buffer will +be overwritten by the next incoming packet. + +If the device's queue is full, the application stops the data from the +remote host by calling the uIP function uip_stop(). The application +can then be sure that it will not receive any new data until +uip_restart() is called. The application polling event is used to +check if the device's queue is no longer full and if so, the data flow +is restarted with uip_restart(). + +\subsection example5 A Simple Web Server + +This example shows a very simple file server application that listens +to two ports and uses the port number to determine which file to +send. If the files are properly formatted, this simple application can +be used as a web server with static pages. The implementation follows. + +\code +struct example5_state { + char *dataptr; + unsigned int dataleft; +}; + +void example5_init(void) { + uip_listen(HTONS(80)); + uip_listen(HTONS(81)); +} + +void example5_app(void) { + struct example5_state *s; + s = (struct example5_state)uip_conn->appstate; + + if(uip_connected()) { + switch(uip_conn->lport) { + case HTONS(80): + s->dataptr = data_port_80; + s->dataleft = datalen_port_80; + break; + case HTONS(81): + s->dataptr = data_port_81; + s->dataleft = datalen_port_81; + break; + } + uip_send(s->dataptr, s->dataleft); + return; + } + + if(uip_acked()) { + if(s->dataleft < uip_mss()) { + uip_close(); + return; + } + s->dataptr += uip_conn->len; + s->dataleft -= uip_conn->len; + uip_send(s->dataptr, s->dataleft); + } +} +\endcode + +The application state consists of a pointer to the data that should be +sent and the size of the data that is left to send. When a remote host +connects to the application, the local port number is used to +determine which file to send. The first chunk of data is sent using +uip_send(). uIP makes sure that no more than MSS bytes of data is +actually sent, even though s->dataleft may be larger than the MSS. + +The application is driven by incoming acknowledgments. When data has +been acknowledged, new data can be sent. If there is no more data to +send, the connection is closed using uip_close(). + +\subsection example6 Structured Application Program Design + +When writing larger programs using uIP it is useful to be able to +utilize the uIP API in a structured way. The following example +provides a structured design that has showed itself to be useful for +writing larger protocol implementations than the previous examples +showed here. The program is divided into an uIP event handler function +that calls seven application handler functions that process new data, +act on acknowledged data, send new data, deal with connection +establishment or closure events and handle errors. The functions are +called newdata(), acked(), senddata(), connected(), closed(), +aborted(), and timedout(), and needs to be written specifically for +the protocol that is being implemented. + +The uIP event handler function is shown below. + +\code +void example6_app(void) { + if(uip_aborted()) { + aborted(); + } + if(uip_timedout()) { + timedout(); + } + if(uip_closed()) { + closed(); + } + if(uip_connected()) { + connected(); + } + if(uip_acked()) { + acked(); + } + if(uip_newdata()) { + newdata(); + } + if(uip_rexmit() || + uip_newdata() || + uip_acked() || + uip_connected() || + uip_poll()) { + senddata(); + } +} +\endcode + +The function starts with dealing with any error conditions that might +have happened by checking if uip_aborted() or uip_timedout() are +true. If so, the appropriate error function is called. Also, if the +connection has been closed, the closed() function is called to the it +deal with the event. + +Next, the function checks if the connection has just been established +by checking if uip_connected() is true. The connected() function is +called and is supposed to do whatever needs to be done when the +connection is established, such as intializing the application state +for the connection. Since it may be the case that data should be sent +out, the senddata() function is called to deal with the outgoing data. + +The following very simple application serves as an example of how the +application handler functions might look. This application simply +waits for any data to arrive on the connection, and responds to the +data by sending out the message "Hello world!". To illustrate how to +develop an application state machine, this message is sent in two +parts, first the "Hello" part and then the "world!" part. + +\code +#define STATE_WAITING 0 +#define STATE_HELLO 1 +#define STATE_WORLD 2 + +struct example6_state { + u8_t state; + char *textptr; + int textlen; +}; + +static void aborted(void) {} +static void timedout(void) {} +static void closed(void) {} + +static void connected(void) { + struct example6_state *s = (struct example6_state *)uip_conn->appstate; + + s->state = STATE_WAITING; + s->textlen = 0; +} + +static void newdata(void) { + struct example6_state *s = (struct example6_state *)uip_conn->appstate; + + if(s->state == STATE_WAITING) { + s->state = STATE_HELLO; + s->textptr = "Hello "; + s->textlen = 6; + } +} + +static void acked(void) { + struct example6_state *s = (struct example6_state *)uip_conn->appstate; + + s->textlen -= uip_conn->len; + s->textptr += uip_conn->len; + if(s->textlen == 0) { + switch(s->state) { + case STATE_HELLO: + s->state = STATE_WORLD; + s->textptr = "world!\n"; + s->textlen = 7; + break; + case STATE_WORLD: + uip_close(); + break; + } + } +} + +static void senddata(void) { + struct example6_state *s = (struct example6_state *)uip_conn->appstate; + + if(s->textlen > 0) { + uip_send(s->textptr, s->textlen); + } +} +\endcode + +The application state consists of a "state" variable, a "textptr" +pointer to a text message and the "textlen" length of the text +message. The "state" variable can be either "STATE_WAITING", meaning +that the application is waiting for data to arrive from the network, +"STATE_HELLO", in which the application is sending the "Hello" part of +the message, or "STATE_WORLD", in which the application is sending the +"world!" message. + +The application does not handle errors or connection closing events, +and therefore the aborted(), timedout() and closed() functions are +implemented as empty functions. + +The connected() function will be called when a connection has been +established, and in this case sets the "state" variable to be +"STATE_WAITING" and the "textlen" variable to be zero, indicating that +there is no message to be sent out. + +When new data arrives from the network, the newdata() function will be +called by the event handler function. The newdata() function will +check if the connection is in the "STATE_WAITING" state, and if so +switches to the "STATE_HELLO" state and registers a 6 byte long "Hello +" message with the connection. This message will later be sent out by +the senddata() function. + +The acked() function is called whenever data that previously was sent +has been acknowleged by the receiving host. This acked() function +first reduces the amount of data that is left to send, by subtracting +the length of the previously sent data (obtained from "uip_conn->len") +from the "textlen" variable, and also adjusts the "textptr" pointer +accordingly. It then checks if the "textlen" variable now is zero, +which indicates that all data now has been successfully received, and +if so changes application state. If the application was in the +"STATE_HELLO" state, it switches state to "STATE_WORLD" and sets up a +7 byte "world!\n" message to be sent. If the application was in the +"STATE_WORLD" state, it closes the connection. + +Finally, the senddata() function takes care of actually sending the +data that is to be sent. It is called by the event handler function +when new data has been received, when data has been acknowledged, when +a new connection has been established, when the connection is polled +because of inactivity, or when a retransmission should be made. The +purpose of the senddata() function is to optionally format the data +that is to be sent, and to call the uip_send() function to actually +send out the data. In this particular example, the function simply +calls uip_send() with the appropriate arguments if data is to be sent, +after checking if data should be sent out or not as indicated by the +"textlen" variable. + +It is important to note that the senddata() function never should +affect the application state; this should only be done in the acked() +and newdata() functions. + +\section protoimpl Protocol Implementations + +The protocols in the TCP/IP protocol suite are designed in a layered +fashion where each protocol performs a specific function and the +interactions between the protocol layers are strictly defined. While +the layered approach is a good way to design protocols, it is not +always the best way to implement them. In uIP, the protocol +implementations are tightly coupled in order to save code space. + +This section gives detailed information on the specific protocol +implementations in uIP. + +\subsection ip IP --- Internet Protocol + +When incoming packets are processed by uIP, the IP layer is the first +protocol that examines the packet. The IP layer does a few simple +checks such as if the destination IP address of the incoming packet +matches any of the local IP address and verifies the IP header +checksum. Since there are no IP options that are strictly required and +because they are very uncommon, any IP options in received packets are +dropped. + +\subsubsection ipreass IP Fragment Reassembly + +IP fragment reassembly is implemented using a separate buffer that +holds the packet to be reassembled. An incoming fragment is copied +into the right place in the buffer and a bit map is used to keep track +of which fragments have been received. Because the first byte of an IP +fragment is aligned on an 8-byte boundary, the bit map requires a +small amount of memory. When all fragments have been reassembled, the +resulting IP packet is passed to the transport layer. If all fragments +have not been received within a specified time frame, the packet is +dropped. + +The current implementation only has a single buffer for holding +packets to be reassembled, and therefore does not support simultaneous +reassembly of more than one packet. Since fragmented packets are +uncommon, this ought to be a reasonable decision. Extending the +implementation to support multiple buffers would be straightforward, +however. + +\subsubsection ipbroadcast Broadcasts and Multicasts + +IP has the ability to broadcast and multicast packets on the local +network. Such packets are addressed to special broadcast and multicast +addresses. Broadcast is used heavily in many UDP based protocols such +as the Microsoft Windows file-sharing SMB protocol. Multicast is +primarily used in protocols used for multimedia distribution such as +RTP. TCP is a point-to-point protocol and does not use broadcast or +multicast packets. uIP current supports broadcast packets as well as +sending multicast packets. Joining multicast groups (IGMP) and +receiving non-local multicast packets is not currently supported. + +\subsection icmp ICMP --- Internet Control Message Protocol + +The ICMP protocol is used for reporting soft error conditions and for +querying host parameters. Its main use is, however, the echo mechanism +which is used by the "ping" program. + +The ICMP implementation in uIP is very simple as itis restricted to +only implement ICMP echo messages. Replies to echo messages are +constructed by simply swapping the source and destination IP addresses +of incoming echo requests and rewriting the ICMP header with the +Echo-Reply message type. The ICMP checksum is adjusted using standard +techniques (see RFC1624). + +Since only the ICMP echo message is implemented, there is no support +for Path MTU discovery or ICMP redirect messages. Neither of these is +strictly required for interoperability; they are performance +enhancement mechanisms. + +\subsection tcp TCP --- Transmission Control Protocol + +The TCP implementation in uIP is driven by incoming packets and timer +events. Incoming packets are parsed by TCP and if the packet contains +data that is to be delivered to the application, the application is +invoked by the means of the application function call. If the incoming +packet acknowledges previously sent data, the connection state is +updated and the application is informed, allowing it to send out new +data. + +\subsubsection listeb Listening Connections + +TCP allows a connection to listen for incoming connection requests. In +uIP, a listening connection is identified by the 16-bit port number +and incoming connection requests are checked against the list of +listening connections. This list of listening connections is dynamic +and can be altered by the applications in the system. + +\subsubsection slidingwindow Sliding Window + +Most TCP implementations use a sliding window mechanism for sending +data. Multiple data segments are sent in succession without waiting +for an acknowledgment for each segment. + +The sliding window algorithm uses a lot of 32-bit operations and +because 32-bit arithmetic is fairly expensive on most 8-bit CPUs, uIP +does not implement it. Also, uIP does not buffer sent packets and a +sliding window implementation that does not buffer sent packets will have +to be supported by a complex application layer. Instead, uIP allows +only a single TCP segment per connection to be unacknowledged at any +given time. + +It is important to note that even though most TCP implementations use +the sliding window algorithm, it is not required by the TCP +specifications. Removing the sliding window mechanism does not affect +interoperability in any way. + +\subsubsection rttest Round-Trip Time Estimation + +TCP continuously estimates the current Round-Trip Time (RTT) of every +active connection in order to find a suitable value for the +retransmission time-out. + +The RTT estimation in uIP is implemented using TCP's periodic +timer. Each time the periodic timer fires, it increments a counter for +each connection that has unacknowledged data in the network. When an +acknowledgment is received, the current value of the counter is used +as a sample of the RTT. The sample is used together with Van +Jacobson's standard TCP RTT estimation function to calculate an +estimate of the RTT. Karn's algorithm is used to ensure that +retransmissions do not skew the estimates. + +\subsubsection rexmit Retransmissions + +Retransmissions are driven by the periodic TCP timer. Every time the +periodic timer is invoked, the retransmission timer for each +connection is decremented. If the timer reaches zero, a retransmission +should be made. + +As uIP does not keep track of packet contents after they have +been sent by the device driver, uIP requires that the +application takes an active part in performing the +retransmission. When uIP decides that a segment should be +retransmitted, it calls the application with a flag set indicating +that a retransmission is required. The application checks the +retransmission flag and produces the same data that was previously +sent. From the application's standpoint, performing a retransmission +is not different from how the data originally was sent. Therefore the +application can be written in such a way that the same code is used +both for sending data and retransmitting data. Also, it is important +to note that even though the actual retransmission operation is +carried out by the application, it is the responsibility of the stack +to know when the retransmission should be made. Thus the complexity of +the application does not necessarily increase because it takes an +active part in doing retransmissions. + +\subsubsection flowcontrol Flow Control + +The purpose of TCP's flow control mechanisms is to allow communication +between hosts with wildly varying memory dimensions. In each TCP +segment, the sender of the segment indicates its available buffer +space. A TCP sender must not send more data than the buffer space +indicated by the receiver. + +In uIP, the application cannot send more data than the receiving host +can buffer. And application cannot send more data than the amount of +bytes it is allowed to send by the receiving host. If the remote host +cannot accept any data at all, the stack initiates the zero window +probing mechanism. + +\subsubsection congestioncontrol Congestion Control + +The congestion control mechanisms limit the number of simultaneous TCP +segments in the network. The algorithms used for congestion control +are designed to be simple to implement and require only a few lines of +code. + +Since uIP only handles one in-flight TCP segment per connection, +the amount of simultaneous segments cannot be further limited, thus +the congestion control mechanisms are not needed. + +\subsubsection urgdata Urgent Data + +TCP's urgent data mechanism provides an application-to-application +notification mechanism, which can be used by an application to mark +parts of the data stream as being more urgent than the normal +stream. It is up to the receiving application to interpret the meaning +of the urgent data. + +In many TCP implementations, including the BSD implementation, the +urgent data feature increases the complexity of the implementation +because it requires an asynchronous notification mechanism in an +otherwise synchronous API. As uIP already use an asynchronous event +based API, the implementation of the urgent data feature does not lead +to increased complexity. + +\section performance Performance + +In TCP/IP implementations for high-end systems, processing time is +dominated by the checksum calculation loop, the operation of copying +packet data and context switching. Operating systems for high-end +systems often have multiple protection domains for protecting kernel +data from user processes and user processes from each other. Because +the TCP/IP stack is run in the kernel, data has to be copied between +the kernel space and the address space of the user processes and a +context switch has to be performed once the data has been +copied. Performance can be enhanced by combining the copy operation +with the checksum calculation. Because high-end systems usually have +numerous active connections, packet demultiplexing is also an +expensive operation. + +A small embedded device does not have the necessary processing power +to have multiple protection domains and the power to run a +multitasking operating system. Therefore there is no need to copy +data between the TCP/IP stack and the application program. With an +event based API there is no context switch between the TCP/IP stack +and the applications. + +In such limited systems, the TCP/IP processing overhead is dominated +by the copying of packet data from the network device to host memory, +and checksum calculation. Apart from the checksum calculation and +copying, the TCP processing done for an incoming packet involves only +updating a few counters and flags before handing the data over to the +application. Thus an estimate of the CPU overhead of our TCP/IP +implementations can be obtained by calculating the amount of CPU +cycles needed for the checksum calculation and copying of a maximum +sized packet. + +\subsection delack The Impact of Delayed Acknowledgments + +Most TCP receivers implement the delayed acknowledgment algorithm for +reducing the number of pure acknowledgment packets sent. A TCP +receiver using this algorithm will only send acknowledgments for every +other received segment. If no segment is received within a specific +time-frame, an acknowledgment is sent. The time-frame can be as high +as 500 ms but typically is 200 ms. + +A TCP sender such as uIP that only handles a single outstanding TCP +segment will interact poorly with the delayed acknowledgment +algorithm. Because the receiver only receives a single segment at a +time, it will wait as much as 500 ms before an acknowledgment is +sent. This means that the maximum possible throughput is severely +limited by the 500 ms idle time. + +Thus the maximum throughput equation when sending data from uIP will +be $p = s / (t + t_d)$ where $s$ is the segment size and $t_d$ is the +delayed acknowledgment timeout, which typically is between 200 and +500 ms. With a segment size of 1000 bytes, a round-trip time of 40 ms +and a delayed acknowledgment timeout of 200 ms, the maximum +throughput will be 4166 bytes per second. With the delayed acknowledgment +algorithm disabled at the receiver, the maximum throughput would be +25000 bytes per second. + +It should be noted, however, that since small systems running uIP are +not very likely to have large amounts of data to send, the delayed +acknowledgmen t throughput degradation of uIP need not be very +severe. Small amounts of data sent by such a system will not span more +than a single TCP segment, and would therefore not be affected by the +throughput degradation anyway. + +The maximum throughput when uIP acts as a receiver is not affected by +the delayed acknowledgment throughput degradation. + +\note The \ref uipsplit module implements a hack that overcomes the +problems with the delayed acknowledgment throughput degradation. + + +*/ + + +/** @} */ +/** @} */ + diff --git a/examples/telnet-server/Makefile b/examples/telnet-server/Makefile new file mode 100644 index 000000000..c8133f08c --- /dev/null +++ b/examples/telnet-server/Makefile @@ -0,0 +1,5 @@ +all: telnet-server +APPS=telnetd + +CONTIKI = ../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/telnet-server/telnet-server.c b/examples/telnet-server/telnet-server.c new file mode 100644 index 000000000..768fc3eef --- /dev/null +++ b/examples/telnet-server/telnet-server.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: telnet-server.c,v 1.1 2006/06/17 22:41:24 adamdunkels Exp $ + */ + +/** + * \file + * Example showing how to use the Telnet server + * \author + * Adam Dunkels + */ + +#include "contiki-net.h" +#include "telnetd.h" + +/*---------------------------------------------------------------------------*/ +AUTOSTART_PROCESSES(&telnetd_process); +/*---------------------------------------------------------------------------*/ diff --git a/examples/test-ipv6/Makefile b/examples/test-ipv6/Makefile new file mode 100644 index 000000000..c217d3e8e --- /dev/null +++ b/examples/test-ipv6/Makefile @@ -0,0 +1,9 @@ +all: testv6 +APPS=webserver +CONTIKI = ../.. +TARGET=minimal-net +CFLAGS=-DUIP_CONF_IPV6 + +include $(CONTIKI)/Makefile.include + +testv6.$(TARGET): $(OBJECTDIR)/tapdev6.o #$(OBJECTDIR)/uip-keepalive.o diff --git a/examples/test-ipv6/tapdev.h b/examples/test-ipv6/tapdev.h new file mode 100644 index 000000000..544cdb104 --- /dev/null +++ b/examples/test-ipv6/tapdev.h @@ -0,0 +1,46 @@ +/* + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. 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: tapdev.h,v 1.1 2006/06/17 22:41:24 adamdunkels Exp $ + * + */ +#ifndef __TAPDEV_H__ +#define __TAPDEV_H__ + +#include "contiki-net.h" + +void tapdev_init(void); +u8_t tapdev_send(void); +u16_t tapdev_poll(void); +void tapdev_do_send(void); +#endif /* __TAPDEV_H__ */ diff --git a/examples/test-ipv6/tapdev6.c b/examples/test-ipv6/tapdev6.c new file mode 100644 index 000000000..19b1cdc13 --- /dev/null +++ b/examples/test-ipv6/tapdev6.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Adam Dunkels + * + * $Id: tapdev6.c,v 1.1 2006/06/17 22:41:24 adamdunkels Exp $ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef linux +#include +#include +#include +#define DEVTAP "/dev/net/tun" +#else /* linux */ +#define DEVTAP "/dev/tap0" +#endif /* linux */ + +#include "tapdev.h" + +#include "contiki-net.h" + +#define DROP 0 + +#if DROP +static int drop = 0; +#endif + +static int fd; + +static unsigned long lasttime; + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) +#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +static void do_send(void); +u8_t tapdev_send(void); + + +u16_t +tapdev_poll(void) +{ + fd_set fdset; + struct timeval tv; + int ret; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&fdset); + if(fd > 0) { + FD_SET(fd, &fdset); + } + + ret = select(fd + 1, &fdset, NULL, NULL, &tv); + + if(ret == 0) { + return 0; + } + ret = read(fd, uip_buf, UIP_BUFSIZE); + + /* printf("tapdev6: read %d bytes\n", ret);*/ + + if(ret == -1) { + perror("tapdev_poll: read"); + } + return ret; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_init(void) +{ + char buf[1024]; + + fd = open(DEVTAP, O_RDWR); + if(fd == -1) { + perror("tapdev: tapdev_init: open"); + return; + } + +#ifdef linux + { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { + perror(buf); + exit(1); + } + } +#endif /* Linux */ + + snprintf(buf, sizeof(buf), "ifconfig tap0 inet6 fc00::123"); + system(buf); + printf("%s\n", buf); + snprintf(buf, sizeof(buf), "route add -inet6 fc00::0/64 -interface tap0"); + system(buf); + printf("%s\n", buf); + + lasttime = 0; + + /* gdk_input_add(fd, GDK_INPUT_READ, + read_callback, NULL);*/ + +} +/*---------------------------------------------------------------------------*/ +static void +do_send(void) +{ + int ret; + + if(fd <= 0) { + return; + } + + + /* printf("tapdev_send: sending %d bytes\n", size);*/ + /* check_checksum(uip_buf, size);*/ +#if DROP + drop++; + if(drop % 8 == 7) { + printf("Dropped an output packet!\n"); + return; + } +#endif /* DROP */ + + ret = write(fd, uip_buf, uip_len); + + if(ret == -1) { + perror("tap_dev: tapdev_send: writev"); + exit(1); + } +} +/*---------------------------------------------------------------------------*/ +#define DEBUG_PRINTF(...) printf(__VA_ARGS__) +#define DEBUG_PRINT6ADDR(addr) DEBUG_PRINTF("%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", ((u8_t *)addr)[0], ((u8_t *)addr)[1], ((u8_t *)addr)[2], ((u8_t *)addr)[3], ((u8_t *)addr)[4], ((u8_t *)addr)[5], ((u8_t *)addr)[6], ((u8_t *)addr)[7], ((u8_t *)addr)[8], ((u8_t *)addr)[9], ((u8_t *)addr)[10], ((u8_t *)addr)[11], ((u8_t *)addr)[12], ((u8_t *)addr)[13], ((u8_t *)addr)[14], ((u8_t *)addr)[15]) +u8_t +tapdev_send(void) +{ + struct uip_neighbor_addr *addr; + /* uip_arp_out();*/ + + addr = uip_neighbor_lookup(IPBUF->destipaddr); + if(addr == NULL) { + printf("tapdev6: tapdev_send: no matching neighbor found\n"); + DEBUG_PRINT6ADDR(IPBUF->destipaddr); + printf("\n"); + } else { + memcpy(&BUF->dest, addr, 6); + memcpy(&BUF->src, &uip_ethaddr, 6); + uip_len += sizeof(struct uip_eth_hdr); + do_send(); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_do_send(void) +{ + do_send(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/test-ipv6/testv6.c b/examples/test-ipv6/testv6.c new file mode 100644 index 000000000..37d64071d --- /dev/null +++ b/examples/test-ipv6/testv6.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: testv6.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + */ + +#include "contiki-net.h" +#include "webserver-nogui.h" + +static const struct uip_eth_addr ethaddr = {{0x00,0x06,0x98,0x01,0x02,0x29}}; + +/*---------------------------------------------------------------------------*/ +PROCESS(test_process, "Test"); +PROCESS(test_tcpip_process, "tcp/ip test"); +AUTOSTART_PROCESSES(&test_process, &test_tcpip_process, &webserver_nogui_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_process, ev, data) +{ + uip_ip6addr_t ip6addr; + static struct etimer etimer; + + PROCESS_BEGIN(); + + uip_ip6addr(ip6addr, 0xfc00,0,0,0,0,0,0,0x232); + uip_sethostaddr(ip6addr); + uip_setethaddr(ethaddr); + + uip_ip6addr(ip6addr, 0xfc00,0,0,0,0,0,0,0x231); + + tcp_connect(ip6addr, HTONS(7), NULL); + + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_tcpip_process, ev, data) +{ + PROCESS_BEGIN(); + + tcp_listen(HTONS(800)); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == tcpip_event); + if(uip_newdata()) { + ((char *)uip_appdata)[uip_datalen()] = 0; + printf("New uIP data: '%s'\n", uip_appdata); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/webserver/Makefile b/examples/webserver/Makefile new file mode 100644 index 000000000..a8c5e72e4 --- /dev/null +++ b/examples/webserver/Makefile @@ -0,0 +1,7 @@ +all: webserver-example +APPS=webserver + +CONTIKI = ../.. +include $(CONTIKI)/Makefile.include + +webserver-example.$(TARGET): diff --git a/examples/webserver/webserver-example.c b/examples/webserver/webserver-example.c new file mode 100644 index 000000000..9603df66d --- /dev/null +++ b/examples/webserver/webserver-example.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: webserver-example.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + */ + +/** + * \file + * Example showing how to use the web server + * \author + * Adam Dunkels + */ + +#include "webserver-nogui.h" + +/*---------------------------------------------------------------------------*/ +AUTOSTART_PROCESSES(&webserver_nogui_process); +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/Makefile b/platform/c64/Makefile new file mode 100644 index 000000000..83c62cd74 --- /dev/null +++ b/platform/c64/Makefile @@ -0,0 +1,77 @@ +# 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: Makefile,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ +# + +CONTIKI=../.. +CONTIKICC65=../../cpu/6502 + +usage: + @echo "Make sure the Contiki sources is in the directory $(CONTIKI)" + @echo 'To compile Contiki, use "'$(MAKE)' target" where target' + @echo 'is one of the following:' + @echo all + @echo c64 + @echo programs + @echo d64 + @echo programs + @echo '(Also check the Makefile for more targets to try...)' + +all: clean c64 programs + +programs: + $(MAKE) CONTIKI=$(CONTIKI) CONTIKICC65=$(CONTIKICC65) -f Makefile.programs +c64: + $(MAKE) CONTIKI=$(CONTIKI) CONTIKICC65=$(CONTIKICC65) -f Makefile.c64 + +c64-exo: + $(MAKE) CONTIKI=$(CONTIKI) CONTIKICC65=$(CONTIKICC65) -f Makefile.c64 contiki-exo + +wget: + $(MAKE) CONTIKI=$(CONTIKI) CONTIKICC65=$(CONTIKICC65) -f Makefile.c64-wget + +installer: clean + $(MAKE) CONTIKI=$(CONTIKI) CONTIKICC65=$(CONTIKICC65) -f Makefile.installer + + +CCDEPFLAGS=-D__CBM__ -D__C64__ -DCTK_HIRES -DWITH_UIP -DWITH_LOADER_ARCH -I/usr/local/lib/cc65/include + +include $(CONTIKICC65)/Makefile.cc65 + +d64: + c1541 -format contiki,00 d64 contiki.d64 + c1541 -attach contiki.d64 -write contiki + c1541 -attach contiki.d64 -write config.cfg + c1541 -attach contiki.d64 $(foreach dsc, $(wildcard *.dsc), -write $(dsc)) + c1541 -attach contiki.d64 $(foreach prg, $(wildcard *.prg), -write $(prg)) + c1541 -attach contiki.d64 $(foreach sav, $(wildcard *.sav), -write $(sav)) + c1541 -attach contiki.d64 $(foreach drv, $(wildcard *.drv), -write $(drv)) + c1541 -attach contiki.d64 $(foreach ser, $(wildcard *.ser), -write $(ser)) + c1541 -attach contiki.d64 -list diff --git a/platform/c64/apps/blueround-dsc.c b/platform/c64/apps/blueround-dsc.c new file mode 100644 index 000000000..5ffa564c5 --- /dev/null +++ b/platform/c64/apps/blueround-dsc.c @@ -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: blueround-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon blueround_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(blueround_dsc, + "Blueround CTK theme", + "blueround.prg", + blueround_init, + &blueround_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char blueroundicon_bitmap[3*3*8] = { + 0xfe,0xf8,0xe0,0xc0,0xc0,0x80,0x80,0x00, + 0x00,0x55,0xaa,0x00,0xaa,0x00,0x00,0x00, + 0x7f,0x1f,0x07,0x03,0x03,0x01,0x01,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,0x80,0x80,0xc0,0xc0,0xe0,0xf8,0xfe, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01,0x01,0x03,0x03,0x07,0x1f,0x7f +}; +#endif /* CTK_CONF_ICON_BITMAPS */ + +#if CTK_CONF_ICON_TEXTMAPS +static char blueroundicon_textmap[9] = { + '(', '=', ')', + '|', 'o', '|', + '(', '-', ')' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon blueround_icon = + {CTK_ICON("Blueround", blueroundicon_bitmap, blueroundicon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/cgterm-dsc.c b/platform/c64/apps/cgterm-dsc.c new file mode 100644 index 000000000..5e069e320 --- /dev/null +++ b/platform/c64/apps/cgterm-dsc.c @@ -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: cgterm-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon cgterm_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(cgterm_dsc, + "Program for connecting to C64 Telnet BBSes", + "cgterm.prg", + cgterm_init, + &cgterm_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char cgtermicon_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 cgtermicon_textmap[9] = { + 'T', 'e', 'l', + 'n', 'e', 't', + 'B', 'B', 'S' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon cgterm_icon = + {CTK_ICON("C/G terminal", cgtermicon_bitmap, cgtermicon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/cgterm.c b/platform/c64/apps/cgterm.c new file mode 100644 index 000000000..f96be745a --- /dev/null +++ b/platform/c64/apps/cgterm.c @@ -0,0 +1,242 @@ +#include "contiki-net.h" +#include "ctk/ctk-draw.h" + +#include +#include +#include + +static struct { + struct psock sout, sin; + struct pt inpt, outpt; + char outputbuf[200]; + char inputbuf[200]; + unsigned short len; +} s; + +#define CURSOR_ON() *(char *)0xcc = 0 +#define CURSOR_OFF() *(char *)0xcc = 1 +static void ctkmode(void); +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(send(void)) +{ + PSOCK_BEGIN(&s.sout); + + PSOCK_SEND(&s.sout, s.outputbuf, s.len); + PSOCK_END(&s.sout); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_output(void)) +{ + ctk_arch_key_t c; + char *ptr; + + PT_BEGIN(&s.outpt); + + while(1) { + PT_WAIT_UNTIL(&s.outpt, (ctk_mode_get() == CTK_MODE_EXTERNAL) && + kbhit()); + + + ptr = s.outputbuf; + s.len = 0; + while(kbhit() && s.len < sizeof(s.outputbuf)) { + c = cgetc(); + *ptr = c; + ++ptr; + ++s.len; + } + + PT_WAIT_THREAD(&s.outpt, send()); + } + PT_END(&s.outpt); +} +/*---------------------------------------------------------------------------*/ +static +PT_THREAD(handle_input(void)) +{ + unsigned short i; + char *ptr; + char next; + + next = 1; + PT_BEGIN(&s.inpt); + + while(1) { + /* Wait until data arrives. */ + next = 0; + PT_WAIT_UNTIL(&s.inpt, next && uip_newdata()); + + CURSOR_OFF(); + /* Print it out on the screen. */ + ptr = (char *)uip_appdata; + for(i = 0; i < uip_len; ++i) { + cbm_k_bsout(*ptr); + ++ptr; + } + CURSOR_ON(); + } + PT_END(&s.inpt); +} +/*---------------------------------------------------------------------------*/ +static void +appcall(void *state) +{ + if(uip_closed() || uip_aborted() || uip_timedout()) { + ctkmode(); + } else if(uip_connected()) { + } else { + handle_input(); + handle_output(); + } +} +/*---------------------------------------------------------------------------*/ +static struct uip_conn * +connect(u16_t *host, u16_t port) +{ + PSOCK_INIT(&s.sin, s.inputbuf, sizeof(s.inputbuf)); + PSOCK_INIT(&s.sout, s.inputbuf, sizeof(s.inputbuf)); + PT_INIT(&s.inpt); + PT_INIT(&s.outpt); + return tcp_connect(host, htons(port), NULL); +} +/*---------------------------------------------------------------------------*/ +PROCESS(cgterm_process, "C/G terminal"); + +static struct uip_conn *conn; +static u16_t serveraddr[2]; +static u16_t serverport; +/*---------------------------------------------------------------------------*/ +static struct ctk_window window; +static struct ctk_label hostlabel = + {CTK_LABEL(0, 0, 4, 1, "Host")}; +static char host[32]; +static struct ctk_textentry hostentry = + {CTK_TEXTENTRY(5, 0, 20, 1, host, sizeof(host) - 1)}; +static struct ctk_label portlabel = + {CTK_LABEL(27, 0, 4, 1, "Port")}; +static char port[7]; +static struct ctk_textentry portentry = + {CTK_TEXTENTRY(32, 0, 4, 1, port, sizeof(port) - 1)}; +static struct ctk_button connectbutton = + {CTK_BUTTON(0, 2, 7, "Connect")}; +static struct ctk_button switchbutton = + {CTK_BUTTON(30, 2, 6, "Switch")}; +static struct ctk_label helplabel = + {CTK_LABEL(0, 4, 37, 1, "RUN/STOP to return from terminal view")}; +/*---------------------------------------------------------------------------*/ +static void +ctkmode(void) +{ + ctk_mode_set(CTK_MODE_NORMAL); + ctk_draw_init(); + ctk_desktop_redraw(NULL); +} +/*---------------------------------------------------------------------------*/ +static void +textmode(void) +{ + ctk_mode_set(CTK_MODE_EXTERNAL); + + VIC.ctrl1 = 0x1b; /* $D011 */ + VIC.addr = 0x17; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + CIA2.pra = 0x03; /* $DD00 */ + + VIC.bordercolor = 0x00; /* $D020 */ + VIC.bgcolor0 = 0x00; /* $D021 */ + + CURSOR_ON(); +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ + if(ctk_mode_get() == CTK_MODE_EXTERNAL) { + if(CIA1.prb == 0x7f) { + ctkmode(); + } else if(kbhit() && conn != NULL) { + tcpip_poll_tcp(conn); + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cgterm_process, ev, data) +{ + u16_t *ipaddr; + char *cptr; + + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + ctk_window_new(&window, 38, 5, "C/G term"); + CTK_WIDGET_ADD(&window, &hostlabel); + CTK_WIDGET_ADD(&window, &hostentry); + CTK_WIDGET_ADD(&window, &portlabel); + CTK_WIDGET_ADD(&window, &portentry); + CTK_WIDGET_ADD(&window, &connectbutton); + CTK_WIDGET_ADD(&window, &switchbutton); + CTK_WIDGET_ADD(&window, &helplabel); + ctk_window_open(&window); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == tcpip_event) { + appcall(data); + } else if(ev == ctk_signal_widget_activate) { + + if(data == &switchbutton) { + textmode(); + } else if(data == &connectbutton) { + serverport = 0; + for(cptr = port; *cptr != ' ' && *cptr != 0; ++cptr) { + if(*cptr < '0' || *cptr > '9') { + continue; + } + serverport = 10 * serverport + *cptr - '0'; + } + + ipaddr = serveraddr; + if(uiplib_ipaddrconv(host, (u8_t *)serveraddr) == 0) { + ipaddr = resolv_lookup(host); + if(ipaddr == NULL) { + resolv_query(host); + } else { + uip_ipaddr_copy(serveraddr, ipaddr); + } + } + if(ipaddr != NULL) { + conn = connect(serveraddr, serverport); + if(conn != NULL) { + memset((char *)0x0400, 0x20, 40*25); + memset((char *)0xd800, 0x01, 40*25); + textmode(); + } + } + } + } else if(ev == resolv_event_found) { + ipaddr = resolv_lookup(host); + if(ipaddr != NULL) { + uip_ipaddr_copy(serveraddr, ipaddr); + + conn = connect(serveraddr, serverport); + if(conn != NULL) { + memset((char *)0x0400, 0x20, 40*25); + memset((char *)0xd800, 0x01, 40*25); + textmode(); + } + } + } else if(ev == PROCESS_EVENT_EXIT || + ev == ctk_signal_window_close) { + + break; + } + } + ctk_window_close(&window); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/config.c b/platform/c64/apps/config.c new file mode 100644 index 000000000..187529cff --- /dev/null +++ b/platform/c64/apps/config.c @@ -0,0 +1,241 @@ +/* + * 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: config.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "program-handler.h" +#include "contiki-net.h" +#include "cfs/cfs.h" + +struct ptentry { + char c; + char * (* pfunc)(char *str); +}; + +/*-----------------------------------------------------------------------------------*/ +static char * +parse(char *str, struct ptentry *t) +{ + struct ptentry *p; + + /* Loop over the parse table entries in t in order to find one that + matches the first character in str. */ + for(p = t; p->c != 0; ++p) { + if(*str == p->c) { + /* 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. */ + return p->pfunc(str); + } + } + + /* Did not find matching entry in parse table. We just call the + default handler supplied by the caller and return. */ + return p->pfunc(str); +} +/*-----------------------------------------------------------------------------------*/ +static char * +skipnewline(char *str) +{ + /* Skip all characters until the newline. */ + while(*str != '\n') { + ++str; + } + + /* Return a pointer to the first character after the newline. */ + return str + 1; +} +/*-----------------------------------------------------------------------------------*/ +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 char * +loadfile(char *str) +{ + char *nt; + + nt = nullterminate(str); + + /* Call loader function. */ + program_handler_load(str, NULL); + + return nt + 1; +} +/*-----------------------------------------------------------------------------------*/ +static char * +screensaverconf(char *str) +{ + char *nt; + + nt = nullterminate(str); + program_handler_setscreensaver(str); + + return nt + 1; +} +/*-----------------------------------------------------------------------------------*/ +static u16_t addr[2]; +static char * +ipaddrconf(char *str) +{ + char *nt; + + nt = nullterminate(str); + if(uiplib_ipaddrconv(str, (unsigned char *)addr)) { + uip_sethostaddr(addr); + } + + return nt + 1; +} +/*-----------------------------------------------------------------------------------*/ +static char * +netmaskconf(char *str) +{ + char *nt; + + nt = nullterminate(str); + if(uiplib_ipaddrconv(str, (unsigned char *)addr)) { + uip_setnetmask(addr); + } + + return nt + 1; +} +/*-----------------------------------------------------------------------------------*/ +static char * +drconf(char *str) +{ + char *nt; + + nt = nullterminate(str); + if(uiplib_ipaddrconv(str, (unsigned char *)addr)) { + uip_setdraddr(addr); + } + + return nt + 1; +} +/*-----------------------------------------------------------------------------------*/ +static char * +dnsconf(char *str) +{ + char *nt; + + nt = nullterminate(str); + if(uiplib_ipaddrconv(str, (unsigned char *)addr)) { + resolv_conf(addr); + } + + return nt + 1; +} +/*-----------------------------------------------------------------------------------*/ +static struct ptentry configparsetab[] = + {{'n', loadfile}, + {'t', loadfile}, + {'c', loadfile}, + {'s', screensaverconf}, + {'i', ipaddrconf}, + {'m', netmaskconf}, + {'r', drconf}, + {'d', dnsconf}, + {'#', skipnewline}, + + /* Default action */ + {0, skipnewline}}; +static void +configscript(void) +{ + static char line[40], *lineptr; + /* static struct c64_fs_file f;*/ + int f; + + if((f = cfs_open("config.cfg", 0)) == -1) { + return; + } + + line[0] = ' '; + while(line[0] != '.' && + line[0] != 0) { + lineptr = line; + do { + if(cfs_read(f, lineptr, 1) != 1) { + cfs_close(f); + return; + } + ++lineptr; + } while(*(lineptr - 1) != '\n' && + *(lineptr - 1) != '\r'); + + *lineptr = 0; + + if(line[0] != '.' && + line[0] != 0) { + parse(line, configparsetab); + } + + } + cfs_close(f); + return; +} +/*-----------------------------------------------------------------------------------*/ +LOADER_INIT_FUNC(config_init, arg) +{ + arg_free(arg); + program_handler_setscreensaver(NULL); + configscript(); + LOADER_UNLOAD(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/configedit-dsc.c b/platform/c64/apps/configedit-dsc.c new file mode 100644 index 000000000..b82c52c9b --- /dev/null +++ b/platform/c64/apps/configedit-dsc.c @@ -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: configedit-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon configedit_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(configedit_dsc, + "Edit Contiki configuration", + "configedit.prg", + configedit_init, + &configedit_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] = { + 'C', 'F', 'G', + ' ', ' ', ' ', + 'C', 'F', 'G' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon configedit_icon = + {CTK_ICON("Configuration", tcpipconficon_bitmap, tcpipconficon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/configedit-dsc.h b/platform/c64/apps/configedit-dsc.h new file mode 100644 index 000000000..be9e33f10 --- /dev/null +++ b/platform/c64/apps/configedit-dsc.h @@ -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: configedit-dsc.h,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ +#ifndef __CONFIGEDIT_DSC_H__ +#define __CONFIGEDIT_DSC_H__ + +#include "sys/dsc.h" + +DSC_HEADER(configedit_dsc); + +#endif /* __CONFIGEDIT_DSC_H__ */ diff --git a/platform/c64/apps/configedit.c b/platform/c64/apps/configedit.c new file mode 100644 index 000000000..54ac8b1ec --- /dev/null +++ b/platform/c64/apps/configedit.c @@ -0,0 +1,418 @@ +/* + * 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: configedit.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "contiki.h" +#include "contiki-net.h" + +#include "ctk/ctk-draw-service.h" +#include "net/packet-service.h" + +#include "ctk/ctk.h" +#include "ctk/ctk-draw.h" + +#include "program-handler.h" + +#include "cfs/cfs.h" + +#include + +#include + +/* TCP/IP configuration window. */ +static struct ctk_window window; + +#define LABELMAXWIDTH 12 + +static struct ctk_label cfslabel = + {CTK_LABEL(0, 1, LABELMAXWIDTH, 1, "Disk driver")}; +static char cfs[25]; +static struct ctk_textentry cfstextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 1, 16, 1, cfs, 24)}; + +static struct ctk_label themelabel = + {CTK_LABEL(0, 3, LABELMAXWIDTH, 1, "CTK theme")}; +static char theme[25]; +static struct ctk_textentry themetextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 3, 16, 1, theme, 24)}; + +static struct ctk_label driverlabel = + {CTK_LABEL(0, 5, LABELMAXWIDTH, 1, "Net driver")}; +static char driver[25]; +static struct ctk_textentry drivertextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 5, 16, 1, driver, 24)}; + +static struct ctk_label screensaverlabel = + {CTK_LABEL(0, 7, LABELMAXWIDTH, 1, "Screensaver")}; +static char screensaver[25]; +static struct ctk_textentry screensavertextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 7, 16, 1, screensaver, 24)}; + + +static struct ctk_label ipaddrlabel = + {CTK_LABEL(0, 9, LABELMAXWIDTH, 1, "IP address")}; +static char ipaddr[25]; +static struct ctk_textentry ipaddrtextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 9, 16, 1, ipaddr, 24)}; +static struct ctk_label netmasklabel = + {CTK_LABEL(0, 11, LABELMAXWIDTH, 1, "Netmask")}; +static char netmask[25]; +static struct ctk_textentry netmasktextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 11, 16, 1, netmask, 24)}; +static struct ctk_label gatewaylabel = + {CTK_LABEL(0, 13, LABELMAXWIDTH, 1, "Gateway")}; +static char gateway[25]; +static struct ctk_textentry gatewaytextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 13, 16, 1, gateway, 24)}; +static struct ctk_label dnsserverlabel = + {CTK_LABEL(0, 15, LABELMAXWIDTH, 1, "DNS server")}; +static char dnsserver[25]; +static struct ctk_textentry dnsservertextentry = + {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 15, 16, 1, dnsserver, 24)}; + +static struct ctk_button savebutton = + {CTK_BUTTON(0, 17, 12, "Save & close")}; +static struct ctk_button cancelbutton = + {CTK_BUTTON(24, 17, 6, "Cancel")}; + +PROCESS(configedit_process, "Configuration editor"); +/*-----------------------------------------------------------------------------------*/ +struct ptentry { + char c; + char * (* pfunc)(char *str); +}; + +/*-----------------------------------------------------------------------------------*/ +static char * +parse(char *str, struct ptentry *t) +{ + struct ptentry *p; + + /* Loop over the parse table entries in t in order to find one that + matches the first character in str. */ + for(p = t; p->c != 0; ++p) { + if(*str == p->c) { + /* 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. */ + return p->pfunc(str); + } + } + + /* Did not find matching entry in parse table. We just call the + default handler supplied by the caller and return. */ + return p->pfunc(str); +} +/*-----------------------------------------------------------------------------------*/ +static char * +skipnewline(char *str) +{ + /* Skip all characters until the newline. */ + while(*str != '\n') { + ++str; + } + + /* Return a pointer to the first character after the newline. */ + return str + 1; +} +/*-----------------------------------------------------------------------------------*/ +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 char * __fastcall__ +copystr(char *dst, char *src, int len) +{ + char *nt = nullterminate(src); + strncpy(dst, src, len); + return nt + 1; +} +/*-----------------------------------------------------------------------------------*/ +static char * +loaddriver(char *str) +{ + return copystr(driver, str, sizeof(driver)); +} +/*-----------------------------------------------------------------------------------*/ +static char * +loadtheme(char *str) +{ + return copystr(theme, str, sizeof(theme)); +} +/*-----------------------------------------------------------------------------------*/ +static char * +loadcfs(char *str) +{ + return copystr(cfs, str, sizeof(cfs)); +} +/*-----------------------------------------------------------------------------------*/ +static char * +loadscreensaver(char *str) +{ + return copystr(screensaver, str, sizeof(screensaver)); +} +/*-----------------------------------------------------------------------------------*/ +static char * +ipaddrconf(char *str) +{ + return copystr(ipaddr, str, sizeof(ipaddr)); +} +/*-----------------------------------------------------------------------------------*/ +static char * +netmaskconf(char *str) +{ + return copystr(netmask, str, sizeof(netmask)); +} +/*-----------------------------------------------------------------------------------*/ +static char * +drconf(char *str) +{ + return copystr(gateway, str, sizeof(gateway)); +} +/*-----------------------------------------------------------------------------------*/ +static char * +dnsconf(char *str) +{ + return copystr(dnsserver, str, sizeof(dnsserver)); +} +/*-----------------------------------------------------------------------------------*/ +static struct ptentry initparsetab[] = + {{'n', loaddriver}, + {'t', loadtheme}, + {'c', loadcfs}, + {'s', loadscreensaver}, + {'i', ipaddrconf}, + {'m', netmaskconf}, + {'r', drconf}, + {'d', dnsconf}, + {'#', skipnewline}, + + /* Default action */ + {0, skipnewline}}; +static void +initscript(void) +{ + char line[40], *lineptr; + /* struct c64_fs_file f;*/ + int f; + + if((f = cfs_open("config.cfg", 0)) == -1) { + return; + } + line[0] = ' '; + while(line[0] != '.' && + line[0] != 0) { + lineptr = line; + do { + if(cfs_read(f, lineptr, 1) != 1) { + cfs_close(f); + return; + } + ++lineptr; + } while(*(lineptr - 1) != '\n' && + *(lineptr - 1) != '\r'); + + *lineptr = 0; + + if(line[0] != '.' && + line[0] != 0) { + parse(line, initparsetab); + } + + } + cfs_close(f); + return; +} +/*-----------------------------------------------------------------------------------*/ +static int +makeline(char *line, char c, char *str) +{ + int len; + + len = strlen(str); + + line[0] = c; + line[1] = ' '; + strcpy(&line[2], str); + line[2 + len] = '\n'; + line[3 + len] = 0; + return len + 3; +} +/*-----------------------------------------------------------------------------------*/ +static void +savescript(void) +{ + char line[40]; + /* struct c64_fs_file f;*/ + int f; + + f = cfs_open("@:config.cfg", CFS_WRITE); + if(f == -1) { + log_message("Could not open config.cfg", ""); + return; + } + if(cfs[0] != 0) { + cfs_write(f, line, makeline(line, 'c', cfs)); + } + if(theme[0] != 0) { + cfs_write(f, line, makeline(line, 't', theme)); + } + if(driver[0] != 0) { + cfs_write(f, line, makeline(line, 'n', driver)); + } + if(ipaddr[0] != 0) { + cfs_write(f, line, makeline(line, 'i', ipaddr)); + } + if(netmask[0] != 0) { + cfs_write(f, line, makeline(line, 'm', netmask)); + } + if(gateway[0] != 0) { + cfs_write(f, line, makeline(line, 'r', gateway)); + } + if(dnsserver[0] != 0) { + cfs_write(f, line, makeline(line, 'd', dnsserver)); + } + + if(screensaver[0] != 0) { + cfs_write(f, line, makeline(line, 's', screensaver)); + } + + strcpy(line, ".\n\0\n\n\n"); + cfs_write(f, line, strlen(line)); + + cfs_close(f); + +} +/*-----------------------------------------------------------------------------------*/ +static void +quit_services(void) +{ + /* cfs_init_init(NULL); + ctk_draw_quit(); + + if(ek_service_find(&packetservice) == EK_ERR_OK) { + ek_post(packetservice.id, EK_EVENT_REQUEST_EXIT, NULL); + ek_service_reset(&packetservice); + }*/ +} +/*-----------------------------------------------------------------------------------*/ +PROCESS_THREAD(configedit_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Create window. */ + ctk_window_new(&window, 32, 18, "Config editor"); + + CTK_WIDGET_ADD(&window, &cfslabel); + CTK_WIDGET_ADD(&window, &cfstextentry); + + CTK_WIDGET_ADD(&window, &themelabel); + CTK_WIDGET_ADD(&window, &themetextentry); + + CTK_WIDGET_ADD(&window, &driverlabel); + CTK_WIDGET_ADD(&window, &drivertextentry); + + CTK_WIDGET_ADD(&window, &screensaverlabel); + CTK_WIDGET_ADD(&window, &screensavertextentry); + + CTK_WIDGET_ADD(&window, &ipaddrlabel); + CTK_WIDGET_ADD(&window, &ipaddrtextentry); + CTK_WIDGET_ADD(&window, &netmasklabel); + CTK_WIDGET_ADD(&window, &netmasktextentry); + CTK_WIDGET_ADD(&window, &gatewaylabel); + CTK_WIDGET_ADD(&window, &gatewaytextentry); + CTK_WIDGET_ADD(&window, &dnsserverlabel); + CTK_WIDGET_ADD(&window, &dnsservertextentry); + + CTK_WIDGET_ADD(&window, &savebutton); + CTK_WIDGET_ADD(&window, &cancelbutton); + + CTK_WIDGET_FOCUS(&window, &cfstextentry); + + /* Fill the configuration strings with values from the current + configuration */ + initscript(); + + ctk_window_open(&window); + + while(1) { + PROCESS_WAIT_EVENT(); + + if(ev == ctk_signal_button_activate) { + if(data == &savebutton) { + savescript(); + quit_services(); + ctk_window_close(&window); + program_handler_load("config.prg", NULL); + break; + } else if(data == &cancelbutton) { + ctk_window_close(&window); + break; + } + } else if(ev == ctk_signal_window_close || + ev == PROCESS_EVENT_EXIT) { + ctk_window_close(&window); + break; + } + } + + PROCESS_END(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/default-dsc.c b/platform/c64/apps/default-dsc.c new file mode 100644 index 000000000..585fb04f0 --- /dev/null +++ b/platform/c64/apps/default-dsc.c @@ -0,0 +1,72 @@ +/* + * 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: default-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon default_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(default_dsc, + "Default CTK theme", + "default.prg", + default_init, + &default_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char defaulticon_bitmap[3*3*8] = { + 0xff,0xff,0xc0,0xcf,0xc0,0xc3,0xc0,0xc0, + 0xff,0xff,0x00,0xff,0x00,0xff,0x00,0x00, + 0xff,0xfc,0x00,0xf0,0x00,0xc0,0x00,0x00, + 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b, + 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x80,0x00, + 0x00,0x00,0x00,0x00,0xff,0x00,0xff,0xff, + 0x0b,0x0b,0x0b,0x0b,0xfb,0x03,0xff,0xff +}; +#endif /* CTK_CONF_ICON_BITMAPS */ + +#if CTK_CONF_ICON_TEXTMAPS +static char defaulticon_textmap[9] = { + '+', '=', '+', + '|', 'D', '|', + '+', '-', '+' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon default_icon = + {CTK_ICON("Default", defaulticon_bitmap, defaulticon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/enabler-dsc.c b/platform/c64/apps/enabler-dsc.c new file mode 100644 index 000000000..1da789ab4 --- /dev/null +++ b/platform/c64/apps/enabler-dsc.c @@ -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: enabler-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon enabler_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(enabler_dsc, + "Colorless grayish CTK theme", + "enabler.prg", + enabler_init, + &enabler_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char enablericon_bitmap[3*3*8] = { + 0xff,0xff,0xff,0xfc,0xf0,0xf0,0xe0,0xe0, + 0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00, + 0xff,0xff,0xff,0x3f,0x0f,0x0f,0x07,0x07, + + 0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07, + + 0xe0,0xe0,0xf0,0xf0,0xfc,0xff,0xff,0xff, + 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff, + 0x07,0x07,0x0f,0x0f,0x3f,0xff,0xff,0xff +}; +#endif /* CTK_CONF_ICON_BITMAPS */ + +#if CTK_CONF_ICON_TEXTMAPS +static char enablericon_textmap[9] = { + '(', '=', ')', + '|', 'o', '|', + '(', '-', ')' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon enabler_icon = + {CTK_ICON("Enabler", enablericon_bitmap, enablericon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/http-user-agent-string.c b/platform/c64/apps/http-user-agent-string.c new file mode 100644 index 000000000..dd59a0aba --- /dev/null +++ b/platform/c64/apps/http-user-agent-string.c @@ -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 + * + * $Id: http-user-agent-string.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + */ +char http_user_agent_fields[100] = +/* "Connection: close\r\nUser-Agent: Contiki/1.1-rc0 (Commodore 64; 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, 0x2d, 0x72, 0x63, 0x30, 0x20, 0x28, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x64, 0x6f, 0x72, 0x65, 0x20, 0x36, 0x34, 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, }; diff --git a/platform/c64/apps/http-user-agent-string.h b/platform/c64/apps/http-user-agent-string.h new file mode 100644 index 000000000..6767640c3 --- /dev/null +++ b/platform/c64/apps/http-user-agent-string.h @@ -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 + * + * $Id: http-user-agent-string.h,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + */ +extern char http_user_agent_fields[100]; diff --git a/platform/c64/apps/memstat-dsc.c b/platform/c64/apps/memstat-dsc.c new file mode 100644 index 000000000..88831b28d --- /dev/null +++ b/platform/c64/apps/memstat-dsc.c @@ -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: memstat-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon memstat_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(memstat_dsc, + "Memory statistics", + "memstat.prg", + memstat_init, + &memstat_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char memstaticon_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 memstaticon_textmap[9] = { + '0', '0', '1', + '0', '1', '0', + '1', '0', '1' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon memstat_icon = + {CTK_ICON("Memory stats", memstaticon_bitmap, memstaticon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/mtest.c b/platform/c64/apps/mtest.c new file mode 100644 index 000000000..d492c1094 --- /dev/null +++ b/platform/c64/apps/mtest.c @@ -0,0 +1,54 @@ +/* + * 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 + * + * $Id: mtest.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + */ +#include "mt.h" + +MTP(t, p, "Test thread"); +/*--------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +test(void *data) +{ + while(1) { + asm("inc $d020"); + } +} +#pragma optimize(pop) +/*--------------------------------------------------------------------------*/ +LOADER_INIT_FUNC(mtest_init, arg) +{ + arg_free(arg); + mtp_start(&t, test, NULL); +} +/*--------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/plasma-dsc.c b/platform/c64/apps/plasma-dsc.c new file mode 100644 index 000000000..223f0c916 --- /dev/null +++ b/platform/c64/apps/plasma-dsc.c @@ -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: plasma-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon plasma_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(plasma_dsc, + "Screensaver with a plasma", + "plasma.sav", + plasma_init, + &plasma_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char plasmaicon_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 plasmaicon_textmap[9] = { + '.', ' ', '.', + ' ', 'O', ' ', + '.', ' ', '.' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon plasma_icon = + {CTK_ICON("Plasma", plasmaicon_bitmap, plasmaicon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/plasma.c b/platform/c64/apps/plasma.c new file mode 100644 index 000000000..c8f84e0f5 --- /dev/null +++ b/platform/c64/apps/plasma.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2002-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: plasma.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include + +#include "ctk/ctk.h" +#include "ctk/ctk-draw.h" +#include "ctk/ctk-mouse.h" +#include "contiki.h" + +static unsigned char sinetab1[256] = { + 128, 131, 134, 137, 140, 143, 146, 149, + 152, 156, 159, 162, 165, 168, 171, 174, + 176, 179, 182, 185, 188, 191, 193, 196, + 199, 201, 204, 206, 209, 211, 213, 216, + 218, 220, 222, 224, 226, 228, 230, 232, + 234, 236, 237, 239, 240, 242, 243, 245, + 246, 247, 248, 249, 250, 251, 252, 252, + 253, 254, 254, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 254, 254, + 253, 252, 252, 251, 250, 249, 248, 247, + 246, 245, 243, 242, 240, 239, 237, 236, + 234, 232, 230, 228, 226, 224, 222, 220, + 218, 216, 213, 211, 209, 206, 204, 201, + 199, 196, 193, 191, 188, 185, 182, 179, + 176, 174, 171, 168, 165, 162, 159, 156, + 152, 149, 146, 143, 140, 137, 134, 131, + 128, 124, 121, 118, 115, 112, 109, 106, + 103, 99, 96, 93, 90, 87, 84, 81, + 79, 76, 73, 70, 67, 64, 62, 59, + 56, 54, 51, 49, 46, 44, 42, 39, + 37, 35, 33, 31, 29, 27, 25, 23, + 21, 19, 18, 16, 15, 13, 12, 10, + 9, 8, 7, 6, 5, 4, 3, 3, + 2, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, + 2, 3, 3, 4, 5, 6, 7, 8, + 9, 10, 12, 13, 15, 16, 18, 19, + 21, 23, 25, 27, 29, 31, 33, 35, + 37, 39, 42, 44, 46, 49, 51, 54, + 56, 59, 62, 64, 67, 70, 73, 76, + 78, 81, 84, 87, 90, 93, 96, 99, + 103, 106, 109, 112, 115, 118, 121, 124, +}; + +static unsigned char sinetab2[256]; +static unsigned char sinetab3[256]; + +static unsigned char colortab[256]; + +static unsigned char colors[16] = + { + 0x00, 0x06, 0x0b, 0x04, + 0x0a, 0x0f, 0x07, 0x01, + 0x07, 0x0f, 0x0a, 0x08, + 0x02, 0x09, 0x00, 0x00, + }; + +#define XSIZE 25 +#define YSIZE 25 + +#define XADD01 0xfe +#define YADD01 0x05 + +#define XADD1 0x04 +#define YADD1 0x02 +#define XADD2 0xfc +#define YADD2 0xf9 + +#define XADD 0x03 +#define YADD 0xfe + +#define MOVADD 0xfb + +static unsigned char xplasma[XSIZE], yplasma[YSIZE]; +static unsigned char xcnt, ycnt; +static unsigned char xcnt01, xcnt02, xcnt1, xcnt2; +static unsigned char ycnt01, ycnt02, ycnt1, ycnt2; + +static unsigned char xadd02 = 0x01; +static unsigned char yadd02 = 0xfb; + +static unsigned char movcnt; + +PROCESS(plasma_process, "Plasma screensaver"); +/*---------------------------------------------------------------------------*/ +static void +scrninit(void) +{ + unsigned char *ptr, *cptr; + static int i; + + /* Make sine tables */ + for(i = 0; i < 256; ++i) { + sinetab2[(unsigned char)i] = sinetab1[(unsigned char)i] / 2; + sinetab3[(unsigned char)i] = sinetab1[(unsigned char)i] / 4; + } + + /* Make color table */ + for(i = 0; i < 256; ++i) { + colortab[(unsigned char)i] = colors[(unsigned char)i / 16]; + } + + + /* Fill screen with inverted spaces. */ + cptr = COLOR_RAM; + for(ptr = (unsigned char *)0x0400; + ptr != (unsigned char *)0x07e8; + ++ptr) { + *ptr = 0xa0; + *cptr++ = 0x00; + } + + VIC.ctrl1 = 0x1b; /* $D011 */ + VIC.addr = 0x17; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + VIC.bordercolor = 0x00; /* $D020 */ + VIC.bgcolor0 = 0x00; /* $D021 */ + CIA2.pra = 0x03; /* $DD00 */ + +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ + static unsigned char i, x, y; + register unsigned char *cptr; + + if(ctk_mode_get() == CTK_MODE_SCREENSAVER) { + + + xcnt1 = xcnt01; + xcnt2 = xcnt02; + + for(i = 0; i < XSIZE; ++i) { + xplasma[i] = sinetab1[xcnt1] + sinetab2[xcnt2]; + xcnt1 += XADD1; + xcnt2 += XADD2; + } + + ycnt1 = ycnt01; + ycnt2 = ycnt02; + + for(i = 0; i < YSIZE; ++i) { + yplasma[i] = sinetab1[ycnt1] + sinetab3[ycnt2]; + ycnt1 += YADD1; + ycnt2 += YADD2; + } + + xcnt01 += XADD01; + xcnt02 += xadd02; + ycnt01 += YADD01; + ycnt02 += yadd02; + + + yadd02 = sinetab3[ycnt] / 4; + xadd02 = sinetab3[xcnt] / 4; + + ycnt += YADD; + xcnt += XADD; + + movcnt += MOVADD; + cptr = (unsigned char *)(COLOR_RAM + sinetab1[movcnt]/16); + for(y = 0; y < YSIZE; ++y) { + for(x = 0; x < XSIZE; ++x) { + *cptr = colortab[(xplasma[x] + yplasma[y]) & 0xff]; + ++cptr; + } + cptr += 40 - XSIZE; + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(plasma_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + ctk_mode_set(CTK_MODE_SCREENSAVER); + ctk_mouse_hide(); + + scrninit(); + + PROCESS_WAIT_EVENT_UNTIL(ev == ctk_signal_screensaver_stop || + ev == PROCESS_EVENT_EXIT); + ctk_draw_init(); + ctk_desktop_redraw(NULL); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/ravenpine-dsc.c b/platform/c64/apps/ravenpine-dsc.c new file mode 100644 index 000000000..aa2c0b4e6 --- /dev/null +++ b/platform/c64/apps/ravenpine-dsc.c @@ -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: ravenpine-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon ravenpine_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(ravenpine_dsc, + "Terminal green CTK theme", + "ravenpine.prg", + ravenpine_init, + &ravenpine_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char ravenpineicon_bitmap[3*3*8] = { + 0x00,0x3f,0x6a,0x40,0x60,0x40,0x60,0x40, + 0x00,0xff,0xaa,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf0,0x20,0x00,0x00,0x00,0x00,0x00, + + 0x60,0x40,0x60,0x40,0x60,0x40,0x60,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + + 0x60,0x40,0x40,0x40,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x02,0x02,0x02,0x02,0x02,0x06,0xfc,0x00 +}; +#endif /* CTK_CONF_ICON_BITMAPS */ + +#if CTK_CONF_ICON_TEXTMAPS +static char ravenpineicon_textmap[9] = { + '(', '=', ')', + '|', 'o', '|', + '(', '-', ')' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon ravenpine_icon = + {CTK_ICON("Ravenpine", ravenpineicon_bitmap, ravenpineicon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/springlight-dsc.c b/platform/c64/apps/springlight-dsc.c new file mode 100644 index 000000000..380f95bf8 --- /dev/null +++ b/platform/c64/apps/springlight-dsc.c @@ -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: springlight-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon springlight_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(springlight_dsc, + "Spring green CTK theme", + "springlight.prg", + springlight_init, + &springlight_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char springlighticon_bitmap[3*3*8] = { + 0x00,0x3f,0x6a,0x40,0x60,0x40,0x60,0x40, + 0x00,0xff,0xaa,0x00,0x00,0x00,0x00,0x00, + 0x00,0xf0,0x20,0x00,0x00,0x00,0x00,0x00, + + 0x60,0x40,0x60,0x40,0x60,0x40,0x60,0x40, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + + 0x60,0x40,0x40,0x40,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00, + 0x02,0x02,0x02,0x02,0x02,0x06,0xfc,0x00 +}; +#endif /* CTK_CONF_ICON_BITMAPS */ + +#if CTK_CONF_ICON_TEXTMAPS +static char springlighticon_textmap[9] = { + '(', '=', ')', + '|', 'o', '|', + '(', '-', ')' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon springlight_icon = + {CTK_ICON("Springlight", springlighticon_bitmap, springlighticon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/ssfire-dsc.c b/platform/c64/apps/ssfire-dsc.c new file mode 100644 index 000000000..46c9f1c25 --- /dev/null +++ b/platform/c64/apps/ssfire-dsc.c @@ -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: ssfire-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon ssfire_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(ssfire_dsc, + "Screensaver with two fires", + "ssfire.sav", + ssfire_init, + &ssfire_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char ssfireicon_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 ssfireicon_textmap[9] = { + '.', ' ', '.', + 'o', ' ', 'o', + 'O', ' ', 'O' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon ssfire_icon = + {CTK_ICON("Fire", ssfireicon_bitmap, ssfireicon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/ssfire.c b/platform/c64/apps/ssfire.c new file mode 100644 index 000000000..01e3a67b3 --- /dev/null +++ b/platform/c64/apps/ssfire.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2002-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: ssfire.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include + +#include "ctk/ctk.h" +#include "ctk/ctk-draw.h" +#include "ctk/ctk-mouse.h" +#include "contiki.h" +#include "sys/loader.h" + +PROCESS(ssfire_process, "Fire screensaver"); + +static unsigned char flames[8*17]; + + +static const unsigned char flamecolors[16] = + {COLOR_BLACK, COLOR_BLACK, COLOR_BLACK, COLOR_RED, + COLOR_LIGHTRED, COLOR_YELLOW, COLOR_WHITE, COLOR_WHITE, + COLOR_WHITE, COLOR_WHITE, COLOR_WHITE, COLOR_WHITE, + COLOR_WHITE, COLOR_WHITE, COLOR_WHITE, COLOR_WHITE}; + + +/*---------------------------------------------------------------------------*/ +static void +fire_init(void) +{ + unsigned char *ptr, *cptr; + + /* Fill screen with inverted spaces. */ + cptr = COLOR_RAM; + for(ptr = (unsigned char *)0x0400; + ptr != (unsigned char *)0x07e8; + ++ptr) { + *ptr = 0xa0; + *cptr++ = 0x00; + } + + SID.v3.freq = 0xffff; + SID.v3.ctrl = 0x80; + SID.amp = 0; + + VIC.ctrl1 = 0x1b; /* $D011 */ + VIC.addr = 0x17; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + VIC.bordercolor = 0x00; /* $D020 */ + VIC.bgcolor0 = 0x00; /* $D021 */ + CIA2.pra = 0x03; /* $DD00 */ +} +/*---------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +fire_burn(void) +{ + /* Calculate new flames. */ + asm("ldy #$00"); +loop1: + asm("lda %v+7,y", flames); + asm("clc"); + asm("adc %v+8,y", flames); + asm("adc %v+9,y", flames); + asm("adc %v+16,y", flames); + asm("lsr"); + asm("lsr"); + asm("sta %v,y", flames); + asm("iny"); + asm("cpy #(8*15)"); + asm("bne %g", loop1); + + /* Fill last line with pseudo-random data from noise generator on + voice 3. */ + asm("ldy #$05"); +loop2: + asm("ldx #$20"); +delay: + asm("dex"); + asm("bne %g", delay); + asm("lda $D41B"); + asm("and #$0F"); + asm("sta %v+8*15+1,y", flames); + asm("dey"); + asm("bpl %g", loop2); +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +static unsigned char *flameptr, *colorptr1, *colorptr2; +static unsigned char x, y; + +static void +pollhandler(void) +{ + + if(ctk_mode_get() == CTK_MODE_SCREENSAVER) { + + fire_burn(); + + /* Display flames on screen. */ + flameptr = flames; + colorptr1 = COLOR_RAM + 40*10; + colorptr2 = colorptr1 + 0x20; + for(y = 0; y < 15; ++y) { + for(x = 0; x < 8; ++x) { + colorptr1[x] = colorptr2[x] = flamecolors[flameptr[x]]; + } + colorptr1 += 0x28; + colorptr2 += 0x28; + flameptr += 8; + } + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ssfire_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + ctk_mode_set(CTK_MODE_SCREENSAVER); + ctk_mouse_hide(); + fire_init(); + + + PROCESS_WAIT_EVENT_UNTIL(ev == ctk_signal_screensaver_stop || + ev == PROCESS_EVENT_EXIT); + + ctk_draw_init(); + ctk_desktop_redraw(NULL); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/themeloader.c b/platform/c64/apps/themeloader.c new file mode 100644 index 000000000..16a92482a --- /dev/null +++ b/platform/c64/apps/themeloader.c @@ -0,0 +1,52 @@ +/* + * 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: themeloader.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include + +#include "loader.h" +#include "ctk-draw.h" +#include "ctk-hires-theme.h" + +/*-----------------------------------------------------------------------------------*/ +LOADER_INIT_FUNC(themeloader_init, arg) +{ + arg_free(arg); + + memcpy(ctk_hires_theme_ptr, &ctk_hires_theme, + sizeof(struct ctk_hires_theme)); + ctk_draw_init(); + LOADER_UNLOAD(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/vnc-draw-asm.h b/platform/c64/apps/vnc-draw-asm.h new file mode 100644 index 000000000..1a324ccd8 --- /dev/null +++ b/platform/c64/apps/vnc-draw-asm.h @@ -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 VNC client + * + * $Id: vnc-draw-asm.h,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ +#ifndef __VNC_DRAW_ASM_H__ +#define __VNC_DRAW_ASM_H__ + +#include "vnc-draw.h" + +void vnc_draw_asm_pixelline(void); + +#endif /* __VNC_DRAW_ASM_H__ */ diff --git a/platform/c64/apps/vnc-draw.c b/platform/c64/apps/vnc-draw.c new file mode 100644 index 000000000..9ebd6aea8 --- /dev/null +++ b/platform/c64/apps/vnc-draw.c @@ -0,0 +1,689 @@ +/* + * 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 VNC client + * + * $Id: vnc-draw.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + + + +#include "vnc-draw.h" +#include "vnc-draw-asm.h" + +#include "vnc-conf.h" + + +static unsigned char conv[256]; + +static unsigned char oratab[8] = + { 0x80, 0x40, 0x20, 0x10, + 0x08, 0x04, 0x02, 0x01 }; +static unsigned char andtab[8] = + { 0x7f, 0xbf, 0xdf, 0xef, + 0xf7, 0xfb, 0xfd, 0xfe }; + +static u8_t *bitmapptrtab[VNC_CONF_VIEWPORT_HEIGHT]; + +static unsigned short viewport_x, + viewport_y, viewport_w, viewport_h; + +u8_t vnc_draw_bitmap[(VNC_CONF_VIEWPORT_WIDTH / 8) * + VNC_CONF_VIEWPORT_HEIGHT]; + + + +u16_t vnc_draw_x; +u16_t vnc_draw_y; +u8_t *vnc_draw_dataptr; +u8_t *vnc_draw_bitmapptr; +u16_t vnc_draw_datalen; + +/*-----------------------------------------------------------------------------------*/ +void +vnc_draw_pixel(u16_t x, u8_t y, u8_t c) +{ + u8_t o, a; + + vnc_draw_bitmapptr = bitmapptrtab[y] + (x & 0x1f8); + + if(c) { + o = oratab[x & 7]; + *vnc_draw_bitmapptr = *vnc_draw_bitmapptr | o; + } else { + a = andtab[x & 7]; + *vnc_draw_bitmapptr = *vnc_draw_bitmapptr & a; + } +} +/*-----------------------------------------------------------------------------------*/ +void +vnc_draw_pixelline(u16_t x, u16_t y, u8_t *data, u16_t datalen) +{ + u8_t o, a; + register u8_t *bitmapptr; + + vnc_draw_x = x - viewport_x; + vnc_draw_y = y - viewport_y; + + /* if(vnc_draw_y & 1) { + return; + } else { + vnc_draw_y /= 2; + }*/ + + + + if(vnc_draw_y >= VNC_CONF_VIEWPORT_HEIGHT || + vnc_draw_x >= VNC_CONF_VIEWPORT_WIDTH) { + return; + } + + vnc_draw_datalen = datalen; + + if(vnc_draw_datalen + vnc_draw_x >= VNC_CONF_VIEWPORT_WIDTH) { + vnc_draw_datalen = VNC_CONF_VIEWPORT_WIDTH - vnc_draw_x; + if(vnc_draw_datalen == 0) { + return; + } + } + + vnc_draw_dataptr = data; + + /* vnc_draw_bitmapptr = bitmaptab[vnc_draw_y] + + (vnc_draw_x & 0x1f8);*/ + + for(; vnc_draw_datalen > 0; --vnc_draw_datalen) { + /* vnc_draw_pixel(vnc_draw_x, vnc_draw_y, + conv[*vnc_draw_dataptr]);*/ + + bitmapptr = bitmapptrtab[vnc_draw_y] + (vnc_draw_x & 0x1f8); + + if(conv[*vnc_draw_dataptr]) { + o = oratab[vnc_draw_x & 7]; + *bitmapptr = *bitmapptr | o; + } else { + a = andtab[vnc_draw_x & 7]; + *bitmapptr = *bitmapptr & a; + } + ++vnc_draw_dataptr; + ++vnc_draw_x; + } +} +/*-----------------------------------------------------------------------------------*/ +void +vnc_draw_init(void) +{ + unsigned int tmp; + unsigned int i; + unsigned short ptr; + + + /* Create color conversion table. */ + for(i = 0; i < 256; ++i) { + if(((i & 0xc0) > 0xc0) || + ((i & 0x38) > 0x18) || + ((i & 0x07) > 0x03)) { + conv[i] = 0; + } else { + conv[i] = 1; + } + } + + memset(vnc_draw_bitmap, 0, sizeof(vnc_draw_bitmap)); + + for(i = 0; i < VNC_CONF_VIEWPORT_HEIGHT; ++i) { + bitmapptrtab[i] = (u8_t *)((u16_t)vnc_draw_bitmap + + ((i & 0xfff8)/8) * VNC_CONF_VIEWPORT_WIDTH + + (i & 7)); + } + + viewport_x = 0; + viewport_y = 0; + + viewport_w = VNC_CONF_VIEWPORT_WIDTH; + viewport_h = VNC_CONF_VIEWPORT_HEIGHT; + + return; +} +/*-----------------------------------------------------------------------------------*/ +u16_t +vnc_draw_viewport_x(void) +{ + return viewport_x; +} +/*-----------------------------------------------------------------------------------*/ +u16_t +vnc_draw_viewport_y(void) +{ + return viewport_y; +} +/*-----------------------------------------------------------------------------------*/ +u16_t +vnc_draw_viewport_w(void) +{ + return viewport_w; +} +/*-----------------------------------------------------------------------------------*/ +u16_t +vnc_draw_viewport_h(void) +{ + return viewport_h; +} +/*-----------------------------------------------------------------------------------*/ +#if 0 +signed short +c64_mouse_x(void) +{ + return 0; +} +/*-----------------------------------------------------------------------------------*/ +signed short +c64_mouse_y(void) +{ + return 0; +} +/*-----------------------------------------------------------------------------------*/ +u8_t +c64_mouse_buttons(void) +{ + return firebutton; +} +/*-----------------------------------------------------------------------------------*/ +void +c64_set_mouse_x(unsigned short x) +{ + joyx = x; +} +/*-----------------------------------------------------------------------------------*/ +void +c64_set_mouse_y(unsigned short y) +{ + joyy = y; +} +/*-----------------------------------------------------------------------------------*/ +void +c64_set_viewport_x(unsigned short x) +{ + viewport_x = x; +} +/*-----------------------------------------------------------------------------------*/ +void +c64_set_viewport_y(unsigned short y) +{ + viewport_y = y; +} +/*-----------------------------------------------------------------------------------*/ + +#endif /* 0 */ +#if 0 +#pragma optimize(push, off) +void +c64_scroll_up(unsigned char c) +{ + asm("lda $f7"); + asm("pha"); + asm("lda $f8"); + asm("pha"); + asm("lda $f9"); + asm("pha"); + asm("lda $fa"); + asm("pha"); + asm("lda $fb"); + asm("pha"); + asm("lda $fc"); + asm("pha"); + asm("lda $fd"); + asm("pha"); + asm("lda $fe"); + asm("pha"); + + asm("lda $01"); + asm("pha"); + asm("lda #$35"); + asm("sta $01"); + + asm("lda #$80"); + asm("sta $f7"); + asm("lda #$a2"); + asm("sta $f8"); + asm("lda #$00"); + asm("sta $f9"); + asm("lda #$a0"); + asm("sta $fa"); + + asm("lda #$80"); + asm("sta $fb"); + asm("lda #$e2"); + asm("sta $fc"); + asm("lda #$00"); + asm("sta $fd"); + asm("lda #$e0"); + asm("sta $fe"); + + asm("ldy #0"); + asm("loop:"); + asm("lda ($f7),y"); + asm("sta ($f9),y"); + asm("lda ($fb),y"); + asm("sta ($fd),y"); + asm("iny"); + asm("bne loop"); + + asm("inc $f8"); + asm("inc $fa"); + asm("inc $fc"); + asm("inc $fe"); + + asm("lda $fc"); + asm("cmp #$00"); + asm("bne loop"); + + asm("ldy #0"); + asm("lda #0"); + asm("sta $fe00,y"); + asm("sta $be00,y"); + asm("sta $fcc0,y"); + asm("sta $bcc0,y"); + asm("iny"); + asm("bne *-13"); + asm("sta $ff00,y"); + asm("sta $bf00,y"); + asm("sta $fdc0,y"); + asm("sta $bdc0,y"); + asm("iny"); + asm("cpy #$40"); + asm("bne *-15"); + + + asm("pla"); + asm("sta $01"); + asm("pla"); + asm("sta $fe"); + asm("pla"); + asm("sta $fd"); + asm("pla"); + asm("sta $fc"); + asm("pla"); + asm("sta $fb"); + asm("pla"); + asm("sta $fa"); + asm("pla"); + asm("sta $f9"); + asm("pla"); + asm("sta $f8"); + asm("pla"); + asm("sta $f7"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +c64_scroll_down(unsigned char c) +{ + asm("lda $f7"); + asm("pha"); + asm("lda $f8"); + asm("pha"); + asm("lda $f9"); + asm("pha"); + asm("lda $fa"); + asm("pha"); + asm("lda $fb"); + asm("pha"); + asm("lda $fc"); + asm("pha"); + asm("lda $fd"); + asm("pha"); + asm("lda $fe"); + asm("pha"); + + + asm("lda $01"); + asm("pha"); + asm("lda #$35"); + asm("sta $01"); + + asm("lda #$c0"); + asm("sta $fb"); + asm("lda #$fb"); + asm("sta $fc"); + asm("lda #$40"); + asm("sta $fd"); + asm("lda #$fe"); + asm("sta $fe"); + + asm("lda #$c0"); + asm("sta $f7"); + asm("lda #$bb"); + asm("sta $f8"); + asm("lda #$40"); + asm("sta $f9"); + asm("lda #$be"); + asm("sta $fa"); + + + asm("ldy #0"); + asm("loop:"); + asm("lda ($fb),y"); + asm("sta ($fd),y"); + asm("lda ($f7),y"); + asm("sta ($f9),y"); + asm("iny"); + asm("bne loop"); + + asm("dec $f8"); + asm("dec $fa"); + asm("dec $fc"); + asm("dec $fe"); + + + asm("lda $fe"); + asm("cmp #$df"); + asm("bne loop"); + + asm("ldy #0"); + asm("lda #0"); + asm("sta $e000,y"); + asm("sta $a000,y"); + asm("sta $e140,y"); + asm("sta $a140,y"); + asm("iny"); + asm("bne *-13"); + asm("sta $e100,y"); + asm("sta $a100,y"); + asm("sta $e240,y"); + asm("sta $a240,y"); + asm("iny"); + asm("cpy #$40"); + asm("bne *-15"); + + asm("pla"); + asm("sta $01"); + asm("pla"); + asm("sta $fe"); + asm("pla"); + asm("sta $fd"); + asm("pla"); + asm("sta $fc"); + asm("pla"); + asm("sta $fb"); + asm("pla"); + asm("sta $fa"); + asm("pla"); + asm("sta $f9"); + asm("pla"); + asm("sta $f8"); + asm("pla"); + asm("sta $f7"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +c64_scroll_right(unsigned char c) +{ + asm("lda $f7"); + asm("pha"); + asm("lda $f8"); + asm("pha"); + asm("lda $f9"); + asm("pha"); + asm("lda $fa"); + asm("pha"); + asm("lda $fb"); + asm("pha"); + asm("lda $fc"); + asm("pha"); + asm("lda $fd"); + asm("pha"); + asm("lda $fe"); + asm("pha"); + + + asm("lda $01"); + asm("pha"); + asm("lda #$35"); + asm("sta $01"); + + asm("lda #$00"); + asm("sta $f7"); + asm("lda #$a0"); + asm("sta $f8"); + asm("lda #$10"); + asm("sta $f9"); + asm("lda #$a0"); + asm("sta $fa"); + + asm("lda #$00"); + asm("sta $fb"); + asm("lda #$e0"); + asm("sta $fc"); + asm("lda #$10"); + asm("sta $fd"); + asm("lda #$e0"); + asm("sta $fe"); + + asm("ldx #0"); + + asm("loop3:"); + + asm("ldy #$ff"); + asm("loop:"); + asm("lda ($f7),y"); + asm("sta ($f9),y"); + asm("lda ($fb),y"); + asm("sta ($fd),y"); + asm("dey"); + asm("cpy #$ff"); + asm("bne loop"); + + asm("inc $f8"); + asm("inc $fa"); + asm("inc $fc"); + asm("inc $fe"); + + asm("ldy #$30"); + asm("loop2:"); + asm("lda ($f7),y"); + asm("sta ($f9),y"); + asm("lda ($fb),y"); + asm("sta ($fd),y"); + asm("dey"); + asm("cpy #$ff"); + asm("bne loop2"); + + asm("lda $f7"); + asm("clc"); + asm("adc #$40"); + asm("sta $f7"); + asm("sta $fb"); + asm("bcc :+"); + asm("inc $f8"); + asm("inc $fc"); + asm(":"); + + asm("lda $f9"); + asm("clc"); + asm("adc #$40"); + asm("sta $f9"); + asm("sta $fd"); + asm("bcc :+"); + asm("inc $fa"); + asm("inc $fe"); + asm(":"); + + + + asm("inx"); + asm("cpx #24"); + asm("bne loop3"); + + asm("pla"); + asm("sta $01"); + asm("pla"); + asm("sta $fe"); + asm("pla"); + asm("sta $fd"); + asm("pla"); + asm("sta $fc"); + asm("pla"); + asm("sta $fb"); + asm("pla"); + asm("sta $fa"); + asm("pla"); + asm("sta $f9"); + asm("pla"); + asm("sta $f8"); + asm("pla"); + asm("sta $f7"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +c64_scroll_left(unsigned char c) +{ + asm("lda $f7"); + asm("pha"); + asm("lda $f8"); + asm("pha"); + asm("lda $f9"); + asm("pha"); + asm("lda $fa"); + asm("pha"); + asm("lda $fb"); + asm("pha"); + asm("lda $fc"); + asm("pha"); + asm("lda $fd"); + asm("pha"); + asm("lda $fe"); + asm("pha"); + + + asm("lda $01"); + asm("pha"); + asm("lda #$35"); + asm("sta $01"); + + asm("lda #$10"); + asm("sta $f7"); + asm("lda #$a0"); + asm("sta $f8"); + asm("lda #$00"); + asm("sta $f9"); + asm("lda #$a0"); + asm("sta $fa"); + + asm("lda #$10"); + asm("sta $fb"); + asm("lda #$e0"); + asm("sta $fc"); + asm("lda #$00"); + asm("sta $fd"); + asm("lda #$e0"); + asm("sta $fe"); + + asm("ldx #0"); + asm("loop3:"); + asm("ldy #0"); + asm("loop:"); + asm("lda ($f7),y"); + asm("sta ($f9),y"); + asm("lda ($fb),y"); + asm("sta ($fd),y"); + asm("iny"); + asm("bne loop"); + + asm("inc $f8"); + asm("inc $fa"); + asm("inc $fc"); + asm("inc $fe"); + + asm("ldy #0"); + asm("loop2:"); + asm("lda ($f7),y"); + asm("sta ($f9),y"); + asm("lda ($fb),y"); + asm("sta ($fd),y"); + asm("iny"); + asm("cpy #$30"); + asm("bne loop2"); + + asm("lda $f7"); + asm("clc"); + asm("adc #$40"); + asm("sta $f7"); + asm("sta $fb"); + asm("bcc :+"); + asm("inc $f8"); + asm("inc $fc"); + asm(":"); + + asm("lda $f9"); + asm("clc"); + asm("adc #$40"); + asm("sta $f9"); + asm("sta $fd"); + asm("bcc :+"); + asm("inc $fa"); + asm("inc $fe"); + asm(":"); + + + asm("inx"); + asm("cpx #24"); + asm("bne loop3"); + + asm("pla"); + asm("sta $01"); + asm("pla"); + asm("sta $fe"); + asm("pla"); + asm("sta $fd"); + asm("pla"); + asm("sta $fc"); + asm("pla"); + asm("sta $fb"); + asm("pla"); + asm("sta $fa"); + asm("pla"); + asm("sta $f9"); + asm("pla"); + asm("sta $f8"); + asm("pla"); + asm("sta $f7"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ + + + +#endif /* 0 */ diff --git a/platform/c64/apps/warmboot.c b/platform/c64/apps/warmboot.c new file mode 100644 index 000000000..cec4675fe --- /dev/null +++ b/platform/c64/apps/warmboot.c @@ -0,0 +1,54 @@ +/* + * 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 + * + * $Id: warmboot.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + */ + +#include "contiki.h" + +#pragma optimize(push, off) + +LOADER_INIT_FUNC(warmboot_init, arg) +{ + + arg_free(arg); + + asm("jsr $fda3"); + asm("jsr $fd15"); + asm("jsr $ff5b"); + asm("ldx #$f8"); + asm("txs"); + asm("cli"); + asm("jmp 2061"); + +} +#pragma optimize(push, on) diff --git a/platform/c64/apps/welcome.c b/platform/c64/apps/welcome.c new file mode 100644 index 000000000..8f8a8feca --- /dev/null +++ b/platform/c64/apps/welcome.c @@ -0,0 +1,88 @@ +/* + * 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: welcome.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "contiki.h" +#include "ctk/ctk.h" +#include + + +static struct ctk_window welcomedialog; +static struct ctk_label welcomelabel1 = + {CTK_LABEL(1, 1, 30, 1, "Welcome to " CONTIKI_VERSION_STRING "!")}; +static struct ctk_label welcomelabel2 = + {CTK_LABEL(2, 4, 28, 1, "F1 - open menus")}; +static struct ctk_label welcomelabel3 = + {CTK_LABEL(2, 6, 28, 1, "F3 - cycle windows")}; +static struct ctk_label welcomelabel4 = + {CTK_LABEL(2, 8, 28, 1, "F5 - select up")}; +static struct ctk_label welcomelabel5 = + {CTK_LABEL(2, 10, 28, 1, "F7 - select down")}; +static struct ctk_label welcomelabel6 = + {CTK_LABEL(2, 12, 28, 1, "Return - activate selected")}; +static struct ctk_label welcomelabel7 = + {CTK_LABEL(3, 15, 25, 1, "Press any key to continue")}; + + +PROCESS(welcome_process, "Welcome"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(welcome_process, ev, data) +{ + unsigned char width; + + PROCESS_BEGIN(); + + width = ctk_desktop_width(NULL); + + if(width > 34) { + ctk_dialog_new(&welcomedialog, 32, 17); + } else { + ctk_dialog_new(&welcomedialog, width - 2, 17); + } + CTK_WIDGET_ADD(&welcomedialog, &welcomelabel1); + CTK_WIDGET_ADD(&welcomedialog, &welcomelabel2); + CTK_WIDGET_ADD(&welcomedialog, &welcomelabel3); + CTK_WIDGET_ADD(&welcomedialog, &welcomelabel4); + CTK_WIDGET_ADD(&welcomedialog, &welcomelabel5); + CTK_WIDGET_ADD(&welcomedialog, &welcomelabel6); + CTK_WIDGET_ADD(&welcomedialog, &welcomelabel7); + + ctk_dialog_open(&welcomedialog); + + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT || + ev == ctk_signal_keypress); + ctk_dialog_close(); + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/wget-dsc.c b/platform/c64/apps/wget-dsc.c new file mode 100644 index 000000000..91fc3c55c --- /dev/null +++ b/platform/c64/apps/wget-dsc.c @@ -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: wget-dsc.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon wget_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(wget_dsc, + "Downloads files or D64 disks from the web", + "wget.prg", + wget_init, + &wget_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char wgeticon_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 wgeticon_textmap[9] = { + 'w', 'e', 'b', + 'p', 'r', 'g', + 'd', '6', '4' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon wget_icon = + {CTK_ICON("Web downloader", wgeticon_bitmap, wgeticon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/apps/wget-dsc.h b/platform/c64/apps/wget-dsc.h new file mode 100644 index 000000000..6e7c23d45 --- /dev/null +++ b/platform/c64/apps/wget-dsc.h @@ -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: wget-dsc.h,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ +#ifndef __WGET_DSC_H__ +#define __WGET_DSC_H__ + +#include "sys/dsc.h" + +DSC_HEADER(wget_dsc); + +#endif /* __WGET_DSC_H__ */ diff --git a/platform/c64/apps/wget.c b/platform/c64/apps/wget.c new file mode 100644 index 000000000..b2cac9ed3 --- /dev/null +++ b/platform/c64/apps/wget.c @@ -0,0 +1,528 @@ +/* + * 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: wget.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + + +#include "ctk/ctk.h" +#include "contiki-net.h" +#include "webclient.h" +#include "lib/petsciiconv.h" + +#include "program-handler.h" + +#include +#include +#include +#include +#include + +#include "c64-dio.h" + +#define USE_KERNAL 0 + +static struct ctk_window window; + +static struct ctk_label urllabel = + {CTK_LABEL(0, 1, 4, 1, "URL:")}; +static char url[80]; +static char urledit[80]; +struct ctk_textentry urltextentry = + {CTK_TEXTENTRY(5, 1, 29, 1, urledit, 78)}; + + +static struct ctk_label savefilenamelabel = + {CTK_LABEL(0, 3, 14, 1, "Save filename:")}; +static char savefilename[40]; +static struct ctk_textentry savefilenametextentry = + {CTK_TEXTENTRY(15, 3, 19, 1, savefilename, 38)}; + +static struct ctk_button filebutton = + {CTK_BUTTON(0, 5, 13, "Download file")}; + +static struct ctk_button d64button = + {CTK_BUTTON(17, 5, 18, "Download D64 disk")}; + +static struct ctk_label statustext = + {CTK_LABEL(0, 7, 36, 1, "")}; +static char statusmsg[40]; + +static struct ctk_window d64dialog; +static struct ctk_label overwritelabel = + {CTK_LABEL(0, 1, 36, 1, "This will overwrite the entire disk!")}; +static struct ctk_label makesurelabel1 = + {CTK_LABEL(7, 3, 22, 1, "Make sure you have the")}; +static struct ctk_label makesurelabel2 = + {CTK_LABEL(6, 4, 24, 1, "right disk in the drive!")}; +static struct ctk_button overwritebutton = + {CTK_BUTTON(2, 6, 14, "Overwrite disk")}; +static struct ctk_button cancelbutton = + {CTK_BUTTON(26, 6, 6, "Cancel")}; + +PROCESS(wget_process, "Web downloader"); +/* State */ + +#define DLOAD_NONE 0 +#define DLOAD_FILE 1 +#define DLOAD_D64 2 +static u8_t dload_state; +static unsigned long dload_bytes; + + + +struct drv_state { + u8_t track; + u8_t sect; +}; + +static struct drv_state ds; + +static char buffer[256]; +static u16_t bufferptr; + +/*-----------------------------------------------------------------------------------*/ +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 +start_get(void) +{ + u16_t addr[2]; + unsigned char i; + static char host[32]; + char *file; + register char *urlptr; + unsigned short port; + + /* 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 = "/"; + } + + + /* First check if the host is an IP address. */ + if(uiplib_ipaddrconv(host, (unsigned char *)addr) == 0) { + + /* Try to lookup the hostname. If it fails, we initiate a hostname + lookup and print out an informative message on the + statusbar. */ + 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..."); + } +} +/*-----------------------------------------------------------------------------------*/ +PROCESS_THREAD(wget_process, ev, data) +{ + int ret; + static unsigned char i; + + + + + PROCESS_BEGIN(); + + if(data != NULL) { + strncpy(url, data, sizeof(url)); + strncpy(urledit, data, sizeof(urledit)); + petsciiconv_topetscii(urledit, sizeof(urledit)); + arg_free(data); + } else { +#ifdef WGET_CONF_URL + strncpy(url, WGET_CONF_URL, sizeof(url)); + strncpy(urledit, WGET_CONF_URL, sizeof(urledit)); +#endif /* WGET_CONF_URL */ + } + + + /* Create the main window. */ + ctk_window_new(&window, 36, 8, "Web downloader"); + + + CTK_WIDGET_ADD(&window, &urllabel); + CTK_WIDGET_ADD(&window, &urltextentry); + + CTK_WIDGET_ADD(&window, &savefilenamelabel); + CTK_WIDGET_ADD(&window, &savefilenametextentry); + + /* CTK_WIDGET_ADD(&window, &filebutton);*/ + + CTK_WIDGET_ADD(&window, &d64button); + + CTK_WIDGET_ADD(&window, &statustext); + + dload_state = DLOAD_NONE; + + memset(savefilename, 0, sizeof(savefilename)); + memset(url, 0, sizeof(url)); + + ctk_dialog_new(&d64dialog, 36, 8); + CTK_WIDGET_ADD(&d64dialog, &overwritelabel); + CTK_WIDGET_ADD(&d64dialog, &makesurelabel1); + CTK_WIDGET_ADD(&d64dialog, &makesurelabel2); + CTK_WIDGET_ADD(&d64dialog, &overwritebutton); + CTK_WIDGET_ADD(&d64dialog, &cancelbutton); + + + ctk_window_open(&window); + + while(1) { + + PROCESS_WAIT_EVENT(); + + if(ev == tcpip_event) { + webclient_appcall(data); + } else if(ev == ctk_signal_button_activate) { + if(data == (void *)&filebutton) { + /* ret = cbm_open(2, 8, 2, savefilename); + if(ret == -1) {*/ + sprintf(statusmsg, "Open error with '%s'", savefilename); + show_statustext(statusmsg); + /* } else { + strncpy(url, urledit, sizeof(url)); + petsciiconv_toascii(url, sizeof(url)); + start_get(); + dload_bytes = 0; + dload_state = DLOAD_FILE; + }*/ + } else if(data == (void *)&d64button) { + ctk_dialog_open(&d64dialog); + } else if(data == (void *)&cancelbutton) { + ctk_dialog_close(); + } else if(data == (void *)&overwritebutton) { + ctk_dialog_close(); + + /* Turn of screensaver. */ + program_handler_setscreensaver(NULL); + + strncpy(url, urledit, sizeof(url)); + petsciiconv_toascii(url, sizeof(url)); + start_get(); + dload_bytes = 0; + dload_state = DLOAD_D64; + ds.track = 1; + ds.sect = 0; + bufferptr = 0; +#if USE_KERNAL +#else + c64_dio_init(_curunit); +#endif + + /* c64_dio_init(8);*/ + } + } else if(ev == ctk_signal_hyperlink_activate) { + if(dload_state == DLOAD_NONE) { + /* open_link(w->widget.hyperlink.url);*/ + strncpy(urledit, + ((struct ctk_widget *)data)->widget.hyperlink.url, sizeof(urledit)); + petsciiconv_topetscii(urledit, sizeof(urledit)); + CTK_WIDGET_REDRAW(&urltextentry); + CTK_WIDGET_FOCUS(&window, &urltextentry); + } + } else if(ev == resolv_event_found) { + /* Either found a hostname, or not. */ + if((char *)data != NULL && + resolv_lookup((char *)data) != NULL) { + start_get(); + } else { + show_statustext("Host not found."); + } + } else if(ev == ctk_signal_window_close) { + break; + } + } + + PROCESS_END(); +} +/*-----------------------------------------------------------------------------------*/ +/* 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"); + if(dload_state == DLOAD_FILE) { + cbm_close(2); + } + +} +/*-----------------------------------------------------------------------------------*/ +/* 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("Done."); +} +/*-----------------------------------------------------------------------------------*/ +/* webclient_closed(): + * + * Callback function. Called from the webclient when the HTTP + * connection is connected. + */ +void +webclient_connected(void) +{ + show_statustext("Request sent..."); +} +/*-----------------------------------------------------------------------------------*/ +static u8_t +next_sector(void) +{ + ++ds.sect; + if(ds.track < 18) { + if(ds.sect == 21) { + ++ds.track; + ds.sect = 0; + } + } else if(ds.track < 25) { + if(ds.sect == 19) { + ++ds.track; + ds.sect = 0; + } + } else if(ds.track < 31) { + if(ds.sect == 18) { + ++ds.track; + ds.sect = 0; + } + } else if(ds.track < 36) { + if(ds.sect == 17) { + ++ds.track; + ds.sect = 0; + } + } + + if(ds.track == 36) { + return 1; + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +static void +x_open(u8_t f, u8_t d, u8_t cmd, u8_t *fname) +{ + u8_t ret; + + ret = cbm_open(f, d, cmd, fname); + if(ret != 0) { + /* printf("open: error %d\n", ret);*/ + /* ctk_label_set_text(&statuslabel, "Open err"); + CTK_WIDGET_REDRAW(&statuslabel);*/ + show_statustext("Open error"); + } + +} +static void +write_sector(u8_t device, u8_t track, u8_t sect, void *mem) +{ + u16_t ret; + static u8_t cmd[32]; + + x_open(15, device, 15, NULL); + x_open(2, device, 2, "#"); + + ret = cbm_write(2, mem, 256); + + sprintf(cmd, "u2: 2 0 %d %d", track, sect); + cbm_write(15, cmd, strlen(cmd)); + /* printf("%s\n", cmd);*/ + + + /* ret = 0;*/ + if(ret == -1) { + sprintf(statusmsg, "Write error at %d:%d", track, sect); + show_statustext(statusmsg); + } else { + sprintf(statusmsg, "Wrote %d bytes to %d:%d", ret, track, sect); + show_statustext(statusmsg); + } + /* printf("write: wrote %d bytes\n", ret);*/ + + cbm_close(2); + cbm_close(15); +} + +static void +write_buffer(void) +{ +#if USE_KERNAL + write_sector(8, ds.track, ds.sect, buffer); +#else + c64_dio_write_block(ds.track, ds.sect, buffer); +#endif + if(next_sector() != 0) { + dload_state = DLOAD_NONE; + } +} +static void +handle_d64_data(char *data, u16_t len) +{ + u16_t bufferlen; + + while(dload_state == DLOAD_D64 && + len > 0) { + bufferlen = sizeof(buffer) - bufferptr; + if(len < bufferlen) { + bufferlen = len; + } + + memcpy(&buffer[bufferptr], data, bufferlen); + + data += bufferlen; + bufferptr += bufferlen; + len -= bufferlen; + + if(bufferptr == sizeof(buffer)) { + write_buffer(); + bufferptr = 0; + } + } +} +/*-----------------------------------------------------------------------------------*/ +/* webclient_datahandler(): + * + * Callback function. Called from the webclient module when HTTP data + * has arrived. + */ +void +webclient_datahandler(char *data, u16_t len) +{ + int ret; + + if(len > 0) { + dload_bytes += len; + sprintf(statusmsg, "Downloading (%lu bytes)", dload_bytes); + show_statustext(statusmsg); + if(dload_state == DLOAD_D64) { + handle_d64_data(data, len); + } else if(dload_state == DLOAD_FILE) { + ret = cbm_write(2, data, len); + if(ret != len) { + sprintf(statusmsg, "Wrote only %d bytes", ret); + show_statustext(statusmsg); + } + } + } + + if(data == NULL) { + if(dload_state == DLOAD_FILE) { + cbm_close(2); + } + dload_state = DLOAD_NONE; + sprintf(statusmsg, "Finished downloading %lu bytes", dload_bytes); + show_statustext(statusmsg); + } +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/c64.cfg b/platform/c64/c64.cfg new file mode 100644 index 000000000..76efb178a --- /dev/null +++ b/platform/c64/c64.cfg @@ -0,0 +1,30 @@ +MEMORY { + ZP: start = $02, size = $1A, type = rw, define = yes; + RAM: start = $7FF, size = $c801, define = yes, file = %O; +} +SEGMENTS { + STARTUP: load = RAM, type = ro; + INIT: load = RAM, type = ro; + CODE: load = RAM, type = ro; + RODATA: load = RAM, type = ro; + DATA: load = RAM, type = rw; + BSS: load = RAM, type = bss, define = yes; + ZEROPAGE: load = ZP, type = zp; +} +FEATURES { + CONDES: segment = RODATA, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = RODATA, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; + CONDES: segment = RODATA, + type = interruptor, + label = __INTERRUPTOR_TABLE__, + count = __INTERRUPTOR_COUNT__; +} +SYMBOLS { + __STACKSIZE__ = $100; +} diff --git a/platform/c64/contiki-conf.h b/platform/c64/contiki-conf.h new file mode 100644 index 000000000..3248dd4c5 --- /dev/null +++ b/platform/c64/contiki-conf.h @@ -0,0 +1,606 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#define LC_CONF_INCLUDE "lib/lc-cc65.h" + +/*#pragma charmap(0, 0); +#pragma charmap(1, 1); +#pragma charmap(2, 2); +#pragma charmap(3, 3); +#pragma charmap(4, 4); +#pragma charmap(5, 5); +#pragma charmap(6, 6); +#pragma charmap(7, 7); +#pragma charmap(8, 8); +#pragma charmap(9, 9); +#pragma charmap(10, 10); +#pragma charmap(11, 11); +#pragma charmap(12, 12); +#pragma charmap(13, 13); +#pragma charmap(14, 14); +#pragma charmap(15, 15); +#pragma charmap(16, 16); +#pragma charmap(17, 17); +#pragma charmap(18, 18); +#pragma charmap(19, 19); +#pragma charmap(20, 20); +#pragma charmap(21, 21); +#pragma charmap(22, 22); +#pragma charmap(23, 23); +#pragma charmap(24, 24); +#pragma charmap(25, 25); +#pragma charmap(26, 26); +#pragma charmap(27, 27); +#pragma charmap(28, 28); +#pragma charmap(29, 29); +#pragma charmap(30, 30); +#pragma charmap(31, 31); +#pragma charmap(32, 32); +#pragma charmap(33, 33); +#pragma charmap(34, 34); +#pragma charmap(35, 35); +#pragma charmap(36, 36); +#pragma charmap(37, 37); +#pragma charmap(38, 38); +#pragma charmap(39, 39); +#pragma charmap(40, 40); +#pragma charmap(41, 41); +#pragma charmap(42, 42); +#pragma charmap(43, 43); +#pragma charmap(44, 44); +#pragma charmap(45, 45); +#pragma charmap(46, 46); +#pragma charmap(47, 47); +#pragma charmap(48, 48); +#pragma charmap(49, 49); +#pragma charmap(50, 50); +#pragma charmap(51, 51); +#pragma charmap(52, 52); +#pragma charmap(53, 53); +#pragma charmap(54, 54); +#pragma charmap(55, 55); +#pragma charmap(56, 56); +#pragma charmap(57, 57); +#pragma charmap(58, 58); +#pragma charmap(59, 59); +#pragma charmap(60, 60); +#pragma charmap(61, 61); +#pragma charmap(62, 62); +#pragma charmap(63, 63); +#pragma charmap(64, 64); +#pragma charmap(65, 65); +#pragma charmap(66, 66); +#pragma charmap(67, 67); +#pragma charmap(68, 68); +#pragma charmap(69, 69); +#pragma charmap(70, 70); +#pragma charmap(71, 71); +#pragma charmap(72, 72); +#pragma charmap(73, 73); +#pragma charmap(74, 74); +#pragma charmap(75, 75); +#pragma charmap(76, 76); +#pragma charmap(77, 77); +#pragma charmap(78, 78); +#pragma charmap(79, 79); +#pragma charmap(80, 80); +#pragma charmap(81, 81); +#pragma charmap(82, 82); +#pragma charmap(83, 83); +#pragma charmap(84, 84); +#pragma charmap(85, 85); +#pragma charmap(86, 86); +#pragma charmap(87, 87); +#pragma charmap(88, 88); +#pragma charmap(89, 89); +#pragma charmap(90, 90); +#pragma charmap(91, 91); +#pragma charmap(92, 92); +#pragma charmap(93, 93); +#pragma charmap(94, 94); +#pragma charmap(95, 95); +#pragma charmap(96, 96); +#pragma charmap(97, 97); +#pragma charmap(98, 98); +#pragma charmap(99, 99); +#pragma charmap(100, 100); +#pragma charmap(101, 101); +#pragma charmap(102, 102); +#pragma charmap(103, 103); +#pragma charmap(104, 104); +#pragma charmap(105, 105); +#pragma charmap(106, 106); +#pragma charmap(107, 107); +#pragma charmap(108, 108); +#pragma charmap(109, 109); +#pragma charmap(110, 110); +#pragma charmap(111, 111); +#pragma charmap(112, 112); +#pragma charmap(113, 113); +#pragma charmap(114, 114); +#pragma charmap(115, 115); +#pragma charmap(116, 116); +#pragma charmap(117, 117); +#pragma charmap(118, 118); +#pragma charmap(119, 119); +#pragma charmap(120, 120); +#pragma charmap(121, 121); +#pragma charmap(122, 122); +#pragma charmap(123, 123); +#pragma charmap(124, 124); +#pragma charmap(125, 125); +#pragma charmap(126, 126); +#pragma charmap(127, 127); +#pragma charmap(128, 128); +#pragma charmap(129, 129); +#pragma charmap(130, 130); +#pragma charmap(131, 131); +#pragma charmap(132, 132); +#pragma charmap(133, 133); +#pragma charmap(134, 134); +#pragma charmap(135, 135); +#pragma charmap(136, 136); +#pragma charmap(137, 137); +#pragma charmap(138, 138); +#pragma charmap(139, 139); +#pragma charmap(140, 140); +#pragma charmap(141, 141); +#pragma charmap(142, 142); +#pragma charmap(143, 143); +#pragma charmap(144, 144); +#pragma charmap(145, 145); +#pragma charmap(146, 146); +#pragma charmap(147, 147); +#pragma charmap(148, 148); +#pragma charmap(149, 149); +#pragma charmap(150, 150); +#pragma charmap(151, 151); +#pragma charmap(152, 152); +#pragma charmap(153, 153); +#pragma charmap(154, 154); +#pragma charmap(155, 155); +#pragma charmap(156, 156); +#pragma charmap(157, 157); +#pragma charmap(158, 158); +#pragma charmap(159, 159); +#pragma charmap(160, 160); +#pragma charmap(161, 161); +#pragma charmap(162, 162); +#pragma charmap(163, 163); +#pragma charmap(164, 164); +#pragma charmap(165, 165); +#pragma charmap(166, 166); +#pragma charmap(167, 167); +#pragma charmap(168, 168); +#pragma charmap(169, 169); +#pragma charmap(170, 170); +#pragma charmap(171, 171); +#pragma charmap(172, 172); +#pragma charmap(173, 173); +#pragma charmap(174, 174); +#pragma charmap(175, 175); +#pragma charmap(176, 176); +#pragma charmap(177, 177); +#pragma charmap(178, 178); +#pragma charmap(179, 179); +#pragma charmap(180, 180); +#pragma charmap(181, 181); +#pragma charmap(182, 182); +#pragma charmap(183, 183); +#pragma charmap(184, 184); +#pragma charmap(185, 185); +#pragma charmap(186, 186); +#pragma charmap(187, 187); +#pragma charmap(188, 188); +#pragma charmap(189, 189); +#pragma charmap(190, 190); +#pragma charmap(191, 191); +#pragma charmap(192, 192); +#pragma charmap(193, 193); +#pragma charmap(194, 194); +#pragma charmap(195, 195); +#pragma charmap(196, 196); +#pragma charmap(197, 197); +#pragma charmap(198, 198); +#pragma charmap(199, 199); +#pragma charmap(200, 200); +#pragma charmap(201, 201); +#pragma charmap(202, 202); +#pragma charmap(203, 203); +#pragma charmap(204, 204); +#pragma charmap(205, 205); +#pragma charmap(206, 206); +#pragma charmap(207, 207); +#pragma charmap(208, 208); +#pragma charmap(209, 209); +#pragma charmap(210, 210); +#pragma charmap(211, 211); +#pragma charmap(212, 212); +#pragma charmap(213, 213); +#pragma charmap(214, 214); +#pragma charmap(215, 215); +#pragma charmap(216, 216); +#pragma charmap(217, 217); +#pragma charmap(218, 218); +#pragma charmap(219, 219); +#pragma charmap(220, 220); +#pragma charmap(221, 221); +#pragma charmap(222, 222); +#pragma charmap(223, 223); +#pragma charmap(224, 224); +#pragma charmap(225, 225); +#pragma charmap(226, 226); +#pragma charmap(227, 227); +#pragma charmap(228, 228); +#pragma charmap(229, 229); +#pragma charmap(230, 230); +#pragma charmap(231, 231); +#pragma charmap(232, 232); +#pragma charmap(233, 233); +#pragma charmap(234, 234); +#pragma charmap(235, 235); +#pragma charmap(236, 236); +#pragma charmap(237, 237); +#pragma charmap(238, 238); +#pragma charmap(239, 239); +#pragma charmap(240, 240); +#pragma charmap(241, 241); +#pragma charmap(242, 242); +#pragma charmap(243, 243); +#pragma charmap(244, 244); +#pragma charmap(245, 245); +#pragma charmap(246, 246); +#pragma charmap(247, 247); +#pragma charmap(248, 248); +#pragma charmap(249, 249); +#pragma charmap(250, 250); +#pragma charmap(251, 251); +#pragma charmap(252, 252); +#pragma charmap(253, 253); +#pragma charmap(254, 254); +#pragma charmap(255, 255);*/ + +/* C compiler configuration. */ + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 + +#define CC_CONF_FASTCALL fastcall + +/* Clock configuration. */ + +#include + +typedef unsigned short clock_time_t; + +#define CLOCK_CONF_SECOND CLK_TCK + + +/* + * CTK GUI toolkit configuration. + */ + +#include "ctk-arch.h" + +/* Defines which key that is to be used for activating the menus */ +#define CTK_CONF_MENU_KEY CH_F1 + +/* Defines which key that is to be used for switching the frontmost + window. */ +#define CTK_CONF_WINDOWSWITCH_KEY CH_F3 + +/* Defines which key that is to be used for switching to the prevoius + widget. */ +#define CTK_CONF_WIDGETUP_KEY CH_F5 + +/* Defines which key that is to be used for switching to the next + widget. */ +#define CTK_CONF_WIDGETDOWN_KEY CH_F7 + +/* Toggles mouse support (must have support functions in the +architecture specific files to work). */ +#define CTK_CONF_MOUSE_SUPPORT 0 + +/* Toggles support for icons. */ +#define CTK_CONF_ICONS 1 + +/* Toggles support for icon bitmaps. */ +#define CTK_CONF_ICON_BITMAPS 1 + +/* Toggles support for icon textmaps. */ +#define CTK_CONF_ICON_TEXTMAPS 1 + +/* Toggles support for movable windows. */ +#define CTK_CONF_WINDOWMOVE 1 + +/* Toggles support for closable windows. */ +#define CTK_CONF_WINDOWCLOSE 1 + +/* Toggles support for menus. */ +#define CTK_CONF_MENUS 1 + +/* Defines the default width of a menu. */ +#define CTK_CONF_MENUWIDTH 16 +/* The maximum number of menu items in each menu. */ +#define CTK_CONF_MAXMENUITEMS 10 + +/* Toggles support for screen savers. */ +#define CTK_CONF_SCREENSAVER 1 + +/* + * CTK conio configuration. + */ + +#if 0 +/* Light gray inverted color scheme: */ +#define BORDERCOLOR COLOR_WHITE +#define SCREENCOLOR COLOR_WHITE +#define BACKGROUNDCOLOR COLOR_WHITE + +#define WINDOWCOLOR_FOCUS COLOR_BLACK +#define WINDOWCOLOR COLOR_GRAY2 + +#define DIALOGCOLOR COLOR_RED + +#define WIDGETCOLOR_HLINK COLOR_BLUE +#define WIDGETCOLOR_FWIN COLOR_BLACK +#define WIDGETCOLOR COLOR_GRAY1 +#define WIDGETCOLOR_DIALOG COLOR_RED +#define WIDGETCOLOR_FOCUS COLOR_BLACK + +#define MENUCOLOR COLOR_BLACK +#define OPENMENUCOLOR COLOR_BLACK +#define ACTIVEMENUITEMCOLOR COLOR_BLACK +#endif /* 0 */ + +#if 0 +/* Blue color scheme: */ +#define BORDERCOLOR COLOR_LIGHTBLUE +#define SCREENCOLOR COLOR_BLUE +#define BACKGROUNDCOLOR COLOR_BLUE + +#define WINDOWCOLOR_FOCUS COLOR_LIGHTBLUE +#define WINDOWCOLOR COLOR_GRAY1 + +#define DIALOGCOLOR COLOR_WHITE + +#define WIDGETCOLOR_HLINK COLOR_CYAN +#define WIDGETCOLOR_FWIN COLOR_LIGHTBLUE +#define WIDGETCOLOR COLOR_GRAY1 +#define WIDGETCOLOR_DIALOG COLOR_WHITE +#define WIDGETCOLOR_FOCUS COLOR_YELLOW + +#define MENUCOLOR COLOR_WHITE +#define OPENMENUCOLOR COLOR_LIGHTBLUE +#define ACTIVEMENUITEMCOLOR COLOR_YELLOW +#endif /* 0 */ + +#if 0 +/* Black and white monocrome color scheme: */ +#define BORDERCOLOR COLOR_BLACK +#define SCREENCOLOR COLOR_BLACK +#define BACKGROUNDCOLOR COLOR_BLACK + +#define WINDOWCOLOR_FOCUS COLOR_WHITE +#define WINDOWCOLOR COLOR_WHITE + +#define DIALOGCOLOR COLOR_WHITE + +#define WIDGETCOLOR_HLINK COLOR_WHITE +#define WIDGETCOLOR_FWIN COLOR_WHITE +#define WIDGETCOLOR COLOR_WHITE +#define WIDGETCOLOR_DIALOG COLOR_WHITE +#define WIDGETCOLOR_FOCUS COLOR_WHITE + +#define MENUCOLOR COLOR_WHITE +#define OPENMENUCOLOR COLOR_WHITE +#define ACTIVEMENUITEMCOLOR COLOR_WHITE +#endif /* 0 */ + +#if 0 +/* Blue monocrome color scheme: */ +#define BORDERCOLOR COLOR_BLUE +#define SCREENCOLOR COLOR_BLUE +#define BACKGROUNDCOLOR COLOR_BLUE + +#define WINDOWCOLOR_FOCUS COLOR_LIGHTBLUE +#define WINDOWCOLOR COLOR_LIGHTBLUE + +#define DIALOGCOLOR COLOR_LIGHTBLUE + +#define WIDGETCOLOR_HLINK COLOR_LIGHTBLUE +#define WIDGETCOLOR_FWIN COLOR_LIGHTBLUE +#define WIDGETCOLOR COLOR_LIGHTBLUE +#define WIDGETCOLOR_DIALOG COLOR_LIGHTBLUE +#define WIDGETCOLOR_FOCUS COLOR_LIGHTBLUE + +#define MENUCOLOR COLOR_LIGHTBLUE +#define OPENMENUCOLOR COLOR_LIGHTBLUE +#define ACTIVEMENUITEMCOLOR COLOR_LIGHTBLUE +#endif /* 0 */ + +#if 1 +/* Gray color scheme: */ +#define BORDERCOLOR COLOR_GRAY1 +#define SCREENCOLOR COLOR_GRAY1 +#define BACKGROUNDCOLOR COLOR_GRAY1 + +#define WINDOWCOLOR_FOCUS COLOR_GRAY3 +#define WINDOWCOLOR COLOR_GRAY2 + +#define DIALOGCOLOR COLOR_WHITE + +#define WIDGETCOLOR_HLINK COLOR_LIGHTBLUE +#define WIDGETCOLOR_FWIN COLOR_GRAY3 +#define WIDGETCOLOR COLOR_GRAY2 +#define WIDGETCOLOR_DIALOG COLOR_WHITE +#define WIDGETCOLOR_FOCUS COLOR_YELLOW + +#define MENUCOLOR COLOR_GRAY3 +#define OPENMENUCOLOR COLOR_WHITE +#define ACTIVEMENUITEMCOLOR COLOR_YELLOW +#endif /* 0 */ + +#if 0 +/* Red color scheme: */ +#define BORDERCOLOR COLOR_BLACK +#define SCREENCOLOR COLOR_BLACK +#define BACKGROUNDCOLOR COLOR_BLACK + +#define WINDOWCOLOR_FOCUS COLOR_LIGHTRED +#define WINDOWCOLOR COLOR_RED + +#define DIALOGCOLOR COLOR_WHITE + +#define WIDGETCOLOR_HLINK COLOR_LIGHTBLUE +#define WIDGETCOLOR_FWIN COLOR_YELLOW +#define WIDGETCOLOR COLOR_LIGHTRED +#define WIDGETCOLOR_DIALOG COLOR_WHITE +#define WIDGETCOLOR_FOCUS COLOR_YELLOW + +#define MENUCOLOR COLOR_LIGHTRED +#define OPENMENUCOLOR COLOR_WHITE +#define ACTIVEMENUITEMCOLOR COLOR_YELLOW +#endif /* 0 */ + +/* CTK VNC server configuration. */ + +#define CTK_VNCSERVER_CONF_NUMCONNS 1 + +#define CTK_VNCSERVER_CONF_MAX_ICONS 4 + +#define CTK_VNCSERVER_CONF_SCREEN (u8_t *)0x0400 + +/* Email program configuration. */ + +#define EMAIL_CONF_WIDTH 36 +#define EMAIL_CONF_HEIGHT 17 + +/* IRC program configuration. */ + +#define IRC_CONF_WIDTH 78 +#define IRC_CONF_HEIGHT 21 + +#define IRC_CONF_SYSTEM_STRING "c64" + +/* Libconio configuration. */ + +#define LIBCONIO_CONF_SCREEN_WIDTH 80 +#define LIBCONIO_CONF_SCREEN_HEIGHT 25 + +/* Logging configuration. */ + +#define LOG_CONF_ENABLED 1 + +/* Program handler configuration. */ + +#define PROGRAM_HANDLER_CONF_MAX_NUMDSCS 10 + +/* Shell GUI configuration. */ + +#define SHELL_GUI_CONF_XSIZE 26 +#define SHELL_GUI_CONF_YSIZE 12 + +/* Telnet daemon configuration. */ + +#define TELNETD_CONF_LINELEN 32 +#define TELNETD_CONF_NUMLINES 12 + +#define TELNETD_CONF_GUI 1 + +/* uIP configuration. */ + +#define UIP_CONF_MAX_CONNECTIONS 10 +#define UIP_CONF_MAX_LISTENPORTS 10 +#define UIP_CONF_BUFFER_SIZE 400 +#define UIP_CONF_RECEIVE_WINDOW 320 + +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN + +#define UIP_CONF_ARBTAB_SIZE 4 + +#define UIP_CONF_RESOLV_ENTRIES 4 +#define UIP_CONF_PINGADDRCONF 0 + +#define UIP_CONF_LOGGING 0 +#define UIP_CONF_UDP_CONNS 6 +#define UIP_CONF_BROADCAST 0 + +#define UIP_CONF_UDP_CHECKSUMS 0 + +#define UIP_ARCH_ADD32 1 +#define UIP_ARCH_CHKSUM 1 + +/** + * The 8-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * char" works for most compilers. + */ +typedef unsigned char u8_t; + +/** + * The 16-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * short" works for most compilers. + */ +typedef unsigned short u16_t; + +/** + * The 32-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * long" works for most compilers. + */ +typedef unsigned long u32_t; + +/** + * The statistics data type. + * + * This datatype determines how high the statistics counters are able + * to count. + */ +typedef unsigned short uip_stats_t; + + +/* VNC viewer configuration. */ + +#define VNC_CONF_VIEWPORT_WIDTH (32*8) +#define VNC_CONF_VIEWPORT_HEIGHT (16*8) + +#define VNC_CONF_REFRESH_ROWS 8 + +/* Web browser configuration. */ + +#define WWW_CONF_HOMEPAGE "http://contiki.c64.org/" + +/* The size of the HTML viewing area. */ +#define WWW_CONF_WEBPAGE_WIDTH 36 +#define WWW_CONF_WEBPAGE_HEIGHT 17 + +/* The size of the "Back" history. */ +#define WWW_CONF_HISTORY_SIZE 2 + +/* Defines the maximum length of an URL */ +#define WWW_CONF_MAX_URLLEN 55 + +/* The maxiumum number of widgets (i.e., hyperlinks, form elements) on + a page. */ +#define WWW_CONF_MAX_NUMPAGEWIDGETS 8 + +/* Turns
        support on or off; must be on for forms to work. */ +#define WWW_CONF_RENDERSTATE 0 + +/* Toggles support for HTML forms. */ +#define WWW_CONF_FORMS 0 + +/* Maximum lengths for various HTML form parameters. */ +#define WWW_CONF_MAX_FORMACTIONLEN 30 +#define WWW_CONF_MAX_FORMNAMELEN 20 +#define WWW_CONF_MAX_INPUTNAMELEN 20 + +#define WWW_CONF_MAX_INPUTVALUELEN (WWW_CONF_WEBPAGE_WIDTH - 1) + + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/c64/ctk/ctk-80col-asm.h b/platform/c64/ctk/ctk-80col-asm.h new file mode 100644 index 000000000..d5632ee3b --- /dev/null +++ b/platform/c64/ctk/ctk-80col-asm.h @@ -0,0 +1,73 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-80col-asm.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#ifndef __CTK_80COL_ASM_H__ +#define __CTK_80COL_ASM_H__ + +void __fastcall__ ctk_80col_cclear(unsigned char len); +void __fastcall__ ctk_80col_chline(unsigned char len); +void __fastcall__ ctk_80col_cputc(unsigned char c); +void __fastcall__ ctk_80col_cputsn(unsigned char *str, + unsigned char len); + +void ctk_80col_draw_buttonleft(void); +void ctk_80col_draw_buttonright(void); + +struct ctk_80col_windowparams { + unsigned char w; + unsigned char h; + unsigned char clipy1; + unsigned char clipy2; + unsigned char color1; + unsigned char color2; + unsigned char titlecolor; + unsigned char titlelen; + char *title; +}; +extern struct ctk_80col_windowparams ctk_80col_windowparams; +void ctk_80col_draw_windowborders(void); + +extern unsigned char ctk_80col_cursx, + ctk_80col_cursy, + ctk_80col_color, + ctk_80col_reversed, + ctk_80col_underline; + + +void __fastcall__ ctk_80col_draw_bitmapline(unsigned char len); + +void __fastcall__ ctk_80col_clear_line(unsigned char len); + +#endif /* __CTK_80COL_ASM_H__ */ diff --git a/platform/c64/ctk/ctk-80col-theme.h b/platform/c64/ctk/ctk-80col-theme.h new file mode 100644 index 000000000..6ba455e8c --- /dev/null +++ b/platform/c64/ctk/ctk-80col-theme.h @@ -0,0 +1,83 @@ + /* + * 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 for the C64 + * + * $Id: ctk-80col-theme.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ +#ifndef __CTK_80COL_THEME_H__ +#define __CTK_80COL_THEME_H__ + +struct ctk_80col_theme { + /* Version string. */ + char version[8]; + + /* Window borders patterns. */ + unsigned char ulcorner[8], /* Upper left corner. */ + titlebar[8], /* Title bar pattern. */ + urcorner[8], /* Upper right corner. */ + rightborder[8], /* Right border. */ + lrcorner[8], /* Lower right corner. */ + lowerborder[8], /* Lower border. */ + llcorner[8], /* Lower left corner. */ + leftborder[8]; /* Left border. */ + + /* Button corner patterns. */ + unsigned char buttonleftpattern[8], + buttonrightpattern[8]; + + /* Menu border patterns. */ + unsigned char menuleftpattern[8], + menurightpattern[8]; + + + + /* Window and widget colors. */ + unsigned char windowcolors[6], + separatorcolors[6], + labelcolors[6], + buttoncolors[6], + hyperlinkcolors[6], + textentrycolors[6], + bitmapcolors[6], + textmapcolors[6], + iconcolors[6]; + + /* Menu colors. */ + unsigned char menucolor, + openmenucolor, + activemenucolor; + +}; + +extern struct ctk_80col_theme ctk_80col_theme; +extern struct ctk_80col_theme *ctk_80col_theme_ptr; + +#endif /* __CTK_80COL_THEME_H__ */ diff --git a/platform/c64/ctk/ctk-80col.c b/platform/c64/ctk/ctk-80col.c new file mode 100644 index 000000000..254c5aeb6 --- /dev/null +++ b/platform/c64/ctk/ctk-80col.c @@ -0,0 +1,1187 @@ +/* + * 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 + * + * $Id: ctk-80col.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ + +#include "contiki.h" + +#include "ctk/ctk.h" +#include "ctk/ctk-draw.h" +#include "ctk/ctk-draw-service.h" + +#include "ctk-80col-asm.h" +#include "ctk-80col-theme.h" + +#include + +unsigned char ctk_80col_cursx, ctk_80col_cursy; +unsigned char ctk_80col_reversed; +unsigned char ctk_80col_color; +unsigned char *ctk_80col_bitmapptr; +unsigned char ctk_80col_underline = 0; + +#define SCREEN_HEIGHT 25 +#define SCREEN_WIDTH 80 + +#define SCREENADDR 0xdc00 +#define HIRESADDR 0xe000 + +unsigned char ctk_80col_lefttab[256]; +unsigned char ctk_80col_righttab[256]; + +#define COLOR(bg, fg) ((fg << 4) | (bg)) + +#define COLOR_DIALOG 0x01 +#define COLOR_FOCUS_WINDOW 0xbf +#define COLOR_BACKGROUND_WINDOW 0x0c + +#define color(c) ctk_80col_color = c + +#define BGCOLOR1 7 +#define BGCOLOR2 10 +#define BGCOLOR3 4 +#define BGCOLOR4 6 + +unsigned char ctk_80col_screencolors[25] = + {COLOR(BGCOLOR4,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,1)}; + +unsigned char ctk_80col_screenpattern[25*8] = + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + +unsigned short ctk_80col_yscreenaddr[25] = + {0 * 40 + SCREENADDR, 1 * 40 + SCREENADDR, + 2 * 40 + SCREENADDR, 3 * 40 + SCREENADDR, + 4 * 40 + SCREENADDR, 5 * 40 + SCREENADDR, + 6 * 40 + SCREENADDR, 7 * 40 + SCREENADDR, + 8 * 40 + SCREENADDR, 9 * 40 + SCREENADDR, + 10 * 40 + SCREENADDR, 11 * 40 + SCREENADDR, + 12 * 40 + SCREENADDR, 13 * 40 + SCREENADDR, + 14 * 40 + SCREENADDR, 15 * 40 + SCREENADDR, + 16 * 40 + SCREENADDR, 17 * 40 + SCREENADDR, + 18 * 40 + SCREENADDR, 19 * 40 + SCREENADDR, + 20 * 40 + SCREENADDR, 21 * 40 + SCREENADDR, + 22 * 40 + SCREENADDR, 23 * 40 + SCREENADDR, + 24 * 40 + SCREENADDR}; + +unsigned short ctk_80col_yhiresaddr[25] = + {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR, + 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR, + 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR, + 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR, + 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR, + 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR, + 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR, + 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR, + 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR, + 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR, + 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR, + 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR, + 24 * 320 + HIRESADDR}; + + +struct ctk_80col_theme ctk_80col_theme = + { + /* Version string. */ + /* char version[8]; */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* Window borders patterns. */ + /* unsigned char ulcorner[8], */ /* Upper left corner. */ + {0xff,0xc0,0x80,0xbf,0x80,0xbf,0x80,0x80}, + + /* titlebar[8], */ /* Title bar pattern. */ + {0xff,0x00,0x00,0xff,0x00,0xff,0x00,0x00}, + + /* urcorner[8], */ /* Upper right corner. */ + {0xff,0x03,0x01,0xfd,0x01,0xfd,0x01,0x01}, + + /* rightborder[8], */ /* Right border. */ + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, + + /* lrcorner[8], */ /* Lower right corner. */ + {0x01,0x01,0x01,0x01,0x01,0x01,0x03,0xff}, + + /* lowerborder[8], */ /* Lower border. */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff}, + + /* llcorner[8], */ /* Lower left corner. */ + {0x80,0x80,0x80,0x80,0x80,0x80,0xc0,0xff}, + + /* leftborder[8]; */ /* Left border. */ + {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80}, + + /* Button corner patterns. */ + /* unsigned char buttonleft[8], */ + {0xc5,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf}, + + /* buttonright[8]; */ + {0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xa3}, + + /* Menu border patterns. */ + /* unsigned char menuleftpattern[8], */ + {0x0f,0x3f,0x3f,0x7f,0x7f,0xff,0xff,0xff}, + + /* menurightpatterns[8]; */ + {0xf0,0xfc,0xfc,0xfe,0xfe,0xff,0xff,0xff}, + + /* Window and widget colors. */ + /* unsigned char windowcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_BLACK), + COLOR(COLOR_GRAY2, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* separatorcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_GRAY2), + COLOR(COLOR_GRAY3, COLOR_GRAY2), + COLOR(COLOR_WHITE, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_GRAY1)}, + + /* labelcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* buttoncolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY3), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY3)}, + + /* hyperlinkcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_WHITE, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_WHITE), + COLOR(COLOR_WHITE, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_WHITE)}, + + /* textentrycolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* bitmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* textmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* iconcolors[6]; */ + {COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_WHITE), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_BLACK, COLOR_YELLOW)}, + + /* Menu colors. */ + /* unsigned char menucolor,*/ + COLOR(COLOR_YELLOW, COLOR_BLACK), + + /* openmenucolor, */ + COLOR(COLOR_WHITE, COLOR_BLACK), + + /* activemenucolor; */ + COLOR(COLOR_BLACK, COLOR_WHITE), + + }; +char ctk_80col_versionstring[] = CONTIKI_VERSION_STRING; +char ctk_80col_versionstring_len = sizeof(CONTIKI_VERSION_STRING) - 1; + +struct ctk_80col_windowparams ctk_80col_windowparams; + +/*---------------------------------------------------------------------------*/ +/*void +ctk_arch_draw_char(char c, + unsigned char xpos, + unsigned char ypos, + unsigned char reversedflag, + unsigned char color) +{ + ctk_80col_cursx = xpos; + ctk_80col_cursy = ypos; + ctk_80col_reversed = reversedflag; + ctk_80col_color = color; + + ctk_80col_cputc(c); +}*/ +/*---------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +nmi2(void) +{ + asm("pla"); + asm("sta $01"); + asm("pla"); + asm("rti"); +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +nmi(void) +{ + asm("sei"); + asm("pha"); + asm("inc $d020"); + asm("lda $01"); + asm("pha"); + asm("lda #$36"); + asm("sta $01"); + asm("lda #>_nmi2"); + asm("pha"); + asm("lda #<_nmi2"); + asm("pha"); + asm("php"); + asm("jmp ($0318)"); + + nmi2(); +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +setup_nmi(void) +{ + asm("lda #<_nmi"); + asm("sta $fffa"); + asm("lda #>_nmi"); + asm("sta $fffb"); + return; + nmi(); +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +void reset(void); +void +quit(void) +{ + VIC.ctrl1 = 0x1b; /* $D011 */ + VIC.addr = 0x17; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + CIA2.pra = 0x03; /* $DD00 */ + + VIC.bordercolor = 0x0e; /* $D020 */ + VIC.bgcolor0 = 0x06; /* $D021 */ + + memset((char *)0xd800, 0x0e, 40*25); + +} +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +ctk_80col_init(void) +{ + int i; + + setup_nmi(); + + /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for + hires/colors. */ + VIC.ctrl1 = 0x3b; /* $D011 */ + VIC.addr = 0x78; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + CIA2.pra = 0x00; /* $DD00 */ + + VIC.bordercolor = 0x06; /* $D020 */ + VIC.bgcolor0 = 0x0b; /* $D021 */ + + /* Fill color memory. */ + asm("sei"); + asm("lda $01"); + asm("pha"); + asm("lda #$30"); + asm("sta $01"); + asm("ldx #0"); + asm("lda #$0"); + asm("fillcolorloop:"); + asm("sta $dc00,x"); + asm("sta $dd00,x"); + asm("sta $de00,x"); + asm("sta $df00,x"); + asm("inx"); + asm("bne fillcolorloop"); + + /* Setup sprite pointers */ + asm("ldx #$fd"); + asm("stx $dff8"); + asm("inx"); + asm("stx $dff9"); + asm("pla"); + asm("sta $01"); + asm("cli"); + + /* Fill hires memory with 0. */ + + memset((char *)0xe000, 0, 8000); + + for(i = 0; i < 256; ++i) { +#if 0 + ctk_80col_lefttab[i] = + ((i & 0x40) << 1) | + ((i & 0x20) << 1) | + ((i & 0x08) << 2) | + ((i & 0x02) << 3); + ctk_80col_righttab[i] = + ((i & 0x40) >> 3) | + ((i & 0x20) >> 3) | + ((i & 0x08) >> 2) | + ((i & 0x02) >> 1); +#else + ctk_80col_lefttab[i] = + ((i & 0x40) << 1) | + ((i & 0x10) << 2) | + ((i & 0x04) << 3) | + ((i & 0x01) << 4); + ctk_80col_righttab[i] = + ((i & 0x40) >> 3) | + ((i & 0x10) >> 2) | + ((i & 0x04) >> 1) | + ((i & 0x01)); +#endif + } + +#if 0 + /* Setup mouse pointer sprite. */ + asm("lda %v+%w", ctk_80col_theme, + offsetof(struct ctk_80col_theme, pointermaskcolor)); + asm("sta $d027"); + asm("lda %v+%w", ctk_80col_theme, + offsetof(struct ctk_80col_theme, pointercolor)); + asm("sta $d028"); + + ptr1 = ctk_80col_theme.pointer; + ptr2 = (unsigned char *)0xff40; + + for(i = 0; i < 0x80; ++i) { + *ptr2++ = *ptr1++; + } +#endif + return; +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +/*static unsigned char cursx, cursy; + static unsigned char reversed;*/ + +/*-----------------------------------------------------------------------------------*/ +static void CC_FASTCALL +cputc(char c) +{ + /* ctk_arch_draw_char(c, cursx, cursy, reversed, 0);*/ + ctk_80col_cputc(c); + /* ++cursx;*/ +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +wherex(void) +{ + return ctk_80col_cursx; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +wherey(void) +{ + return ctk_80col_cursy; +} +/*-----------------------------------------------------------------------------------*/ +/*void +clrscr(void) +{ + unsigned char x, y; + + for(x = 0; x < SCREEN_WIDTH; ++x) { + for(y = 0; y < SCREEN_HEIGHT; ++y) { + gotoxy(x, y); + cputc(' '); + } + } +}*/ +/*-----------------------------------------------------------------------------------*/ +#define revers(c) ctk_80col_reversed = c +/*-----------------------------------------------------------------------------------*/ +static void CC_FASTCALL +_cputs(char *str) +{ + char *ptr = str; + + while(*ptr != 0) { + cputc(*ptr++); + } + + /* int i; + for(i = 0; i < strlen(str); ++i) { + cputc(str[i]); + }*/ +} +/*-----------------------------------------------------------------------------------*/ +static void CC_FASTCALL +cclear(unsigned char length) +{ + int i; + for(i = 0; i < length; ++i) { + cputc(' '); + } +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +chline(unsigned char length) +{ + int i; + for(i = 0; i < length; ++i) { + cputc('-'); + } +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +cvline(unsigned char length) +{ + int i; + for(i = 0; i < length; ++i) { + cputc('|'); + --ctk_80col_cursx; + ++ctk_80col_cursy; + } +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +gotoxy(unsigned char x, unsigned char y) +{ + ctk_80col_cursx = x; + ctk_80col_cursy = y; +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +cclearxy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + cclear(length); +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +chlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + chline(length); +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +cvlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + gotoxy(x, y); + cvline(length); +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +_cputsxy(unsigned char x, unsigned char y, char *str) +{ + gotoxy(x, y); + _cputs(str); +} +/*-----------------------------------------------------------------------------------*/ +void CC_FASTCALL +cputcxy(unsigned char x, unsigned char y, char c) +{ + gotoxy(x, y); + cputc(c); +} +/*-----------------------------------------------------------------------------------*/ +/*void CC_FASTCALL +screensize(unsigned char *x, unsigned char *y) +{ + *x = SCREEN_WIDTH; + *y = SCREEN_HEIGHT; +}*/ +/*-----------------------------------------------------------------------------------*/ +/*static unsigned char sizex, sizey;*/ +/*-----------------------------------------------------------------------------------*/ +static void +_cputsn(char *str, unsigned char len) +{ + /* char c; + + while(len > 0) { + --len; + c = *str; + if(c == 0) { + break; + } + cputc(c); + ++str; + }*/ + ctk_80col_cputsn(str, len); +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_init(void) +{ + ctk_80col_init(); + + /* screensize(&sizex, &sizey);*/ + + ctk_draw_clear(0, SCREEN_HEIGHT); +} +/*-----------------------------------------------------------------------------------*/ +static void +draw_widget(struct ctk_widget *w, + unsigned char x, unsigned char y, + unsigned char clipx, + unsigned char clipy, + unsigned char clipy1, unsigned char clipy2, + unsigned char focus) +{ + unsigned char xpos, ypos, xscroll; + unsigned char i, j; + char c, *text; + unsigned char len, wfocus; + + wfocus = 0; + if(focus & CTK_FOCUS_WINDOW) { + if(focus & CTK_FOCUS_WIDGET) { + wfocus = 1; + } + } else if(focus & CTK_FOCUS_DIALOG) { + if(focus & CTK_FOCUS_WIDGET) { + wfocus = 1; + } + } else { + } + + xpos = x + w->x; + ypos = y + w->y; + + switch(w->type) { + case CTK_WIDGET_SEPARATOR: + if(ypos >= clipy1 && ypos < clipy2) { + chlinexy(xpos, ypos, w->w); + } + break; + case CTK_WIDGET_LABEL: + text = w->widget.label.text; + for(i = 0; i < w->h; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + gotoxy(xpos, ypos); + _cputsn(text, w->w); + if(w->w - (wherex() - xpos) > 0) { + cclear(w->w - (wherex() - xpos)); + } + } + ++ypos; + text += w->w; + } + break; + case CTK_WIDGET_BUTTON: + if(ypos >= clipy1 && ypos < clipy2) { + if(wfocus != 0) { + revers(1); + } else { + revers(0); + } + cputcxy(xpos, ypos, '['); + _cputsn(w->widget.button.text, w->w); + cputc(']'); + revers(0); + } + break; + case CTK_WIDGET_HYPERLINK: + if(ypos >= clipy1 && ypos < clipy2) { + if(wfocus != 0) { + revers(0); + } else { + revers(1); + } + gotoxy(xpos, ypos); + _cputsn(w->widget.button.text, w->w); + revers(0); + } + break; + case CTK_WIDGET_TEXTENTRY: + text = w->widget.textentry.text; + xscroll = 0; + if(w->widget.textentry.xpos >= w->w - 1) { + xscroll = w->widget.textentry.xpos - w->w + 1; + } + for(j = 0; j < w->h; ++j) { + if(ypos >= clipy1 && ypos < clipy2) { + if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT && + w->widget.textentry.ypos == j) { + revers(0); + cputcxy(xpos, ypos, '>'); + for(i = 0; i < w->w; ++i) { + c = text[i + xscroll]; + if(i == w->widget.textentry.xpos - xscroll) { + revers(1); + } else { + revers(0); + } + if(c == 0) { + cputc(' '); + } else { + cputc(c); + } + revers(0); + } + cputc('<'); + } else { + if(wfocus != 0 && j == w->widget.textentry.ypos) { + revers(1); + } else { + revers(0); + } + cvlinexy(xpos, ypos, 1); + gotoxy(xpos + 1, ypos); + _cputsn(text, w->w); + i = wherex(); + if(i - xpos - 1 < w->w) { + cclear(w->w - (i - xpos) + 1); + } + cvline(1); + } + } + ++ypos; + text += w->widget.textentry.len + 1; + } + revers(0); + break; + case CTK_WIDGET_ICON: + if(ypos >= clipy1 && ypos < clipy2) { + color(ctk_80col_theme.iconcolors[focus]); + + /* if(focus & 1) { + + revers(1); + } else { + revers(0); + }*/ + /* gotoxy(xpos, ypos);*/ + if(xpos >= 73) { + xpos = 73; + } + if(xpos <= 2) { + xpos = 2; + } + if(w->widget.icon.textmap != NULL) { + ctk_80col_bitmapptr = w->widget.icon.bitmap; + for(i = 0; i < 3; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + gotoxy(xpos, ypos); + ctk_80col_draw_bitmapline(3); + } + ctk_80col_bitmapptr += 3 * 8; + ++ypos; + } + } + x = xpos; + + len = strlen(w->widget.icon.title); + if(x + len >= SCREEN_WIDTH) { + x = SCREEN_WIDTH - len; + } + + if(ypos >= clipy1 && ypos < clipy2) { + len = strlen(w->widget.icon.title); + gotoxy((x & 0xfe) + 1, ypos); + ctk_80col_cclear((len - 1)/ 2); + gotoxy(x, ypos); + ctk_80col_cputsn(w->widget.icon.title, len); + } + revers(0); + } + break; + + default: + break; + } +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_widget(struct ctk_widget *w, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + struct ctk_window *win = w->window; + unsigned char posx, posy; + + posx = (win->x & 0xfe) + 1; + posy = win->y + 2; + + if(w == win->focused) { + focus |= CTK_FOCUS_WIDGET; + } + + draw_widget(w, posx, posy, + posx + win->w, + posy + win->h, + clipy1, clipy2, + focus); + +#ifdef CTK_CONIO_CONF_UPDATE + CTK_CONIO_CONF_UPDATE(); +#endif /* CTK_CONIO_CONF_UPDATE */ +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_clear_window(struct ctk_window *window, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + unsigned char i; + unsigned char h; + + if(focus & CTK_FOCUS_WINDOW) { + color(COLOR_FOCUS_WINDOW); + } else { + color(COLOR_BACKGROUND_WINDOW); + } + + h = window->y + 2 + window->h; + /* Clear window contents. */ + for(i = window->y + 2; i < h; ++i) { + if(i >= clipy1 && i < clipy2) { + gotoxy((window->x & 0xfe) + 1, i); + ctk_80col_cclear((window->w + 1)/2); + } + } +} +/*-----------------------------------------------------------------------------------*/ +static void +draw_window_contents(struct ctk_window *window, unsigned char focus, + unsigned char clipy1, unsigned char clipy2, + unsigned char x1, unsigned char x2, + unsigned char y1, unsigned char y2) +{ + struct ctk_widget *w; + unsigned char wfocus; + + /* Draw inactive widgets. */ + for(w = window->inactive; w != NULL; w = w->next) { + draw_widget(w, x1, y1, x2, y2, + clipy1, clipy2, + focus); + } + + /* Draw active widgets. */ + for(w = window->active; w != NULL; w = w->next) { + wfocus = focus; + if(w == window->focused) { + wfocus |= CTK_FOCUS_WIDGET; + } + + draw_widget(w, x1, y1, x2, y2, + clipy1, clipy2, + wfocus); + } + +#ifdef CTK_CONIO_CONF_UPDATE + CTK_CONIO_CONF_UPDATE(); +#endif /* CTK_CONIO_CONF_UPDATE */ + +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_window(struct ctk_window *window, unsigned char focus, + unsigned char clipy1, unsigned char clipy2, + unsigned char draw_borders) +{ + unsigned char x, y; + unsigned char h; + unsigned char x1, y1, x2, y2; + + + if(window->y + 1 >= clipy2) { + return; + } + + x = window->x & 0xfe; + y = window->y + 1; + +/* if(focus & CTK_FOCUS_WINDOW) { + } else { + }*/ + + x1 = x + 1; + y1 = y + 1; + x2 = x1 + window->w; + y2 = y1 + window->h; + + /* Draw window frame. */ + gotoxy(x, y); + ctk_80col_windowparams.w = (window->w-1)/2; + ctk_80col_windowparams.h = window->h; + if(clipy1 < y) { + ctk_80col_windowparams.clipy1 = 0; + } else { + ctk_80col_windowparams.clipy1 = clipy1 - y; + } + ctk_80col_windowparams.clipy2 = clipy2 - y + 1; + ctk_80col_windowparams.color1 = ctk_80col_theme.windowcolors[focus]; + ctk_80col_windowparams.color2 = ctk_80col_theme.windowcolors[focus]; + ctk_80col_windowparams.titlecolor = ctk_80col_theme.windowcolors[focus+1]; + ctk_80col_windowparams.title = window->title; + ctk_80col_windowparams.titlelen = window->titlelen/2; + + if(ctk_80col_windowparams.clipy1 < ctk_80col_windowparams.clipy2 && + ctk_80col_windowparams.clipy2 > 0) { + ctk_80col_draw_windowborders(); + } + /* + if(y >= clipy1) { + cputcxy(x, y, CH_ULCORNER); + gotoxy(wherex() + window->titlelen + CTK_CONF_WINDOWMOVE * 2, wherey()); + chline(window->w - (wherex() - x) - 2); + cputcxy(x2, y, CH_URCORNER); + } + + h = window->h; + + if(clipy1 > y1) { + if(clipy1 - y1 < h) { + h = clipy1 - y1; + y1 = clipy1; + } else { + h = 0; + } + } + + if(clipy2 < y1 + h) { + if(y1 >= clipy2) { + h = 0; + } else { + h = clipy2 - y1; + } + } + + cvlinexy(x, y1, h); + cvlinexy(x2, y1, h); + + if(y + window->h >= clipy1 && + y + window->h < clipy2) { + cputcxy(x, y2, CH_LLCORNER); + chlinexy(x1, y2, window->w); + cputcxy(x2, y2, CH_LRCORNER); + } + */ + if(ctk_mode_get() != CTK_MODE_WINDOWMOVE) { + draw_window_contents(window, focus, clipy1, clipy2, + x1, x2, y + 1, y2); + } +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_dialog(struct ctk_window *dialog) +{ + unsigned char x, y; + unsigned char i; + unsigned char x1, y1, x2, y2; + + + x = dialog->x & 0xfe; + y = dialog->y + 1; + + + x1 = x + 1; + y1 = y + 1; + x2 = x1 + dialog->w; + y2 = y1 + dialog->h; + + + /* Draw dialog frame. */ + + /* cvlinexy(x, y1, + dialog->h); + cvlinexy(x2, y1, + dialog->h); + + chlinexy(x1, y, + dialog->w); + chlinexy(x1, y2, + dialog->w); + + cputcxy(x, y, CH_ULCORNER); + cputcxy(x, y2, CH_LLCORNER); + cputcxy(x2, y, CH_URCORNER); + cputcxy(x2, y2, CH_LRCORNER); + */ + gotoxy(x, y); + ctk_80col_windowparams.w = (dialog->w-1)/2; + ctk_80col_windowparams.h = dialog->h; + ctk_80col_windowparams.clipy1 = 0; + ctk_80col_windowparams.clipy2 = SCREEN_HEIGHT; + ctk_80col_windowparams.color1 = ctk_80col_theme.windowcolors[4]; + ctk_80col_windowparams.color2 = ctk_80col_theme.windowcolors[4]; + ctk_80col_windowparams.titlecolor = ctk_80col_theme.windowcolors[5]; + + ctk_80col_draw_windowborders(); + + /* Clear dialog contents. */ + color(COLOR_DIALOG); + for(i = y1; i < y2; ++i) { + gotoxy((x1 & 0xfe) + 2, i); + ctk_80col_cclear((dialog->w + 1)/2 - 2); + /* cclearxy(x1, i, dialog->w);*/ + } + + draw_window_contents(dialog, CTK_FOCUS_DIALOG, 0, SCREEN_HEIGHT, + x1, x2, y1, y2); +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_clear(unsigned char y1, unsigned char y2) +{ + unsigned char i; + + + for(i = y1; i < y2; ++i) { + + ctk_80col_clear_line(i); + } +} +/*-----------------------------------------------------------------------------------*/ +static void +draw_menu(struct ctk_menu *m) +{ + unsigned char x, x2, y; + + color(ctk_80col_theme.openmenucolor); + + revers(0); + x = wherex(); + _cputs(m->title); + cputc(' '); + x2 = wherex(); + if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) { + x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH - 2; + } + + for(y = 0; y < m->nitems; ++y) { + if(y == m->active) { + color(ctk_80col_theme.activemenucolor); + } else { + color(ctk_80col_theme.openmenucolor); + } + gotoxy(x, y + 1); + ctk_80col_cclear(CTK_CONF_MENUWIDTH/2); + + gotoxy(x, y + 1); + if(m->items[y].title[0] == '-') { + chline(CTK_CONF_MENUWIDTH); + } else { + /* _cputs(m->items[y].title);*/ + ctk_80col_cputsn(m->items[y].title, m->items[y].titlelen); + } + /* if(x + CTK_CONF_MENUWIDTH > wherex()) { + cclear(x + CTK_CONF_MENUWIDTH - wherex()); + }*/ + + } + gotoxy(x2, 0); + revers(1); + +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_menus(struct ctk_menus *menus) +{ + struct ctk_menu *m; + + memcpy((char *)0xe000, ctk_80col_theme.menuleftpattern, 8); + /* Draw menus */ + gotoxy(2, 0); + + revers(1); + for(m = menus->menus->next; m != NULL; m = m->next) { + color(ctk_80col_theme.menucolor); + if(m != menus->open) { + /* _cputs(m->title);*/ + ctk_80col_cputsn(m->title, m->titlelen); + cputc(' '); + } else { + draw_menu(m); + } + } + + color(ctk_80col_theme.menucolor); + + if(wherex() + strlen(menus->desktopmenu->title) + 2 >= SCREEN_WIDTH) { + gotoxy(SCREEN_WIDTH - strlen(menus->desktopmenu->title) - 2, 0); + } else { + cclear(SCREEN_WIDTH - wherex() - + strlen(menus->desktopmenu->title) - 2); + } + + /* Draw desktopmenu */ + if(menus->desktopmenu != menus->open) { + ctk_80col_cputsn(menus->desktopmenu->title, menus->desktopmenu->titlelen); + } else { + draw_menu(menus->desktopmenu); + } + + /* gotoxy(78, 0); + color(ctk_80col_screencolors[0]); + cputc(' '); + cputc(' '); */ + + revers(0); + memcpy((char *)0xe138, ctk_80col_theme.menurightpattern, 8); +} +/*-----------------------------------------------------------------------------------*/ +static unsigned char +s_ctk_draw_height(void) +{ + return SCREEN_HEIGHT; +} +/*-----------------------------------------------------------------------------------*/ +static unsigned char +s_ctk_draw_width(void) +{ + return SCREEN_WIDTH; +} +/*-----------------------------------------------------------------------------------*/ +static unsigned short +s_ctk_mouse_xtoc(unsigned short x) +{ + return x / 4; +} +/*-----------------------------------------------------------------------------------*/ +static unsigned short +s_ctk_mouse_ytoc(unsigned short y) +{ + return y / 8; +} +/*-----------------------------------------------------------------------------------*/ + +SERVICE(ctk_hires_service, ctk_draw_service, +{ 1, + 1, + 1, + s_ctk_draw_init, + s_ctk_draw_clear, + s_ctk_draw_clear_window, + s_ctk_draw_window, + s_ctk_draw_dialog, + s_ctk_draw_widget, + s_ctk_draw_menus, + s_ctk_draw_width, + s_ctk_draw_height, + s_ctk_mouse_xtoc, + s_ctk_mouse_ytoc }); + +/*--------------------------------------------------------------------------*/ + +PROCESS(ctk_hires_service_process, "CTK hires service"); + +PROCESS_THREAD(ctk_hires_service_process, ev, data) { + PROCESS_BEGIN(); + + s_ctk_draw_init(); + ctk_restore(); + + SERVICE_REGISTER(ctk_hires_service); + + while(ev != PROCESS_EVENT_SERVICE_REMOVED && + ev != PROCESS_EVENT_EXIT) { + PROCESS_WAIT_EVENT(); + } + + SERVICE_REMOVE(ctk_hires_service); + + VIC.ctrl1 = 0x1b; /* $D011 */ + VIC.addr = 0x17; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + CIA2.pra = 0x03; /* $DD00 */ + + PROCESS_END(); +} +/*--------------------------------------------------------------------------*/ diff --git a/platform/c64/ctk/ctk-arch.h b/platform/c64/ctk/ctk-arch.h new file mode 100644 index 000000000..2f8782875 --- /dev/null +++ b/platform/c64/ctk/ctk-arch.h @@ -0,0 +1,55 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-arch.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#ifndef __CTK_ARCH_H__ +#define __CTK_ARCH_H__ + +#if CTK_HIRES +#include "ctk-hires.h" +#endif + +#if CTK_CONIO +#include "ctk-conio.h" +#endif + +#if CTK_VNCSERVER +#include "ctk-vncarch.h" +#endif + +#include + +#define ctk_arch_isprint(c) isprint(c) + +#endif /* __CTK_ARCH_H__ */ diff --git a/platform/c64/ctk/ctk-hires-asm.h b/platform/c64/ctk/ctk-hires-asm.h new file mode 100644 index 000000000..5eb93fb60 --- /dev/null +++ b/platform/c64/ctk/ctk-hires-asm.h @@ -0,0 +1,70 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-hires-asm.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#ifndef __CTK_HIRES_ASM_H__ +#define __CTK_HIRES_ASM_H__ + +void __fastcall__ ctk_hires_cclear(unsigned char len); +void __fastcall__ ctk_hires_chline(unsigned char len); +void __fastcall__ ctk_hires_cputc(unsigned char c); +void __fastcall__ ctk_hires_cputsn(unsigned char *str, + unsigned char len); + +void ctk_hires_draw_buttonleft(void); +void ctk_hires_draw_buttonright(void); + +struct ctk_hires_windowparams { + unsigned char w; + unsigned char h; + unsigned char clipy1; + unsigned char clipy2; + unsigned char color1; + unsigned char color2; + unsigned char titlelen; + char *title; +}; +extern struct ctk_hires_windowparams ctk_hires_windowparams; +void ctk_hires_draw_windowborders(void); + +extern unsigned char ctk_hires_cursx, + ctk_hires_cursy, + ctk_hires_color, + ctk_hires_reversed, + ctk_hires_underline; + + +void __fastcall__ ctk_hires_draw_bitmapline(unsigned char len); + +#endif /* __CTK_HIRES_ASM_H__ */ diff --git a/platform/c64/ctk/ctk-hires-service.c b/platform/c64/ctk/ctk-hires-service.c new file mode 100644 index 000000000..fc0c2572f --- /dev/null +++ b/platform/c64/ctk/ctk-hires-service.c @@ -0,0 +1,925 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-hires-service.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "contiki-version.h" + +#include "ctk/ctk.h" +#include "ctk/ctk-draw.h" +#include "ctk/ctk-draw-service.h" + +#include "ctk-hires.h" +#include "ctk-hires-asm.h" +#include "ctk-hires-theme.h" + +#include + +#ifndef NULL +#define NULL (void *)0 +#endif /* NULL */ + +#define SCREEN_HEIGHT 25 +#define SCREEN_WIDTH 40 + +#define SCREENADDR 0xdc00 +#define HIRESADDR 0xe000 + +static unsigned char lineptr; + +unsigned char ctk_hires_cursx, ctk_hires_cursy; +unsigned char ctk_hires_reversed; +unsigned char ctk_hires_color; +unsigned char ctk_hires_underline; + +/*static unsigned char cchar; + +static unsigned char tmp01; +static unsigned char tmph, tmpl, tmpborder; +static unsigned char *tmpptr;*/ + + +static unsigned char x, y, i; +/*static unsigned char h;*/ +static unsigned char wfocus; +static unsigned char x1, y1, x2, y2; + +struct ctk_hires_windowparams ctk_hires_windowparams; +unsigned char *ctk_hires_bitmapptr; + +/*unsigned char ctk_draw_windowborder_height = 1; +unsigned char ctk_draw_windowborder_width = 1; +unsigned char ctk_draw_windowtitle_height = 1;*/ + +static void s_ctk_draw_clear(unsigned char y1, unsigned char y2); + + +/*-----------------------------------------------------------------------------------*/ +/* Tables. */ + +unsigned short ctk_hires_yscreenaddr[25] = + {0 * SCREEN_WIDTH + SCREENADDR, 1 * SCREEN_WIDTH + SCREENADDR, + 2 * SCREEN_WIDTH + SCREENADDR, 3 * SCREEN_WIDTH + SCREENADDR, + 4 * SCREEN_WIDTH + SCREENADDR, 5 * SCREEN_WIDTH + SCREENADDR, + 6 * SCREEN_WIDTH + SCREENADDR, 7 * SCREEN_WIDTH + SCREENADDR, + 8 * SCREEN_WIDTH + SCREENADDR, 9 * SCREEN_WIDTH + SCREENADDR, + 10 * SCREEN_WIDTH + SCREENADDR, 11 * SCREEN_WIDTH + SCREENADDR, + 12 * SCREEN_WIDTH + SCREENADDR, 13 * SCREEN_WIDTH + SCREENADDR, + 14 * SCREEN_WIDTH + SCREENADDR, 15 * SCREEN_WIDTH + SCREENADDR, + 16 * SCREEN_WIDTH + SCREENADDR, 17 * SCREEN_WIDTH + SCREENADDR, + 18 * SCREEN_WIDTH + SCREENADDR, 19 * SCREEN_WIDTH + SCREENADDR, + 20 * SCREEN_WIDTH + SCREENADDR, 21 * SCREEN_WIDTH + SCREENADDR, + 22 * SCREEN_WIDTH + SCREENADDR, 23 * SCREEN_WIDTH + SCREENADDR, + 24 * SCREEN_WIDTH + SCREENADDR}; + +unsigned short ctk_hires_yhiresaddr[25] = + {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR, + 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR, + 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR, + 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR, + 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR, + 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR, + 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR, + 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR, + 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR, + 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR, + 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR, + 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR, + 24 * 320 + HIRESADDR}; +extern struct ctk_hires_theme ctk_hires_theme; +struct ctk_hires_theme *ctk_hires_theme_ptr = &ctk_hires_theme; +/*-----------------------------------------------------------------------------------*/ +#define hires_wherex() ctk_hires_cursx +#define hires_revers(c) ctk_hires_reversed = c +#define hires_color(c) ctk_hires_color = c +#define hires_underline(c) ctk_hires_underline = c +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cvline(unsigned char length) +{ + static unsigned char i; + + for(i = 0; i < length; ++i) { + ctk_hires_cputc('|'); + --ctk_hires_cursx; + ++ctk_hires_cursy; + } +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_gotoxy(unsigned char x, unsigned char y) +{ + ctk_hires_cursx = x; + ctk_hires_cursy = y; +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cclearxy(unsigned char x, unsigned char y, unsigned char length) +{ + hires_gotoxy(x, y); + ctk_hires_cclear(length); +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_chlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + hires_gotoxy(x, y); + ctk_hires_chline(length); +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cvlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + hires_gotoxy(x, y); + hires_cvline(length); +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cputcxy(unsigned char x, unsigned char y, char c) +{ + hires_gotoxy(x, y); + ctk_hires_cputc(c); +} +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +clear_line(unsigned char line) +{ + lineptr = line; + asm("lda %v", lineptr); + asm("asl"); + asm("tax"); + asm("lda %v,x", ctk_hires_yhiresaddr); + asm("sta ptr2"); + asm("lda %v+1,x", ctk_hires_yhiresaddr); + asm("sta ptr2+1"); + asm("lda %v,x", ctk_hires_yscreenaddr); + asm("sta ptr1"); + asm("lda %v+1,x", ctk_hires_yscreenaddr); + asm("sta ptr1+1"); + + + asm("sei"); + asm("lda $01"); + asm("pha"); + asm("lda #$30"); + asm("sta $01"); + asm("ldy #39"); + asm("ldx %v", lineptr); + asm("lda %v+%w,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpatterncolors)); + asm("clearlineloop1:"); + asm("sta (ptr1),y"); + asm("dey"); + asm("bpl clearlineloop1"); + asm("pla"); + asm("sta $01"); + asm("cli"); + + + asm("lda %v", lineptr); + /* asm("and #7");*/ + asm("asl"); + asm("asl"); + asm("asl"); + asm("tax"); + asm("ldy #0"); + asm("clearlineloop2:"); + asm("lda %v+%w+0,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+1,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+2,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+3,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+4,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+5,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+6,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+7,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("bne clearlineloop2"); + + asm("inc ptr2+1"); + + asm("ldy #0"); + asm("clearlineloop3:"); + asm("lda %v+%w+0,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+1,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+2,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+3,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+4,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+5,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+6,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+7,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("cpy #$40"); + asm("bne clearlineloop3"); + + + if(lineptr == 24) { + hires_color(ctk_hires_theme.backgroundpatterncolors[24]); + hires_gotoxy(0, 24); + ctk_hires_cputsn(CONTIKI_VERSION_STRING, + sizeof(CONTIKI_VERSION_STRING) - 1); + } +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +nmi2(void) +{ + asm("pla"); + asm("sta $01"); + asm("pla"); + asm("rti"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +nmi(void) +{ + asm("sei"); + asm("pha"); + asm("inc $d020"); + asm("lda $01"); + asm("pha"); + asm("lda #$36"); + asm("sta $01"); + asm("lda #>_nmi2"); + asm("pha"); + asm("lda #<_nmi2"); + asm("pha"); + asm("php"); + asm("jmp ($0318)"); + + nmi2(); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +setup_nmi(void) +{ + asm("lda #<_nmi"); + asm("sta $fffa"); + asm("lda #>_nmi"); + asm("sta $fffb"); + return; + nmi(); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +s_ctk_draw_init(void) +{ + unsigned char i, *ptr1, *ptr2; + + + setup_nmi(); + + /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for + hires/colors. */ + VIC.ctrl1 = 0x3b; /* $D011 */ + VIC.addr = 0x78; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + CIA2.pra = 0x00; /* $DD00 */ + + VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */ + VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */ + + /* Fill color memory. */ + asm("sei"); + asm("lda $01"); + asm("pha"); + asm("lda #$30"); + asm("sta $01"); + asm("ldx #0"); + asm("lda #$c0"); + asm("fillcolorloop:"); + asm("sta $dc00,x"); + asm("sta $dd00,x"); + asm("sta $de00,x"); + asm("sta $df00,x"); + asm("inx"); + asm("bne fillcolorloop"); + + /* Setup sprite pointers */ + asm("ldx #$fd"); + asm("stx $dff8"); + asm("inx"); + asm("stx $dff9"); + asm("pla"); + asm("sta $01"); + asm("cli"); + + /* Fill hires memory with 0. */ + + asm("lda $fd"); + asm("pha"); + asm("lda $fe"); + asm("pha"); + asm("lda #0"); + asm("sta $fd"); + asm("lda #$e0"); + asm("sta $fe"); + asm("ldy #0"); + asm("lda #0"); + asm("clrscrnloop:"); + asm("lda #$55"); + asm("sta ($fd),y"); + asm("iny"); + asm("lda #$aa"); + asm("sta ($fd),y"); + asm("iny"); + asm("bne clrscrnloop"); + asm("inc $fe"); + asm("lda $fe"); + asm("cmp #$ff"); + asm("bne clrscrnloop"); + + asm("ldy #$00"); + asm("clrscrnloop2:"); + asm("lda #$55"); + asm("sta $ff00,y"); + asm("iny"); + asm("lda #$aa"); + asm("sta $ff00,y"); + asm("iny"); + asm("cpy #$40"); + asm("bne clrscrnloop2"); + + + asm("pla"); + asm("sta $fe"); + asm("pla"); + asm("sta $fd"); + + + s_ctk_draw_clear(0, SCREEN_HEIGHT); + + /* Setup mouse pointer sprite. */ + asm("lda %v+%w", ctk_hires_theme, + offsetof(struct ctk_hires_theme, pointermaskcolor)); + asm("sta $d027"); + asm("lda %v+%w", ctk_hires_theme, + offsetof(struct ctk_hires_theme, pointercolor)); + asm("sta $d028"); + + ptr1 = ctk_hires_theme.pointer; + ptr2 = (unsigned char *)0xff40; + + for(i = 0; i < 0x80; ++i) { + *ptr2++ = *ptr1++; + } + + return; +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +draw_widget(register struct ctk_widget *w, + unsigned char x, unsigned char y, + unsigned char clipy1, unsigned char clipy2, + unsigned char afocus) +{ + static unsigned char xpos, ypos, xscroll; + static unsigned char i; + static char c; + static unsigned char len; + static unsigned char tmp; + static unsigned char yclipped; + static unsigned char focus; + char *text; + + xpos = x + w->x; + ypos = y + w->y; + + yclipped = 0; + if(ypos >= clipy1 && ypos < clipy2) { + yclipped = 1; + } + focus = afocus; + + + switch(w->type) { + case CTK_WIDGET_SEPARATOR: + hires_color(ctk_hires_theme.separatorcolors[focus]); + if(yclipped) { + hires_chlinexy(xpos, ypos, w->w); + } + break; + case CTK_WIDGET_LABEL: + hires_color(ctk_hires_theme.labelcolors[focus]); + text = w->widget.label.text; + for(i = 0; i < w->h; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + hires_gotoxy(xpos, ypos); + ctk_hires_cputsn(text, w->w); + tmp = w->w - (hires_wherex() - xpos); + if(tmp > 0) { + ctk_hires_cclear(tmp); + } + } + ++ypos; + text += w->w; + } + break; + case CTK_WIDGET_BUTTON: + if(yclipped) { + hires_color(ctk_hires_theme.buttonleftcolors[focus]); + hires_gotoxy(xpos, ypos); + ctk_hires_draw_buttonleft(); + hires_color(ctk_hires_theme.buttoncolors[focus]); + hires_gotoxy(xpos + 1, ypos); + ctk_hires_cputsn(w->widget.button.text, w->w); + hires_color(ctk_hires_theme.buttonrightcolors[focus]); + ctk_hires_draw_buttonright(); + } + break; + case CTK_WIDGET_HYPERLINK: + if(yclipped) { + hires_color(ctk_hires_theme.hyperlinkcolors[focus]); + hires_underline(1); + hires_gotoxy(xpos, ypos); + ctk_hires_cputsn(w->widget.button.text, w->w); + hires_underline(0); + } + break; + case CTK_WIDGET_TEXTENTRY: + if(yclipped) { + hires_color(ctk_hires_theme.textentrycolors[focus]); + + if((focus & CTK_FOCUS_WIDGET) && + w->widget.textentry.state != CTK_TEXTENTRY_EDIT) { + hires_revers(1); + } else { + hires_revers(0); + } + xscroll = 0; + tmp = w->w - 1; + if(w->widget.textentry.xpos >= tmp) { + xscroll = w->widget.textentry.xpos - tmp; + } + text = w->widget.textentry.text; + if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) { + hires_revers(0); + hires_cputcxy(xpos, ypos, '>'); + text += xscroll; + for(i = 0; i < w->w; ++i) { + c = *text; + if(i == w->widget.textentry.xpos - xscroll) { + hires_revers(1); + } else { + hires_revers(0); + } + if(c == 0) { + ctk_hires_cputc(' '); + } else { + ctk_hires_cputc(c); + } + hires_revers(0); + ++text; + } + ctk_hires_cputc('<'); + } else { + hires_cputcxy(xpos, ypos, '|'); + /* hires_gotoxy(xpos + 1, ypos); */ + ctk_hires_cputsn(text, w->w); + i = hires_wherex(); + tmp = i - xpos - 1; + if(tmp < w->w) { + ctk_hires_cclear(w->w - tmp); + } + ctk_hires_cputc('|'); + } + } + hires_revers(0); + break; + case CTK_WIDGET_ICON: + if(yclipped) { + hires_color(ctk_hires_theme.iconcolors[focus]); + + x = xpos; + len = strlen(w->widget.icon.title); + if(x + len >= SCREEN_WIDTH) { + x = SCREEN_WIDTH - len; + } + + tmp = ypos + 3; + + if(tmp < clipy2) { + hires_gotoxy(x, tmp); + ctk_hires_cputsn(w->widget.icon.title, len); + } + + hires_gotoxy(xpos, ypos); + if(w->widget.icon.bitmap != NULL) { + ctk_hires_bitmapptr = w->widget.icon.bitmap; + for(i = 0; i < 3; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + hires_gotoxy(xpos, ypos); + ctk_hires_draw_bitmapline(3); + } + ctk_hires_bitmapptr += 3 * 8; + ++ypos; + } + + /* draw_bitmap_icon(w->widget.icon.bitmap);*/ + } + + } + break; + case CTK_WIDGET_BITMAP: + hires_color(ctk_hires_theme.bitmapcolors[focus]); + ctk_hires_bitmapptr = w->widget.bitmap.bitmap; + for(i = 0; i < w->h; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + hires_gotoxy(xpos, ypos); + ctk_hires_draw_bitmapline(w->w); + } + ctk_hires_bitmapptr += w->w * 8; + ++ypos; + } + break; + + default: + break; + } +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_widget(struct ctk_widget *w, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + struct ctk_window *win = w->window; + unsigned char posx, posy; + + posx = win->x + 1; + posy = win->y + 2; + + if(w == win->focused) { + focus |= CTK_FOCUS_WIDGET; + } + + draw_widget(w, posx, posy, + clipy1, clipy2, + focus); +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_clear_window(register struct ctk_window *window, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + static unsigned char h; + + hires_color(ctk_hires_theme.windowcolors[focus]); + + h = window->y + 2 + window->h; + /* Clear window contents. */ + for(i = window->y + 2; i < h; ++i) { + if(i >= clipy1 && i <= clipy2) { + hires_cclearxy(window->x + 1, i, window->w); + } + } +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_window(register struct ctk_window *window, + unsigned char focus, + unsigned char clipy1, unsigned char clipy2, + unsigned char draw_borders) +{ + register struct ctk_widget *w; + + x = window->x; + y = window->y + 1; + + ++clipy2; + + if(clipy2 <= y) { + return; + } + + /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/ + + x1 = x + 1; + y1 = y + 1; + /* x2 = x1 + window->w; + y2 = y1 + window->h;*/ + + hires_gotoxy(x, y); + ctk_hires_windowparams.w = window->w; + ctk_hires_windowparams.h = window->h; + if(clipy1 < y) { + ctk_hires_windowparams.clipy1 = 0; + } else { + ctk_hires_windowparams.clipy1 = clipy1 - y; + } + ctk_hires_windowparams.clipy2 = clipy2 - y; + ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1]; + ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus]; + ctk_hires_windowparams.title = window->title; + ctk_hires_windowparams.titlelen = window->titlelen; + + if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 && + ctk_hires_windowparams.clipy2 > 0) { + ctk_hires_draw_windowborders(); + } + + /* Draw inactive widgets. */ + for(w = window->inactive; w != NULL; w = w->next) { + draw_widget(w, x1, y1, + clipy1, clipy2, + focus); + } + + /* Draw active widgets. */ + for(w = window->active; w != NULL; w = w->next) { + wfocus = focus; + if(w == window->focused) { + wfocus |= CTK_FOCUS_WIDGET; + } + draw_widget(w, x1, y1, + clipy1, clipy2, + wfocus); + } +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_dialog(register struct ctk_window *dialog) +{ + register struct ctk_widget *w; + + hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]); + + /* x = (SCREEN_WIDTH - dialog->w) / 2; + y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */ + x = dialog->x; + y = dialog->y + 1; + + + x1 = x + 1; + y1 = y + 1; + x2 = x1 + dialog->w; + y2 = y1 + dialog->h; + + + /* Draw dialog frame. */ + + hires_cvlinexy(x, y1, dialog->h); + hires_cvlinexy(x2, y1, dialog->h); + + hires_chlinexy(x1, y, dialog->w); + hires_chlinexy(x1, y2, dialog->w); + + hires_cputcxy(x, y, CH_ULCORNER); + hires_cputcxy(x, y2, CH_LLCORNER); + hires_cputcxy(x2, y, CH_URCORNER); + hires_cputcxy(x2, y2, CH_LRCORNER); + + + /* Clear window contents. */ + for(i = y1; i < y2; ++i) { + hires_cclearxy(x1, i, dialog->w); + } + + /* Draw inactive widgets. */ + for(w = dialog->inactive; w != NULL; w = w->next) { + draw_widget(w, x1, y1, + 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG); + } + + + /* Draw active widgets. */ + for(w = dialog->active; w != NULL; w = w->next) { + wfocus = CTK_FOCUS_DIALOG; + if(w == dialog->focused) { + wfocus |= CTK_FOCUS_WIDGET; + } + draw_widget(w, x1, y1, + 0, SCREEN_HEIGHT, wfocus); + } + +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_clear(unsigned char y1, unsigned char y2) +{ + for(i = y1; i < y2; ++i) { + clear_line(i); + } +} +/*-----------------------------------------------------------------------------------*/ +static void +draw_menu(register struct ctk_menu *m) +{ + static unsigned char x, x2, y; + + hires_color(ctk_hires_theme.openmenucolor); + x = hires_wherex(); + ctk_hires_cputsn(m->title, m->titlelen); + ctk_hires_cputc(' '); + x2 = hires_wherex(); + if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) { + x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH; + } + for(y = 0; y < m->nitems; ++y) { + if(y == m->active) { + hires_color(ctk_hires_theme.activemenucolor); + } else { + hires_color(ctk_hires_theme.menucolor); + } + hires_gotoxy(x, y + 1); + if(m->items[y].title[0] == '-') { + ctk_hires_chline(CTK_CONF_MENUWIDTH); + } else { + ctk_hires_cputsn(m->items[y].title, + strlen(m->items[y].title)); + } + ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex()); + hires_revers(0); + } + hires_gotoxy(x2, 0); + hires_color(ctk_hires_theme.menucolor); +} +/*-----------------------------------------------------------------------------------*/ +static void +s_ctk_draw_menus(struct ctk_menus *menus) +{ + struct ctk_menu *m; + + /* Draw menus */ + hires_color(ctk_hires_theme.menucolor); + hires_gotoxy(0, 0); + hires_revers(0); + ctk_hires_cputc(' '); + for(m = menus->menus->next; m != NULL; m = m->next) { + if(m != menus->open) { + ctk_hires_cputsn(m->title, m->titlelen); + ctk_hires_cputc(' '); + } else { + draw_menu(m); + } + } + ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() - + strlen(menus->desktopmenu->title) - 1); + + /* Draw desktopmenu */ + if(menus->desktopmenu != menus->open) { + ctk_hires_cputsn(menus->desktopmenu->title, + menus->desktopmenu->titlelen); + ctk_hires_cputc(' '); + } else { + draw_menu(menus->desktopmenu); + } + +} +/*-----------------------------------------------------------------------------------*/ +static unsigned char +s_ctk_draw_height(void) +{ + return SCREEN_HEIGHT; +} +/*-----------------------------------------------------------------------------------*/ +static unsigned char +s_ctk_draw_width(void) +{ + return SCREEN_WIDTH; +} +/*-----------------------------------------------------------------------------------*/ +static unsigned short +s_ctk_mouse_xtoc(unsigned short x) +{ + return x / 8; +} +/*-----------------------------------------------------------------------------------*/ +static unsigned short +s_ctk_mouse_ytoc(unsigned short y) +{ + return y / 8; +} +/*-----------------------------------------------------------------------------------*/ + +SERVICE(ctk_hires_service, ctk_draw_service, +{ 1, + 1, + 1, + s_ctk_draw_init, + s_ctk_draw_clear, + s_ctk_draw_clear_window, + s_ctk_draw_window, + s_ctk_draw_dialog, + s_ctk_draw_widget, + s_ctk_draw_menus, + s_ctk_draw_width, + s_ctk_draw_height, + s_ctk_mouse_xtoc, + s_ctk_mouse_ytoc }); + +/*--------------------------------------------------------------------------*/ + +PROCESS(ctk_hires_service_process, "CTK hires service"); + +PROCESS_THREAD(ctk_hires_service_process, ev, data) { + PROCESS_BEGIN(); + + s_ctk_draw_init(); + ctk_restore(); + + SERVICE_REGISTER(ctk_hires_service); + + while(ev != PROCESS_EVENT_SERVICE_REMOVED && + ev != PROCESS_EVENT_EXIT) { + PROCESS_WAIT_EVENT(); + } + + SERVICE_REMOVE(ctk_hires_service); + + VIC.ctrl1 = 0x1b; /* $D011 */ + VIC.addr = 0x17; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + CIA2.pra = 0x03; /* $DD00 */ + + PROCESS_END(); +} +/*--------------------------------------------------------------------------*/ diff --git a/platform/c64/ctk/ctk-hires-theme-blueround.c b/platform/c64/ctk/ctk-hires-theme-blueround.c new file mode 100644 index 000000000..4ea2f8446 --- /dev/null +++ b/platform/c64/ctk/ctk-hires-theme-blueround.c @@ -0,0 +1,313 @@ + /* + * 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 for the C64 + * + * $Id: ctk-hires-theme-blueround.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include +#include "ctk-hires-theme.h" + +#define COLOR(bg, fg) ((fg << 4) | (bg)) + +#define BGCOLOR1 0x06 +#define BGCOLOR2 0x00 +#define BGCOLOR3 0x06 +#define BGCOLOR4 0x00 + +struct ctk_hires_theme ctk_hires_theme = + { + /* Version string. */ + /* char version[8]; */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* Window borders patterns. */ + /* unsigned char ulcorner[8], */ /* Upper left corner. */ + {0xfe,0xf8,0xe0,0xc0,0xc0,0x80,0x80,0x00}, + + /* titlebar[8], */ /* Title bar pattern. */ + {0x00,0x55,0xaa,0x00,0xaa,0x00,0x00,0x00}, + + /* urcorner[8], */ /* Upper right corner. */ + {0x7f,0x1f,0x07,0x03,0x03,0x01,0x01,0x00}, + + /* rightborder[8], */ /* Right border. */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* lrcorner[8], */ /* Lower right corner. */ + {0x00,0x01,0x01,0x03,0x03,0x07,0x1f,0x7f}, + + /* lowerborder[8], */ /* Lower border. */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* llcorner[8], */ /* Lower left corner. */ + {0x00,0x80,0x80,0xc0,0xc0,0xe0,0xf8,0xfe}, + + /* leftborder[8]; */ /* Left border. */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* Button corner patterns. */ + /* unsigned char buttonleft[8], */ + {0x03,0x0f,0x1f,0x1f,0x1f,0x1f,0x0f,0x03}, + + /* buttonright[8]; */ + {0xc0,0xf0,0xf8,0xf8,0xf8,0xf8,0xf0,0xc0}, + + /* Menu border patterns. */ + /* unsigned char menuleftpattern[8], */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* menurightpatterns[8]; */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* Window and widget colors. */ + /* unsigned char windowcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLACK), + COLOR(COLOR_BLACK, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE)}, + + /* separatorcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE)}, + + /* labelcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE)}, + + /* buttoncolors[6], */ + {COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLACK), + COLOR(COLOR_LIGHTBLUE, COLOR_CYAN), + COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_CYAN)}, + + /* hyperlinkcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_CYAN), + COLOR(COLOR_BLUE, COLOR_WHITE), + COLOR(COLOR_LIGHTBLUE, COLOR_CYAN), + COLOR(COLOR_LIGHTBLUE, COLOR_WHITE)}, + + /* textentrycolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_LIGHTBLUE), + COLOR(COLOR_BLACK, COLOR_LIGHTBLUE), + COLOR(COLOR_BLACK, COLOR_CYAN), + COLOR(COLOR_WHITE, COLOR_BLUE), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* bitmapcolors[6], */ + {COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLACK), + COLOR(COLOR_LIGHTBLUE, COLOR_CYAN), + COLOR(COLOR_LIGHTBLUE, COLOR_BLACK), + COLOR(COLOR_LIGHTBLUE, COLOR_CYAN)}, + + /* textmapcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE)}, + + /* iconcolors[6]; */ + {COLOR(COLOR_BLUE, COLOR_BLACK), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLACK), + COLOR(COLOR_LIGHTBLUE, COLOR_CYAN)}, + + + /* Button corner colors. */ + /* unsigned char buttonleftcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE)}, + + /* buttonrightcolors[6]; */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE), + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE)}, + + + /* Menu colors. */ + /* unsigned char menucolor,*/ + COLOR(COLOR_BLUE, COLOR_LIGHTBLUE), + + /* openmenucolor, */ + COLOR(COLOR_LIGHTBLUE, COLOR_BLUE), + + /* activemenucolor; */ + COLOR(COLOR_CYAN, COLOR_BLUE), + + /* Border and screen colors. */ + /* unsigned char bordercolor,*/ + 0, + + /* screencolor; */ + 0, + + /* Pointer sprite 0 color */ + /*unsigned char pointermaskcolor,*/ + 3, + + /* Pointer sprite 1 color */ + /* pointercolor; */ + 6, + + + /* Pointer sprite. */ + /* unsigned char pointer[128]; */ + {0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, + 0x60, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x78, 0x00, 0x00, + 0x7c, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x58, 0x00, 0x00, + 0x18, 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, + + 0xc0, 0x00, 0x00, + 0xe0, 0x00, 0x00, + 0xf0, 0x00, 0x00, + 0xf8, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0x3c, 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 }, + + + + /* Background pattern fill. */ + /* unsigned char backgroundpattern[8*25]; */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x10,0x38,0x10,0x00,0x00,0x00, + 0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x3c,0x18,0x00, + 0x00,0x3c,0x7e,0x7e,0x7e,0x7e,0x3c,0x00, + 0x3c,0x7e,0xff,0xff,0xff,0xff,0x7e,0x3c, + 0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0x7e, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x10,0x38,0x10,0x00,0x00,0x00, + 0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x3c,0x18,0x00, + 0x00,0x3c,0x7e,0x7e,0x7e,0x7e,0x3c,0x00, + 0x3c,0x7e,0xff,0xff,0xff,0xff,0x7e,0x3c, + 0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0x7e, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00, + 0x00,0x00,0x10,0x38,0x10,0x00,0x00,0x00, + 0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00, + 0x00,0x18,0x3c,0x7e,0x7e,0x3c,0x18,0x00, + 0x00,0x3c,0x7e,0x7e,0x7e,0x7e,0x3c,0x00, + 0x3c,0x7e,0xff,0xff,0xff,0xff,0x7e,0x3c, + 0x7e,0xff,0xff,0xff,0xff,0xff,0xff,0x7e, + + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + }, + + /* Background colors. */ + /* unsigned char backgroundpatterncolors[25]; */ + { + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + + COLOR(BGCOLOR2,BGCOLOR3),COLOR(BGCOLOR2,BGCOLOR3), + COLOR(BGCOLOR2,BGCOLOR3),COLOR(BGCOLOR2,BGCOLOR3), + COLOR(BGCOLOR2,BGCOLOR3),COLOR(BGCOLOR2,BGCOLOR3), + COLOR(BGCOLOR2,BGCOLOR3),COLOR(BGCOLOR2,BGCOLOR3), + + COLOR(BGCOLOR3,BGCOLOR4),COLOR(BGCOLOR3,BGCOLOR4), + COLOR(BGCOLOR3,BGCOLOR4),COLOR(BGCOLOR3,BGCOLOR4), + COLOR(BGCOLOR3,BGCOLOR4),COLOR(BGCOLOR3,BGCOLOR4), + COLOR(BGCOLOR3,BGCOLOR4),COLOR(BGCOLOR3,BGCOLOR4), + + COLOR(BGCOLOR4,BGCOLOR4)}, + + + + }; diff --git a/platform/c64/ctk/ctk-hires-theme-default.c b/platform/c64/ctk/ctk-hires-theme-default.c new file mode 100644 index 000000000..74e3aa604 --- /dev/null +++ b/platform/c64/ctk/ctk-hires-theme-default.c @@ -0,0 +1,303 @@ + /* + * 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 for the C64 + * + * $Id: ctk-hires-theme-default.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include +#include "ctk-hires-theme.h" + +#define COLOR(bg, fg) ((fg << 4) | (bg)) + +#define BGCOLOR1 7 +#define BGCOLOR2 10 +#define BGCOLOR3 4 +#define BGCOLOR4 6 + +struct ctk_hires_theme ctk_hires_theme = + { + /* Version string. */ + /* char version[8]; */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* Window borders patterns. */ + /* unsigned char ulcorner[8], */ /* Upper left corner. */ + {0xff,0xff,0xc0,0xcf,0xc0,0xc3,0xc0,0xc0}, + + /* titlebar[8], */ /* Title bar pattern. */ + {0xff,0xff,0x00,0xff,0x00,0xff,0x00,0x00}, + + /* urcorner[8], */ /* Upper right corner. */ + {0xff,0xfc,0x00,0xf0,0x00,0xc0,0x00,0x00}, + + /* rightborder[8], */ /* Right border. */ + {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b}, + + /* lrcorner[8], */ /* Lower right corner. */ + {0x0b,0x0b,0x0b,0x0b,0xfb,0x03,0xff,0xff}, + + /* lowerborder[8], */ /* Lower border. */ + {0x00,0x00,0x00,0x00,0xff,0x00,0xff,0xff}, + + /* llcorner[8], */ /* Lower left corner. */ + {0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x80,0x00}, + + /* leftborder[8]; */ /* Left border. */ + {0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0}, + + /* Button corner patterns. */ + /* unsigned char buttonleft[8], */ + {0xc5,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf}, + + /* buttonright[8]; */ + {0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xfb,0xa3}, + + /* Menu border patterns. */ + /* unsigned char menuleftpattern[8], */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* menurightpatterns[8]; */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* Window and widget colors. */ + /* unsigned char windowcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY3), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_WHITE), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* separatorcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_GRAY2), + COLOR(COLOR_GRAY3, COLOR_GRAY2), + COLOR(COLOR_WHITE, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_GRAY1)}, + + /* labelcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* buttoncolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY3), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY3)}, + + /* hyperlinkcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_WHITE, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_WHITE), + COLOR(COLOR_WHITE, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_WHITE)}, + + /* textentrycolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* bitmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* textmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* iconcolors[6]; */ + {COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_BLACK, COLOR_YELLOW), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_BLACK, COLOR_YELLOW)}, + + + /* Button corner colors. */ + /* unsigned char buttonleftcolors[6], */ + {COLOR(COLOR_GRAY3, COLOR_GRAY2), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_WHITE, COLOR_GRAY3), + COLOR(COLOR_GRAY1, COLOR_GRAY3), + COLOR(COLOR_WHITE, COLOR_GRAY3), + COLOR(COLOR_GRAY1, COLOR_GRAY3)}, + + /* buttonrightcolors[6]; */ + {COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY3, COLOR_GRAY2), + COLOR(COLOR_GRAY1, COLOR_GRAY3), + COLOR(COLOR_WHITE, COLOR_GRAY3), + COLOR(COLOR_GRAY1, COLOR_GRAY3), + COLOR(COLOR_WHITE, COLOR_GRAY3)}, + + + /* Menu colors. */ + /* unsigned char menucolor,*/ + COLOR(COLOR_YELLOW, COLOR_BLACK), + + /* openmenucolor, */ + COLOR(COLOR_BLACK, COLOR_YELLOW), + + /* activemenucolor; */ + COLOR(COLOR_WHITE, COLOR_BLACK), + + /* Border and screen colors. */ + /* unsigned char bordercolor,*/ + 6, + + /* screencolor; */ + 0, + + /* Pointer sprite 0 color */ + 0, + + /* Pointer sprite 1 color */ + 1, + + + /* Pointer sprite. */ + /* unsigned char pointer[128]; */ + {0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, + 0x60, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x78, 0x00, 0x00, + 0x7c, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x58, 0x00, 0x00, + 0x18, 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, + + 0xc0, 0x00, 0x00, + 0xe0, 0x00, 0x00, + 0xf0, 0x00, 0x00, + 0xf8, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0x3c, 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 }, + + + + /* Background pattern fill. */ + /* unsigned char backgroundpattern[8*25]; */ + {0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00}, + + /* Background colors. */ + /* unsigned char backgroundpatterncolors[25]; */ + {COLOR(BGCOLOR1,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3)}, + + + + }; diff --git a/platform/c64/ctk/ctk-hires-theme-enabler.c b/platform/c64/ctk/ctk-hires-theme-enabler.c new file mode 100644 index 000000000..eab78270c --- /dev/null +++ b/platform/c64/ctk/ctk-hires-theme-enabler.c @@ -0,0 +1,303 @@ + /* + * 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 for the C64 + * + * $Id: ctk-hires-theme-enabler.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include +#include "ctk-hires-theme.h" + +#define COLOR(bg, fg) ((fg << 4) | (bg)) + +#define BGCOLOR1 0x0f +#define BGCOLOR2 0x0c +#define BGCOLOR3 0x0b +#define BGCOLOR4 0x00 + +struct ctk_hires_theme ctk_hires_theme = + { + /* Version string. */ + /* char version[8]; */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* Window borders patterns. */ + /* unsigned char ulcorner[8], */ /* Upper left corner. */ + {0xff,0xfc,0xf0,0xf0,0xe0,0xe0,0xe0,0xe0}, + + /* titlebar[8], */ /* Title bar pattern. */ + {0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00}, + + /* urcorner[8], */ /* Upper right corner. */ + {0xff,0x3f,0x0f,0x0f,0x07,0x07,0x07,0x07}, + + /* rightborder[8], */ /* Right border. */ + {0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}, + + /* lrcorner[8], */ /* Lower right corner. */ + {0x07,0x07,0x0f,0x0f,0x3f,0xff,0xff,0xff}, + + /* lowerborder[8], */ /* Lower border. */ + {0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff}, + + /* llcorner[8], */ /* Lower left corner. */ + {0xe0,0xe0,0xf0,0xf0,0xfc,0xff,0xff,0xff}, + + /* leftborder[8]; */ /* Left border. */ + {0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0,0xe0}, + + /* Button corner patterns. */ + /* unsigned char buttonleft[8], */ + {0x03,0x0f,0x1f,0x1f,0x1f,0x1f,0x0f,0x03}, + + /* buttonright[8]; */ + {0xc0,0xf0,0xf8,0xf8,0xf8,0xf8,0xf0,0xc0}, + + /* Menu border patterns. */ + /* unsigned char menuleftpattern[8], */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* menurightpatterns[8]; */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* Window and widget colors. */ + /* unsigned char windowcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* separatorcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY2, COLOR_GRAY3), + COLOR(COLOR_GRAY2, COLOR_GRAY3), + COLOR(COLOR_WHITE, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_GRAY1)}, + + /* labelcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* buttoncolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY3), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY3)}, + + /* hyperlinkcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_GRAY2, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_GRAY2), + COLOR(COLOR_WHITE, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_WHITE)}, + + /* textentrycolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* bitmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* textmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* iconcolors[6]; */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY3, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GRAY3), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_BLACK, COLOR_YELLOW)}, + + + /* Button corner colors. */ + /* unsigned char buttonleftcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY1, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY3), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_GRAY3), + COLOR(COLOR_WHITE, COLOR_GRAY1)}, + + /* buttonrightcolors[6]; */ + {COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY1, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY3), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_GRAY3), + COLOR(COLOR_WHITE, COLOR_GRAY1)}, + + + /* Menu colors. */ + /* unsigned char menucolor,*/ + COLOR(COLOR_GRAY3, COLOR_BLACK), + + /* openmenucolor, */ + COLOR(COLOR_GRAY1, COLOR_GRAY3), + + /* activemenucolor; */ + COLOR(COLOR_WHITE, COLOR_BLACK), + + /* Border and screen colors. */ + /* unsigned char bordercolor,*/ + 0, + + /* screencolor; */ + 0, + + /* Pointer sprite 0 color */ + 0, + + /* Pointer sprite 1 color */ + 1, + + + /* Pointer sprite. */ + /* unsigned char pointer[128]; */ + {0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, + 0x60, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x78, 0x00, 0x00, + 0x7c, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x58, 0x00, 0x00, + 0x18, 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, + + 0xc0, 0x00, 0x00, + 0xe0, 0x00, 0x00, + 0xf0, 0x00, 0x00, + 0xf8, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0x3c, 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 }, + + + + /* Background pattern fill. */ + /* unsigned char backgroundpattern[8*25]; */ + {0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00, + 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, + 0xff,0xdd,0xff,0x77,0xff,0xdd,0xff,0x77, + 0xff,0x55,0xff,0x55,0xff,0x55,0xff,0x55, + 0xee,0x55,0xbb,0x55,0xee,0x55,0xbb,0x55, + 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, + 0xaa,0x44,0xaa,0x11,0xaa,0x44,0xaa,0x11, + 0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00, + 0x88,0x00,0x22,0x00,0x88,0x00,0x22,0x00}, + + /* Background colors. */ + /* unsigned char backgroundpatterncolors[25]; */ + {COLOR(BGCOLOR1,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR2,BGCOLOR1),COLOR(BGCOLOR2,BGCOLOR1), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR3,BGCOLOR2),COLOR(BGCOLOR3,BGCOLOR2), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3), + COLOR(BGCOLOR4,BGCOLOR3),COLOR(BGCOLOR4,BGCOLOR3)}, + + + + }; diff --git a/platform/c64/ctk/ctk-hires-theme-ravenpine.c b/platform/c64/ctk/ctk-hires-theme-ravenpine.c new file mode 100644 index 000000000..7c0874c90 --- /dev/null +++ b/platform/c64/ctk/ctk-hires-theme-ravenpine.c @@ -0,0 +1,288 @@ + /* + * 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 for the C64 + * + * $Id: ctk-hires-theme-ravenpine.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include +#include "ctk-hires-theme.h" + +#define COLOR(bg, fg) ((fg << 4) | (bg)) + +#define BGCOLOR1 0x00 +#define BGCOLOR2 0x05 + + +struct ctk_hires_theme ctk_hires_theme = + { + /* Version string. */ + /* char version[8]; */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* Window borders patterns. */ + /* unsigned char ulcorner[8], */ /* Upper left corner. */ + {0x00,0x3f,0x3f,0x30,0x30,0x30,0x30,0x30}, + + /* titlebar[8], */ /* Title bar pattern. */ + {0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00}, + + /* urcorner[8], */ /* Upper right corner. */ + {0x00,0xfc,0xfc,0x0c,0x0c,0x0c,0x0c,0x0c}, + + /* rightborder[8], */ /* Right border. */ + {0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c}, + + /* lrcorner[8], */ /* Lower right corner. */ + {0x0c,0x0c,0x0c,0x0c,0x0c,0xfc,0xfc,0x00}, + + /* lowerborder[8], */ /* Lower border. */ + {0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00}, + + /* llcorner[8], */ /* Lower left corner. */ + {0x30,0x30,0x30,0x30,0x30,0x3f,0x3f,0x00}, + + /* leftborder[8]; */ /* Left border. */ + {0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30}, + + /* Button corner patterns. */ + /* unsigned char buttonleft[8], */ + {0x3e,0x30,0x30,0x30,0x30,0x30,0x30,0x3c}, + + /* buttonright[8]; */ + {0x1c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c}, + + /* Menu border patterns. */ + /* unsigned char menuleftpattern[8], */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* menurightpatterns[8]; */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* Window and widget colors. */ + /* unsigned char windowcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK)}, + + /* separatorcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK)}, + + /* labelcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK)}, + + /* buttoncolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_WHITE)}, + + /* hyperlinkcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_BLACK, COLOR_BLUE), + COLOR(COLOR_GREEN, COLOR_LIGHTBLUE), + COLOR(COLOR_LIGHTGREEN, COLOR_BLUE), + COLOR(COLOR_LIGHTGREEN, COLOR_LIGHTBLUE)}, + + /* textentrycolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_BLACK, COLOR_LIGHTGREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_WHITE)}, + + + /* bitmapcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_WHITE)}, + + + /* textmapcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_WHITE)}, + + /* iconcolors[6]; */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_WHITE)}, + + + /* Button corner colors. */ + /* unsigned char buttonleftcolors[6], */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_WHITE)}, + + /* buttonrightcolors[6]; */ + {COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GRAY1), + COLOR(COLOR_BLACK, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_WHITE)}, + + + /* Menu colors. */ + /* unsigned char menucolor,*/ + COLOR(COLOR_GREEN, COLOR_BLACK), + + /* openmenucolor, */ + COLOR(COLOR_BLACK, COLOR_GREEN), + + /* activemenucolor; */ + COLOR(COLOR_LIGHTGREEN, COLOR_GREEN), + + /* Border and screen colors. */ + /* unsigned char bordercolor,*/ + 0, + + /* screencolor; */ + 0, + + /* Pointer sprite 0 color */ + COLOR_LIGHTGREEN, + + /* Pointer sprite 1 color */ + COLOR_GREEN, + + + /* Pointer sprite. */ + /* unsigned char pointer[128]; */ + {0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, + 0x60, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x78, 0x00, 0x00, + 0x7c, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x58, 0x00, 0x00, + 0x18, 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, + + 0xc0, 0x00, 0x00, + 0xe0, 0x00, 0x00, + 0xf0, 0x00, 0x00, + 0xf8, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0x3c, 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 }, + + + + /* Background pattern fill. */ + /* unsigned char backgroundpattern[8*25]; */ + { + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0, + }, + /* Background colors. */ + /* unsigned char backgroundpatterncolors[25]; */ + {COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2)}, + + + + }; diff --git a/platform/c64/ctk/ctk-hires-theme-springlight.c b/platform/c64/ctk/ctk-hires-theme-springlight.c new file mode 100644 index 000000000..43df3cee7 --- /dev/null +++ b/platform/c64/ctk/ctk-hires-theme-springlight.c @@ -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 for the C64 + * + * $Id: ctk-hires-theme-springlight.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include +#include "ctk-hires-theme.h" + +#define COLOR(bg, fg) ((fg << 4) | (bg)) + +#define BGCOLOR1 0x05 +#define BGCOLOR2 0x0d + + +struct ctk_hires_theme ctk_hires_theme = + { + /* Version string. */ + /* char version[8]; */ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + + /* Window borders patterns. */ + /* unsigned char ulcorner[8], */ /* Upper left corner. */ + {0x00,0x3f,0x6a,0x40,0x60,0x40,0x60,0x40}, + + /* titlebar[8], */ /* Title bar pattern. */ + {0x00,0xff,0xaa,0x00,0x00,0x00,0x00,0x00}, + + /* urcorner[8], */ /* Upper right corner. */ + {0x00,0xf0,0x20,0x00,0x00,0x00,0x00,0x00}, + + /* rightborder[8], */ /* Right border. */ + {0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02}, + + /* lrcorner[8], */ /* Lower right corner. */ + {0x02,0x02,0x02,0x02,0x02,0x06,0xfc,0x00}, + + /* lowerborder[8], */ /* Lower border. */ + {0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00}, + + /* llcorner[8], */ /* Lower left corner. */ + {0x60,0x40,0x40,0x40,0x00,0x00,0x00,0x00}, + + /* leftborder[8]; */ /* Left border. */ + {0x60,0x40,0x60,0x40,0x60,0x40,0x60,0x40}, + + /* Button corner patterns. */ + /* unsigned char buttonleft[8], */ + {0x0f,0x18,0x10,0x10,0x10,0x10,0x10,0x00}, + + /* buttonright[8]; */ + {0x00,0x08,0x08,0x08,0x08,0x08,0x18,0xf0}, + + /* Menu border patterns. */ + /* unsigned char menuleftpattern[8], */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* menurightpatterns[8]; */ + {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}, + + /* Window and widget colors. */ + /* unsigned char windowcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY1, COLOR_GREEN), + COLOR(COLOR_GREEN, COLOR_GRAY1), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK)}, + + /* separatorcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GRAY1, COLOR_GRAY2), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_GRAY1), + COLOR(COLOR_LIGHTGREEN, COLOR_GRAY1)}, + + /* labelcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK)}, + + /* buttoncolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY1, COLOR_GREEN), + COLOR(COLOR_GREEN, COLOR_GRAY1), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_GRAY2), + COLOR(COLOR_LIGHTGREEN, COLOR_WHITE)}, + + /* hyperlinkcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_GRAY2, COLOR_LIGHTBLUE), + COLOR(COLOR_GREEN, COLOR_CYAN), + COLOR(COLOR_GREEN, COLOR_BLUE), + COLOR(COLOR_LIGHTGREEN, COLOR_BLUE), + COLOR(COLOR_BLUE, COLOR_LIGHTGREEN)}, + + /* textentrycolors[6], */ + {COLOR(COLOR_GREEN, COLOR_GRAY1), + COLOR(COLOR_GREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_LIGHTGREEN, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* bitmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_GRAY1), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK), + COLOR(COLOR_GRAY3, COLOR_BLACK)}, + + /* textmapcolors[6], */ + {COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_GRAY2, COLOR_GRAY1), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_WHITE, COLOR_BLACK)}, + + /* iconcolors[6]; */ + {COLOR(COLOR_GREEN, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_GREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_GRAY1), + COLOR(COLOR_GRAY1, COLOR_LIGHTGREEN), + COLOR(COLOR_WHITE, COLOR_BLACK), + COLOR(COLOR_BLACK, COLOR_YELLOW)}, + + + /* Button corner colors. */ + /* unsigned char buttonleftcolors[6], */ + {COLOR(COLOR_GRAY1, COLOR_GREEN), + COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_GREEN, COLOR_GRAY1), + COLOR(COLOR_LIGHTGREEN, COLOR_WHITE), + COLOR(COLOR_LIGHTGREEN, COLOR_GRAY2)}, + + /* buttonrightcolors[6]; */ + {COLOR(COLOR_GRAY1, COLOR_BLACK), + COLOR(COLOR_GRAY1, COLOR_GREEN), + COLOR(COLOR_GREEN, COLOR_GRAY1), + COLOR(COLOR_GREEN, COLOR_LIGHTGREEN), + COLOR(COLOR_LIGHTGREEN, COLOR_GRAY2), + COLOR(COLOR_LIGHTGREEN, COLOR_WHITE)}, + + + /* Menu colors. */ + /* unsigned char menucolor,*/ + COLOR(COLOR_LIGHTGREEN, COLOR_GRAY1), + + /* openmenucolor, */ + COLOR(COLOR_BLACK, COLOR_GREEN), + + /* activemenucolor; */ + COLOR(COLOR_BLACK, COLOR_LIGHTGREEN), + + /* Border and screen colors. */ + /* unsigned char bordercolor,*/ + 5, + + /* screencolor; */ + 0, + + /* Pointer sprite 0 color */ + COLOR_WHITE, + + /* Pointer sprite 1 color */ + COLOR_GREEN, + + + /* Pointer sprite. */ + /* unsigned char pointer[128]; */ + {0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, + 0x60, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x78, 0x00, 0x00, + 0x7c, 0x00, 0x00, + 0x70, 0x00, 0x00, + 0x58, 0x00, 0x00, + 0x18, 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, + + 0xc0, 0x00, 0x00, + 0xe0, 0x00, 0x00, + 0xf0, 0x00, 0x00, + 0xf8, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfe, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0xfc, 0x00, 0x00, + 0x3c, 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 }, + + + + /* Background pattern fill. */ + /* unsigned char backgroundpattern[8*25]; */ + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 223, 255, 255, 247, 255, 255, 191, 247, 255, 255, 219, 255, 255, 187, +255, 239, 251, 191, 239, 253, 223, 251, 223, 253, 183, 255, 213, 127, 237, 191, +245, 95, 245, 223, 181, 255, 85, 255, 85, 219, 118, 219, 109, 219, 182, 109, 219, 182, 109, 219, 170, 109, 219, 170, 181, 173, 85, 218, 85, 173, 170, 85, 170, 85, 170, 85, 170, 85, 170, 85, 170, 146, 85, 146, 170, 82, 138, 50, 74, 164, 73, +146, 84, 137, 82, 4, 169, 18, 164, 2, 168, 18, 68, 18, 160, 10, 32, 74, 0, 42, 128, 18, 64, 20, 0, 82, 0, 4, 80, 4, 0, 72, 2, 0, 16, 132, 0, 0, 72, 0, 0, 4, 64, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + + /* Background colors. */ + /* unsigned char backgroundpatterncolors[25]; */ + {COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2), + COLOR(BGCOLOR1,BGCOLOR2),COLOR(BGCOLOR1,BGCOLOR2)}, + + + + }; diff --git a/platform/c64/ctk/ctk-hires-theme.h b/platform/c64/ctk/ctk-hires-theme.h new file mode 100644 index 000000000..34e2406a7 --- /dev/null +++ b/platform/c64/ctk/ctk-hires-theme.h @@ -0,0 +1,105 @@ + /* + * 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 for the C64 + * + * $Id: ctk-hires-theme.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ +#ifndef __CTK_HIRES_THEME_H__ +#define __CTK_HIRES_THEME_H__ + +struct ctk_hires_theme { + /* Version string. */ + char version[8]; + + /* Window borders patterns. */ + unsigned char ulcorner[8], /* Upper left corner. */ + titlebar[8], /* Title bar pattern. */ + urcorner[8], /* Upper right corner. */ + rightborder[8], /* Right border. */ + lrcorner[8], /* Lower right corner. */ + lowerborder[8], /* Lower border. */ + llcorner[8], /* Lower left corner. */ + leftborder[8]; /* Left border. */ + + /* Button corner patterns. */ + unsigned char buttonleftpattern[8], + buttonrightpattern[8]; + + /* Menu border patterns. */ + unsigned char menuleftpattern[8], + menurightpatterns[8]; + + + + /* Window and widget colors. */ + unsigned char windowcolors[6], + separatorcolors[6], + labelcolors[6], + buttoncolors[6], + hyperlinkcolors[6], + textentrycolors[6], + bitmapcolors[6], + textmapcolors[6], + iconcolors[6]; + + + /* Button corner colors. */ + unsigned char buttonleftcolors[6], + buttonrightcolors[6]; + + /* Menu colors. */ + unsigned char menucolor, + openmenucolor, + activemenucolor; + + /* Border and screen colors. */ + unsigned char bordercolor, + screencolor; + + /* Pointer sprite colors. */ + unsigned char pointermaskcolor, + pointercolor; + + /* Pointer sprite. */ + unsigned char pointer[128]; + + /* Background pattern fill. */ + unsigned char backgroundpattern[8*25]; + + /* Background colors. */ + unsigned char backgroundpatterncolors[25]; + +}; + +extern struct ctk_hires_theme ctk_hires_theme; +extern struct ctk_hires_theme *ctk_hires_theme_ptr; + +#endif /* __CTK_HIRES_THEME_H__ */ diff --git a/platform/c64/ctk/ctk-hires.c b/platform/c64/ctk/ctk-hires.c new file mode 100644 index 000000000..3b94735be --- /dev/null +++ b/platform/c64/ctk/ctk-hires.c @@ -0,0 +1,871 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-hires.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "contiki-version.h" + +#include "ctk/ctk.h" +#include "ctk-draw.h" +#include "ctk-hires.h" +#include "ctk-hires-asm.h" + +#include "ctk-hires-theme.h" + +#include +#include + +#ifndef NULL +#define NULL (void *)0 +#endif /* NULL */ + +#define SCREEN_HEIGHT 25 +#define SCREEN_WIDTH 40 + +#define SCREENADDR 0xdc00 +#define HIRESADDR 0xe000 + +static unsigned char lineptr; + +unsigned char ctk_hires_cursx, ctk_hires_cursy; +unsigned char ctk_hires_reversed; +unsigned char ctk_hires_color; +unsigned char ctk_hires_underline; + +/*static unsigned char cchar; + +static unsigned char tmp01; +static unsigned char tmph, tmpl, tmpborder; +static unsigned char *tmpptr;*/ + + +static unsigned char x, y, i; +/*static unsigned char h;*/ +static unsigned char wfocus; +static unsigned char x1, y1, x2, y2; + +struct ctk_hires_windowparams ctk_hires_windowparams; +unsigned char *ctk_hires_bitmapptr; + +unsigned char ctk_draw_windowborder_height = 1; +unsigned char ctk_draw_windowborder_width = 1; +unsigned char ctk_draw_windowtitle_height = 1; + +/*-----------------------------------------------------------------------------------*/ +/* Tables. */ + +unsigned short ctk_hires_yscreenaddr[25] = + {0 * SCREEN_WIDTH + SCREENADDR, 1 * SCREEN_WIDTH + SCREENADDR, + 2 * SCREEN_WIDTH + SCREENADDR, 3 * SCREEN_WIDTH + SCREENADDR, + 4 * SCREEN_WIDTH + SCREENADDR, 5 * SCREEN_WIDTH + SCREENADDR, + 6 * SCREEN_WIDTH + SCREENADDR, 7 * SCREEN_WIDTH + SCREENADDR, + 8 * SCREEN_WIDTH + SCREENADDR, 9 * SCREEN_WIDTH + SCREENADDR, + 10 * SCREEN_WIDTH + SCREENADDR, 11 * SCREEN_WIDTH + SCREENADDR, + 12 * SCREEN_WIDTH + SCREENADDR, 13 * SCREEN_WIDTH + SCREENADDR, + 14 * SCREEN_WIDTH + SCREENADDR, 15 * SCREEN_WIDTH + SCREENADDR, + 16 * SCREEN_WIDTH + SCREENADDR, 17 * SCREEN_WIDTH + SCREENADDR, + 18 * SCREEN_WIDTH + SCREENADDR, 19 * SCREEN_WIDTH + SCREENADDR, + 20 * SCREEN_WIDTH + SCREENADDR, 21 * SCREEN_WIDTH + SCREENADDR, + 22 * SCREEN_WIDTH + SCREENADDR, 23 * SCREEN_WIDTH + SCREENADDR, + 24 * SCREEN_WIDTH + SCREENADDR}; + +unsigned short ctk_hires_yhiresaddr[25] = + {0 * 320 + HIRESADDR, 1 * 320 + HIRESADDR, + 2 * 320 + HIRESADDR, 3 * 320 + HIRESADDR, + 4 * 320 + HIRESADDR, 5 * 320 + HIRESADDR, + 6 * 320 + HIRESADDR, 7 * 320 + HIRESADDR, + 8 * 320 + HIRESADDR, 9 * 320 + HIRESADDR, + 10 * 320 + HIRESADDR, 11 * 320 + HIRESADDR, + 12 * 320 + HIRESADDR, 13 * 320 + HIRESADDR, + 14 * 320 + HIRESADDR, 15 * 320 + HIRESADDR, + 16 * 320 + HIRESADDR, 17 * 320 + HIRESADDR, + 18 * 320 + HIRESADDR, 19 * 320 + HIRESADDR, + 20 * 320 + HIRESADDR, 21 * 320 + HIRESADDR, + 22 * 320 + HIRESADDR, 23 * 320 + HIRESADDR, + 24 * 320 + HIRESADDR}; +extern struct ctk_hires_theme ctk_hires_theme; +struct ctk_hires_theme *ctk_hires_theme_ptr = &ctk_hires_theme; +/*-----------------------------------------------------------------------------------*/ +#define hires_wherex() ctk_hires_cursx +#define hires_revers(c) ctk_hires_reversed = c +#define hires_color(c) ctk_hires_color = c +#define hires_underline(c) ctk_hires_underline = c +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cvline(unsigned char length) +{ + static unsigned char i; + + for(i = 0; i < length; ++i) { + ctk_hires_cputc('|'); + --ctk_hires_cursx; + ++ctk_hires_cursy; + } +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_gotoxy(unsigned char x, unsigned char y) +{ + ctk_hires_cursx = x; + ctk_hires_cursy = y; +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cclearxy(unsigned char x, unsigned char y, unsigned char length) +{ + hires_gotoxy(x, y); + ctk_hires_cclear(length); +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_chlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + hires_gotoxy(x, y); + ctk_hires_chline(length); +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cvlinexy(unsigned char x, unsigned char y, unsigned char length) +{ + hires_gotoxy(x, y); + hires_cvline(length); +} +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +hires_cputcxy(unsigned char x, unsigned char y, char c) +{ + hires_gotoxy(x, y); + ctk_hires_cputc(c); +} +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +clear_line(unsigned char line) +{ + lineptr = line; + asm("lda %v", lineptr); + asm("asl"); + asm("tax"); + asm("lda %v,x", ctk_hires_yhiresaddr); + asm("sta ptr2"); + asm("lda %v+1,x", ctk_hires_yhiresaddr); + asm("sta ptr2+1"); + asm("lda %v,x", ctk_hires_yscreenaddr); + asm("sta ptr1"); + asm("lda %v+1,x", ctk_hires_yscreenaddr); + asm("sta ptr1+1"); + + + asm("sei"); + asm("lda $01"); + asm("pha"); + asm("lda #$30"); + asm("sta $01"); + asm("ldy #39"); + asm("ldx %v", lineptr); + asm("lda %v+%w,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpatterncolors)); + asm("clearlineloop1:"); + asm("sta (ptr1),y"); + asm("dey"); + asm("bpl clearlineloop1"); + asm("pla"); + asm("sta $01"); + asm("cli"); + + + asm("lda %v", lineptr); + /* asm("and #7");*/ + asm("asl"); + asm("asl"); + asm("asl"); + asm("tax"); + asm("ldy #0"); + asm("clearlineloop2:"); + asm("lda %v+%w+0,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+1,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+2,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+3,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+4,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+5,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+6,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+7,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("bne clearlineloop2"); + + asm("inc ptr2+1"); + + asm("ldy #0"); + asm("clearlineloop3:"); + asm("lda %v+%w+0,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+1,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+2,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+3,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+4,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+5,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+6,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("lda %v+%w+7,x", ctk_hires_theme, + offsetof(struct ctk_hires_theme, backgroundpattern)); + asm("sta (ptr2),y"); + asm("iny"); + asm("cpy #$40"); + asm("bne clearlineloop3"); + + + if(lineptr == 24) { + hires_color(ctk_hires_theme.backgroundpatterncolors[24]); + hires_gotoxy(0, 24); + ctk_hires_cputsn(CONTIKI_VERSION_STRING, + sizeof(CONTIKI_VERSION_STRING) - 1); + } +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +nmi2(void) +{ + asm("pla"); + asm("sta $01"); + asm("pla"); + asm("rti"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +nmi(void) +{ + asm("sei"); + asm("pha"); + asm("inc $d020"); + asm("lda $01"); + asm("pha"); + asm("lda #$36"); + asm("sta $01"); + asm("lda #>_nmi2"); + asm("pha"); + asm("lda #<_nmi2"); + asm("pha"); + asm("php"); + asm("jmp ($0318)"); + + nmi2(); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +setup_nmi(void) +{ + asm("lda #<_nmi"); + asm("sta $fffa"); + asm("lda #>_nmi"); + asm("sta $fffb"); + return; + nmi(); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +ctk_draw_init(void) +{ + unsigned char i, *ptr1, *ptr2; + + + setup_nmi(); + + /* Turn on hires mode, bank 0 ($c000 - $ffff) and $e000/$c000 for + hires/colors. */ + VIC.ctrl1 = 0x3b; /* $D011 */ + VIC.addr = 0x78; /* $D018 */ + VIC.ctrl2 = 0xc8; /* $D016 */ + CIA2.pra = 0x00; /* $DD00 */ + + VIC.bordercolor = ctk_hires_theme.bordercolor; /* $D020 */ + VIC.bgcolor0 = ctk_hires_theme.screencolor; /* $D021 */ + + /* Fill color memory. */ + asm("sei"); + asm("lda $01"); + asm("pha"); + asm("lda #$30"); + asm("sta $01"); + asm("ldx #0"); + asm("lda #$c0"); + asm("fillcolorloop:"); + asm("sta $dc00,x"); + asm("sta $dd00,x"); + asm("sta $de00,x"); + asm("sta $df00,x"); + asm("inx"); + asm("bne fillcolorloop"); + + /* Setup sprite pointers */ + asm("ldx #$fd"); + asm("stx $dff8"); + asm("inx"); + asm("stx $dff9"); + asm("pla"); + asm("sta $01"); + asm("cli"); + + /* Fill hires memory with 0. */ + + asm("lda $fd"); + asm("pha"); + asm("lda $fe"); + asm("pha"); + asm("lda #0"); + asm("sta $fd"); + asm("lda #$e0"); + asm("sta $fe"); + asm("ldy #0"); + asm("lda #0"); + asm("clrscrnloop:"); + asm("lda #$55"); + asm("sta ($fd),y"); + asm("iny"); + asm("lda #$aa"); + asm("sta ($fd),y"); + asm("iny"); + asm("bne clrscrnloop"); + asm("inc $fe"); + asm("lda $fe"); + asm("cmp #$ff"); + asm("bne clrscrnloop"); + + asm("ldy #$00"); + asm("clrscrnloop2:"); + asm("lda #$55"); + asm("sta $ff00,y"); + asm("iny"); + asm("lda #$aa"); + asm("sta $ff00,y"); + asm("iny"); + asm("cpy #$40"); + asm("bne clrscrnloop2"); + + + asm("pla"); + asm("sta $fe"); + asm("pla"); + asm("sta $fd"); + + + ctk_draw_clear(0, SCREEN_HEIGHT); + + /* Setup mouse pointer sprite. */ + asm("lda %v+%w", ctk_hires_theme, + offsetof(struct ctk_hires_theme, pointermaskcolor)); + asm("sta $d027"); + asm("lda %v+%w", ctk_hires_theme, + offsetof(struct ctk_hires_theme, pointercolor)); + asm("sta $d028"); + + ptr1 = ctk_hires_theme.pointer; + ptr2 = (unsigned char *)0xff40; + + for(i = 0; i < 0x80; ++i) { + *ptr2++ = *ptr1++; + } + + return; +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +static void __fastcall__ +draw_widget(register struct ctk_widget *w, + unsigned char x, unsigned char y, + unsigned char clipy1, unsigned char clipy2, + unsigned char afocus) +{ + static unsigned char xpos, ypos, xscroll; + static unsigned char i; + static char c; + static unsigned char len; + static unsigned char tmp; + static unsigned char yclipped; + static unsigned char focus; + char *text; + + xpos = x + w->x; + ypos = y + w->y; + + yclipped = 0; + if(ypos >= clipy1 && ypos < clipy2) { + yclipped = 1; + } + focus = afocus; + + + switch(w->type) { + case CTK_WIDGET_SEPARATOR: + hires_color(ctk_hires_theme.separatorcolors[focus]); + if(yclipped) { + hires_chlinexy(xpos, ypos, w->w); + } + break; + case CTK_WIDGET_LABEL: + hires_color(ctk_hires_theme.labelcolors[focus]); + text = w->widget.label.text; + for(i = 0; i < w->h; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + hires_gotoxy(xpos, ypos); + ctk_hires_cputsn(text, w->w); + tmp = w->w - (hires_wherex() - xpos); + if(tmp > 0) { + ctk_hires_cclear(tmp); + } + } + ++ypos; + text += w->w; + } + break; + case CTK_WIDGET_BUTTON: + if(yclipped) { + hires_color(ctk_hires_theme.buttonleftcolors[focus]); + hires_gotoxy(xpos, ypos); + ctk_hires_draw_buttonleft(); + hires_color(ctk_hires_theme.buttoncolors[focus]); + hires_gotoxy(xpos + 1, ypos); + ctk_hires_cputsn(w->widget.button.text, w->w); + hires_color(ctk_hires_theme.buttonrightcolors[focus]); + ctk_hires_draw_buttonright(); + } + break; + case CTK_WIDGET_HYPERLINK: + if(yclipped) { + hires_color(ctk_hires_theme.hyperlinkcolors[focus]); + hires_underline(1); + hires_gotoxy(xpos, ypos); + ctk_hires_cputsn(w->widget.button.text, w->w); + hires_underline(0); + } + break; + case CTK_WIDGET_TEXTENTRY: + if(yclipped) { + hires_color(ctk_hires_theme.textentrycolors[focus]); + + if((focus & CTK_FOCUS_WIDGET) && + w->widget.textentry.state != CTK_TEXTENTRY_EDIT) { + hires_revers(1); + } else { + hires_revers(0); + } + xscroll = 0; + tmp = w->w - 1; + if(w->widget.textentry.xpos >= tmp) { + xscroll = w->widget.textentry.xpos - tmp; + } + text = w->widget.textentry.text; + if(w->widget.textentry.state == CTK_TEXTENTRY_EDIT) { + hires_revers(0); + hires_cputcxy(xpos, ypos, '>'); + text += xscroll; + for(i = 0; i < w->w; ++i) { + c = *text; + if(i == w->widget.textentry.xpos - xscroll) { + hires_revers(1); + } else { + hires_revers(0); + } + if(c == 0) { + ctk_hires_cputc(' '); + } else { + ctk_hires_cputc(c); + } + hires_revers(0); + ++text; + } + ctk_hires_cputc('<'); + } else { + hires_cputcxy(xpos, ypos, '|'); + /* hires_gotoxy(xpos + 1, ypos); */ + ctk_hires_cputsn(text, w->w); + i = hires_wherex(); + tmp = i - xpos - 1; + if(tmp < w->w) { + ctk_hires_cclear(w->w - tmp); + } + ctk_hires_cputc('|'); + } + } + hires_revers(0); + break; + case CTK_WIDGET_ICON: + if(yclipped) { + hires_color(ctk_hires_theme.iconcolors[focus]); + + x = xpos; + len = strlen(w->widget.icon.title); + if(x + len >= SCREEN_WIDTH) { + x = SCREEN_WIDTH - len; + } + + tmp = ypos + 3; + + if(tmp < clipy2) { + hires_gotoxy(x, tmp); + ctk_hires_cputsn(w->widget.icon.title, len); + } + + hires_gotoxy(xpos, ypos); + if(w->widget.icon.bitmap != NULL) { + ctk_hires_bitmapptr = w->widget.icon.bitmap; + for(i = 0; i < 3; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + hires_gotoxy(xpos, ypos); + ctk_hires_draw_bitmapline(3); + } + ctk_hires_bitmapptr += 3 * 8; + ++ypos; + } + + /* draw_bitmap_icon(w->widget.icon.bitmap);*/ + } + + } + break; + case CTK_WIDGET_BITMAP: + hires_color(ctk_hires_theme.bitmapcolors[focus]); + ctk_hires_bitmapptr = w->widget.bitmap.bitmap; + for(i = 0; i < w->h; ++i) { + if(ypos >= clipy1 && ypos < clipy2) { + hires_gotoxy(xpos, ypos); + ctk_hires_draw_bitmapline(w->w); + } + ctk_hires_bitmapptr += w->w * 8; + ++ypos; + } + break; + + default: + break; + } +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_draw_widget(struct ctk_widget *w, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + struct ctk_window *win = w->window; + unsigned char posx, posy; + + posx = win->x + 1; + posy = win->y + 2; + + if(w == win->focused) { + focus |= CTK_FOCUS_WIDGET; + } + + draw_widget(w, posx, posy, + clipy1, clipy2, + focus); +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_draw_clear_window(register struct ctk_window *window, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + static unsigned char h; + + hires_color(ctk_hires_theme.windowcolors[focus]); + + h = window->y + 2 + window->h; + /* Clear window contents. */ + for(i = window->y + 2; i < h; ++i) { + if(i >= clipy1 && i <= clipy2) { + hires_cclearxy(window->x + 1, i, window->w); + } + } +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_draw_window(register struct ctk_window *window, + unsigned char focus, + unsigned char clipy1, unsigned char clipy2, + unsigned char draw_borders) +{ + register struct ctk_widget *w; + + x = window->x; + y = window->y + 1; + + ++clipy2; + + if(clipy2 <= y) { + return; + } + + /* hires_color(ctk_hires_theme.windowcolors[focus+1]);*/ + + x1 = x + 1; + y1 = y + 1; + /* x2 = x1 + window->w; + y2 = y1 + window->h;*/ + + hires_gotoxy(x, y); + ctk_hires_windowparams.w = window->w; + ctk_hires_windowparams.h = window->h; + if(clipy1 < y) { + ctk_hires_windowparams.clipy1 = 0; + } else { + ctk_hires_windowparams.clipy1 = clipy1 - y; + } + ctk_hires_windowparams.clipy2 = clipy2 - y; + ctk_hires_windowparams.color1 = ctk_hires_theme.windowcolors[focus+1]; + ctk_hires_windowparams.color2 = ctk_hires_theme.windowcolors[focus]; + ctk_hires_windowparams.title = window->title; + ctk_hires_windowparams.titlelen = window->titlelen; + + if(ctk_hires_windowparams.clipy1 < ctk_hires_windowparams.clipy2 && + ctk_hires_windowparams.clipy2 > 0) { + ctk_hires_draw_windowborders(); + } + + /* Draw inactive widgets. */ + for(w = window->inactive; w != NULL; w = w->next) { + draw_widget(w, x1, y1, + clipy1, clipy2, + focus); + } + + /* Draw active widgets. */ + for(w = window->active; w != NULL; w = w->next) { + wfocus = focus; + if(w == window->focused) { + wfocus |= CTK_FOCUS_WIDGET; + } + draw_widget(w, x1, y1, + clipy1, clipy2, + wfocus); + } +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_draw_dialog(register struct ctk_window *dialog) +{ + register struct ctk_widget *w; + + hires_color(ctk_hires_theme.windowcolors[CTK_FOCUS_DIALOG]); + + /* x = (SCREEN_WIDTH - dialog->w) / 2; + y = (SCREEN_HEIGHT - 1 - dialog->h) / 2; */ + x = dialog->x; + y = dialog->y + 1; + + + x1 = x + 1; + y1 = y + 1; + x2 = x1 + dialog->w; + y2 = y1 + dialog->h; + + + /* Draw dialog frame. */ + + hires_cvlinexy(x, y1, dialog->h); + hires_cvlinexy(x2, y1, dialog->h); + + hires_chlinexy(x1, y, dialog->w); + hires_chlinexy(x1, y2, dialog->w); + + hires_cputcxy(x, y, CH_ULCORNER); + hires_cputcxy(x, y2, CH_LLCORNER); + hires_cputcxy(x2, y, CH_URCORNER); + hires_cputcxy(x2, y2, CH_LRCORNER); + + + /* Clear window contents. */ + for(i = y1; i < y2; ++i) { + hires_cclearxy(x1, i, dialog->w); + } + + /* Draw inactive widgets. */ + for(w = dialog->inactive; w != NULL; w = w->next) { + draw_widget(w, x1, y1, + 0, SCREEN_HEIGHT, CTK_FOCUS_DIALOG); + } + + + /* Draw active widgets. */ + for(w = dialog->active; w != NULL; w = w->next) { + wfocus = CTK_FOCUS_DIALOG; + if(w == dialog->focused) { + wfocus |= CTK_FOCUS_WIDGET; + } + draw_widget(w, x1, y1, + 0, SCREEN_HEIGHT, wfocus); + } + +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_draw_clear(unsigned char y1, unsigned char y2) +{ + for(i = y1; i < y2; ++i) { + clear_line(i); + } +} +/*-----------------------------------------------------------------------------------*/ +static void +draw_menu(register struct ctk_menu *m) +{ + static unsigned char x, x2, y; + + hires_color(ctk_hires_theme.openmenucolor); + x = hires_wherex(); + ctk_hires_cputsn(m->title, m->titlelen); + ctk_hires_cputc(' '); + x2 = hires_wherex(); + if(x + CTK_CONF_MENUWIDTH > SCREEN_WIDTH) { + x = SCREEN_WIDTH - CTK_CONF_MENUWIDTH; + } + for(y = 0; y < m->nitems; ++y) { + if(y == m->active) { + hires_color(ctk_hires_theme.activemenucolor); + } else { + hires_color(ctk_hires_theme.menucolor); + } + hires_gotoxy(x, y + 1); + if(m->items[y].title[0] == '-') { + ctk_hires_chline(CTK_CONF_MENUWIDTH); + } else { + ctk_hires_cputsn(m->items[y].title, + strlen(m->items[y].title)); + } + ctk_hires_cclear(x + CTK_CONF_MENUWIDTH - hires_wherex()); + hires_revers(0); + } + hires_gotoxy(x2, 0); + hires_color(ctk_hires_theme.menucolor); +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_draw_menus(struct ctk_menus *menus) +{ + struct ctk_menu *m; + + /* Draw menus */ + hires_color(ctk_hires_theme.menucolor); + hires_gotoxy(0, 0); + hires_revers(0); + ctk_hires_cputc(' '); + for(m = menus->menus->next; m != NULL; m = m->next) { + if(m != menus->open) { + ctk_hires_cputsn(m->title, m->titlelen); + ctk_hires_cputc(' '); + } else { + draw_menu(m); + } + } + ctk_hires_cclear(SCREEN_WIDTH - hires_wherex() - + strlen(menus->desktopmenu->title) - 1); + + /* Draw desktopmenu */ + if(menus->desktopmenu != menus->open) { + ctk_hires_cputsn(menus->desktopmenu->title, + menus->desktopmenu->titlelen); + ctk_hires_cputc(' '); + } else { + draw_menu(menus->desktopmenu); + } + +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_draw_height(void) +{ + return SCREEN_HEIGHT; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_draw_width(void) +{ + return SCREEN_WIDTH; +} +/*-----------------------------------------------------------------------------------*/ +/*unsigned char +ctk_arch_isprint(char c) +{ + return isprint(c); +}*/ diff --git a/platform/c64/ctk/ctk-hires.h b/platform/c64/ctk/ctk-hires.h new file mode 100644 index 000000000..a2af558a5 --- /dev/null +++ b/platform/c64/ctk/ctk-hires.h @@ -0,0 +1,48 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-hires.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#ifndef __CTK_HIRES_H__ +#define __CTK_HIRES_H__ + +#include + +#define CTK_ARCH_KEY_T char + +#define ctk_arch_keyavail kbhit +#define ctk_arch_getkey cgetc + +#define CH_ENTER '\n' + +#endif /* __CTK_HIRES_H__ */ diff --git a/platform/c64/ctk/ctk-mouse-arch.c b/platform/c64/ctk/ctk-mouse-arch.c new file mode 100644 index 000000000..ec3ab6538 --- /dev/null +++ b/platform/c64/ctk/ctk-mouse-arch.c @@ -0,0 +1,122 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-mouse-arch.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "ctk/ctk.h" +#include "ctk-mouse.h" +#include "ctk-conf.h" + +#if CTK_CONF_MOUSE_SUPPORT + +unsigned short ctk_mouse_joyy, ctk_mouse_joyx; +unsigned char ctk_mouse_firebutton; + +extern void ctk_mouse_asm_irq(void); + +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +ctk_mouse_init(void) +{ + /* Place mouse pointer at the middle of the screen. */ + ctk_mouse_joyx = 160; + ctk_mouse_joyy = 100; + + /* Setup and start IRQ */ + asm("sei"); + asm("lda #<%v", ctk_mouse_asm_irq); + asm("sta $0314"); + asm("lda #>%v", ctk_mouse_asm_irq); + asm("sta $0315"); + asm("cli"); + +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_x(void) +{ + if(ctk_mouse_joyx >= 342) { + ctk_mouse_joyx = 0; + } else if(ctk_mouse_joyx >= 320) { + ctk_mouse_joyx = 319; + } + return ctk_mouse_joyx; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_y(void) +{ + return ctk_mouse_joyy; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_button(void) +{ + return ctk_mouse_firebutton; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_xtoc(unsigned short x) +{ + return x / 8; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_ytoc(unsigned short y) +{ + return y / 8; +} +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +ctk_mouse_hide(void) +{ + /* Turn off sprites 0 and 1 */ + asm("lda #0"); + asm("sta $d015"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +ctk_mouse_show(void) +{ + /* Turn on sprites 0 and 1 */ + asm("lda #3"); + asm("sta $d015"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#endif /* CTK_CONF_MOUSE_SUPPORT */ diff --git a/platform/c64/ctk/ctk-mouse.c b/platform/c64/ctk/ctk-mouse.c new file mode 100644 index 000000000..b99c246cb --- /dev/null +++ b/platform/c64/ctk/ctk-mouse.c @@ -0,0 +1,122 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-mouse.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "ctk/ctk.h" +#include "ctk-mouse.h" +#include "ctk-conf.h" + +#if CTK_CONF_MOUSE_SUPPORT + +unsigned short ctk_mouse_joyy, ctk_mouse_joyx; +unsigned char ctk_mouse_firebutton; + +extern void ctk_mouse_asm_irq(void); + +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +ctk_mouse_init(void) +{ + /* Place mouse pointer at the middle of the screen. */ + ctk_mouse_joyx = 160; + ctk_mouse_joyy = 100; + + /* Setup and start IRQ */ + asm("sei"); + asm("lda #<%v", ctk_mouse_asm_irq); + asm("sta $0314"); + asm("lda #>%v", ctk_mouse_asm_irq); + asm("sta $0315"); + asm("cli"); + +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_x(void) +{ + if(ctk_mouse_joyx >= 342) { + ctk_mouse_joyx = 0; + } else if(ctk_mouse_joyx >= 320) { + ctk_mouse_joyx = 319; + } + return ctk_mouse_joyx; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_y(void) +{ + return ctk_mouse_joyy; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_button(void) +{ + return ctk_mouse_firebutton; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_xtoc(unsigned short x) +{ + return x / 8; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_ytoc(unsigned short y) +{ + return y / 8; +} +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +ctk_mouse_hide(void) +{ + /* Turn off sprites 0 and 1 */ + asm("lda #0"); + asm("sta $d015"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +ctk_mouse_show(void) +{ + /* Turn on sprites 0 and 1 */ + asm("lda #3"); + asm("sta $d015"); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#endif /* CTK_CONF_MOUSE_SUPPORT */ diff --git a/platform/c64/lib/iconfield.c b/platform/c64/lib/iconfield.c new file mode 100644 index 000000000..caf86f9e1 --- /dev/null +++ b/platform/c64/lib/iconfield.c @@ -0,0 +1,119 @@ +/* + * 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: iconfield.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +/*-----------------------------------------------------------------------------------*/ +#define LFN 9 +static void +loaddirectory(char *ext) +{ + unsigned char i, j; + unsigned char extlen; + + extlen = strlen(ext); + + if(cbm_opendir(LFN, 8) != 0) { + show_statustext("Cannot open directory"); + } else { + i = 0; + while(cbm_readdir(LFN, &dirent) == 0) { + if(strcmp(&dirent.name[strlen(dirent.name) - extlen], + ext) == 0) { + strncpy(filenames[i], dirent.name, 16); + ++i; + if(i == MAX_NUMFILES) { + break; + } + } + cbm_closedir(LFN); + + numfiles = i; + + j = 0; + for(i = 0; i < numfiles; ++i) { + dscs[j] = LOADER_LOAD_DSC(filenames[i]); + if(dscs[j] != NULL) { + ++j; + } + } + } + } +} +/*-----------------------------------------------------------------------------------*/ +static void +makewindow(struct ctk_window *window) +{ + 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) + 1; + } + CTK_WIDGET_SET_YPOS(&autoexitbutton, height - 2); + CTK_WIDGET_ADD(&window, &autoexitbutton); + CTK_WIDGET_SET_YPOS(&autoexitlabel, height - 2); + CTK_WIDGET_ADD(&window, &autoexitlabel); + + 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); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/lib/mtarch.c b/platform/c64/lib/mtarch.c new file mode 100644 index 000000000..53e79afd8 --- /dev/null +++ b/platform/c64/lib/mtarch.c @@ -0,0 +1,98 @@ +/* + * 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 + * + * $Id: mtarch.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#include "mtarch.h" +#include + +unsigned char mtarch_asm_threadspreg; +unsigned char *mtarch_asm_threadsp; +unsigned char *mtarch_asm_threadzp; +unsigned char *mtarch_asm_threadstack; + +void mtarch_asm_start(void); +void mtarch_asm_exec(void); + + +/*--------------------------------------------------------------------------*/ +void +mtarch_start(struct mtarch_thread *thread, + void (* function)(void *data), + void *data) +{ + memset(thread->cpustack, 0, sizeof(thread->cpustack)); + memset(thread->cstack, 0, sizeof(thread->cstack)); + + /* Create a CPU stack frame with the appropriate values... */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 2] = ((unsigned short)function) >> 8; /* high byte of return address. */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 3] = ((unsigned short)function) & 0xff; /* low byte of return address. */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 4] = 0x21; /* processor flags. */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 5] = /* a register */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 6] = /* x register */ + thread->cpustack[MTARCH_CPUSTACKSIZE - 7] = 0; /* y register */ + thread->spreg = MTARCH_CPUSTACKSIZE - 8; + + /* Setup the C stack with the data pointer. */ + thread->sp = &thread->cstack[MTARCH_CSTACKSIZE - 1]; + + mtarch_asm_threadzp = &(thread->zp); + mtarch_asm_start(); +} +/*--------------------------------------------------------------------------*/ +void +mtarch_exec(struct mtarch_thread *thread) +{ + /* Switch processor stack. The call to mtarch_asm_switch() will not + return until the process that we switch to calls yield(). */ + mtarch_asm_threadspreg = thread->spreg; + mtarch_asm_threadsp = thread->sp; + + mtarch_asm_threadstack = &(thread->cpustack[0]); + mtarch_asm_threadzp = &(thread->zp[0]); + + mtarch_asm_exec(); + + thread->sp = mtarch_asm_threadsp; + thread->spreg = mtarch_asm_threadspreg; +} +/*--------------------------------------------------------------------------*/ +void +mtarch_init(void) { + +} +/*--------------------------------------------------------------------------*/ +void +mtarch_remove(void) +{ + +} diff --git a/platform/c64/lib/mtarch.h b/platform/c64/lib/mtarch.h new file mode 100644 index 000000000..a116c0e86 --- /dev/null +++ b/platform/c64/lib/mtarch.h @@ -0,0 +1,51 @@ +/* + * 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 + * + * $Id: mtarch.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#ifndef __MTARCH_H__ +#define __MTARCH_H__ + +#define MTARCH_CPUSTACKSIZE 256 +#define MTARCH_CSTACKSIZE 256 +#define MTARCH_ZPSIZE 32 + +struct mtarch_thread { + unsigned char spreg; + unsigned char *sp; + unsigned char cpustack[MTARCH_CPUSTACKSIZE]; + unsigned char cstack[MTARCH_CSTACKSIZE]; + unsigned char zp[MTARCH_ZPSIZE]; +}; + +#endif /* __MTARCH_H__ */ + diff --git a/platform/c64/loader/c64-dio-asm.h b/platform/c64/loader/c64-dio-asm.h new file mode 100644 index 000000000..794f977ec --- /dev/null +++ b/platform/c64/loader/c64-dio-asm.h @@ -0,0 +1,47 @@ +/* + * 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: c64-dio-asm.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ +#ifndef __C64_DIO_ASM_H__ +#define __C64_DIO_ASM_H__ + +extern unsigned char c64_dio_asm_track, + c64_dio_asm_sector; + +extern unsigned char *c64_dio_asm_ptr; + +void __fastcall__ c64_dio_asm_init(unsigned char drive); +unsigned char c64_dio_asm_read_block(void); +unsigned char c64_dio_asm_write_block(void); + +#endif /* __C64_DIO_H__ */ diff --git a/platform/c64/loader/c64-dio.c b/platform/c64/loader/c64-dio.c new file mode 100644 index 000000000..2de007b7f --- /dev/null +++ b/platform/c64/loader/c64-dio.c @@ -0,0 +1,119 @@ +/** + * \addtogroup c64fs + * @{ + * + */ + +/** + * \file + * C64 direct disk I/O. + * \author Adam Dunkels + * + */ + +/* + * 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: c64-dio.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "c64-dio.h" +#include "c64-dio-asm.h" + +/*-----------------------------------------------------------------------------------*/ +/** + * Read a block of data (256 bytes) from the disk. + * + * \param track The track of the disk block to be read. + * + * \param sector The sector of the disk block to be read. + * + * \param ptr A pointer to a buffer than must be able to accomodate + * 256 bytes of data. + * + * \return An error code or C64_DIO_OK if the data was successfully + * read. + */ +/*-----------------------------------------------------------------------------------*/ +unsigned char +c64_dio_read_block(unsigned char track, + unsigned char sector, + unsigned char *ptr) +{ + c64_dio_asm_track = track; + c64_dio_asm_sector = sector; + c64_dio_asm_ptr = ptr; + return c64_dio_asm_read_block(); +} +/*-----------------------------------------------------------------------------------*/ +/** + * Write a block of data (256 bytes) to the disk. + * + * \param track The track of the disk block to be written. + * + * \param sector The sector of the disk block to be written. + * + * \param ptr A pointer to a buffer containing the 256 bytes of data + * to be written. + * + * \return An error code or C64_DIO_OK if the data was successfully + * written. + */ +/*-----------------------------------------------------------------------------------*/ +unsigned char +c64_dio_write_block(unsigned char track, + unsigned char sector, + unsigned char *ptr) +{ + c64_dio_asm_track = track; + c64_dio_asm_sector = sector; + c64_dio_asm_ptr = ptr; + return c64_dio_asm_write_block(); +} +/*-----------------------------------------------------------------------------------*/ +/** + * Initialize the direct disk I/O routines for a particular disk drive. + * + * This function must be called before any of the other direct disk + * I/O functions can be used. + * + * \param drive The drive number of the disk drive for which the + * direct disk I/O should be enabled. + */ +/*-----------------------------------------------------------------------------------*/ +void +c64_dio_init(unsigned char drive) +{ + c64_dio_asm_init(drive); +} +/*-----------------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/c64/loader/c64-dio.h b/platform/c64/loader/c64-dio.h new file mode 100644 index 000000000..8c4e2b636 --- /dev/null +++ b/platform/c64/loader/c64-dio.h @@ -0,0 +1,50 @@ +/* + * 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: c64-dio.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ +#ifndef __C64_DIO_H__ +#define __C64_DIO_H__ + +void c64_dio_init(unsigned char drive); + +unsigned char c64_dio_read_block(unsigned char track, + unsigned char sector, + unsigned char *buf); + +unsigned char c64_dio_write_block(unsigned char track, + unsigned char sector, + unsigned char *buf); + +#define C64_DIO_OK 0 + +#endif /* __C64_DIO_H__ */ diff --git a/platform/c64/loader/c64-fs-raw.c b/platform/c64/loader/c64-fs-raw.c new file mode 100644 index 000000000..01fc10e3e --- /dev/null +++ b/platform/c64/loader/c64-fs-raw.c @@ -0,0 +1,205 @@ +/** + * \addtogroup c64fs + * @{ + */ + +/** + * \file + * "Raw" C64 file system access. + * \author Adam Dunkels + * + * This file provides functions that allow reading data from files + * without updating the file descriptor pointer. The functions are not + * automatically included in the core Contiki code and therefore + * application programs that use tham must manually link with this + * file. + * + */ + + +/* + * 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: c64-fs-raw.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "c64-fs-raw.h" + +#include + +struct directory_entry { + unsigned char type; + unsigned char track, sect; + unsigned char name[16]; + unsigned char reltrack, relsect, relreclen; + unsigned char unused1, unused2, unused3, unused4; + unsigned char tmptrack, tmpsect; + unsigned char blockslo, blockshi; +}; + + +extern unsigned char _c64_fs_dirbuf[256]; +extern unsigned char _c64_fs_dirbuftrack, _c64_fs_dirbufsect; + +extern unsigned char _c64_fs_filebuf[256]; +extern unsigned char _c64_fs_filebuftrack, _c64_fs_filebufsect; + +void _c64_fs_readdirbuf(unsigned char track, unsigned char sect); + + +/*-----------------------------------------------------------------------------------*/ +/** + * Read data from a file without updating the file descriptor pointer. + * + * This function reads data from an open file into a buffer than must + * be allocated by the caller, but does not update the file + * description pointer like the c64_fs_read() function does. + * + * \param f A pointer to a file descriptor structure that must have + * been opened with c64_fs_open(). + * + * \param buf A pointer to the buffer in which the data should be placed. + * + * \param len The maxiumum amount of bytes to read. + * + * \return The number of bytes that actually was read, or 0 if an end + * of file was encountered. + * + */ +/*-----------------------------------------------------------------------------------*/ +int __fastcall__ +c64_fs_read_raw(register struct c64_fs_file *f, char *buf, int len) +{ + int i; + unsigned char fptr, ftrack, fsect; + + /* Check if current block is already in buffer, and if not read it + from disk. */ + if(_c64_fs_filebuftrack != f->track || + _c64_fs_filebufsect != f->sect) { + _c64_fs_filebuftrack = f->track; + _c64_fs_filebufsect = f->sect; + c64_dio_read_block(_c64_fs_filebuftrack, + _c64_fs_filebufsect, _c64_fs_filebuf); + } + + if(_c64_fs_filebuf[0] == 0 && + f->ptr == _c64_fs_filebuf[1]) { + return 0; /* EOF */ + } + + fptr = f->ptr; + ftrack = f->track; + fsect = f->sect; + + for(i = 0; i < len; ++i) { + *buf = _c64_fs_filebuf[fptr]; + + ++fptr; + if(_c64_fs_filebuf[0] == 0) { + if(fptr == _c64_fs_filebuf[1]) { + /* End of file reached, we return the amount of bytes read so + far. */ + return i + 1; + } + } else if(fptr == 0) { + + /* Read new block into buffer and set buffer state + accordingly. */ + _c64_fs_filebuftrack = ftrack = _c64_fs_filebuf[0]; + _c64_fs_filebufsect = fsect = _c64_fs_filebuf[1]; + fptr = 2; + c64_dio_read_block(_c64_fs_filebuftrack, + _c64_fs_filebufsect, _c64_fs_filebuf); + } + + ++buf; + } + return i; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Move the file descriptior pointer forward in the file. + * + * + * \param f A pointer to a file descriptor structure that must have + * been opened with c64_fs_open(). + * + * \param len The number of bytes the pointer should be moved forward. + * + * \return The number of bytes that the pointer actually was moved, or + * 0 if an end of file was encountered. + */ +/*-----------------------------------------------------------------------------------*/ +int +c64_fs_read_next(register struct c64_fs_file *f, int len) +{ + int i; + + /* Check if current block is already in buffer, and if not read it + from disk. */ + if(_c64_fs_filebuftrack != f->track || + _c64_fs_filebufsect != f->sect) { + _c64_fs_filebuftrack = f->track; + _c64_fs_filebufsect = f->sect; + c64_dio_read_block(_c64_fs_filebuftrack, + _c64_fs_filebufsect, _c64_fs_filebuf); + } + + if(_c64_fs_filebuf[0] == 0 && + f->ptr == _c64_fs_filebuf[1]) { + return 0; /* EOF */ + } + + for(i = 0; i < len; ++i) { + + ++f->ptr; + if(_c64_fs_filebuf[0] == 0) { + if(f->ptr == _c64_fs_filebuf[1]) { + /* End of file reached, we return the amount of bytes read so + far. */ + return i + 1; + } + } else if(f->ptr == 0) { + /* Read new block into buffer and set buffer state + accordingly. */ + _c64_fs_filebuftrack = f->track = _c64_fs_filebuf[0]; + _c64_fs_filebufsect = f->sect = _c64_fs_filebuf[1]; + f->ptr = 2; + c64_dio_read_block(_c64_fs_filebuftrack, + _c64_fs_filebufsect, _c64_fs_filebuf); + } + } + return i; +} +/*-----------------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/c64/loader/c64-fs-raw.h b/platform/c64/loader/c64-fs-raw.h new file mode 100644 index 000000000..aec1c8cbc --- /dev/null +++ b/platform/c64/loader/c64-fs-raw.h @@ -0,0 +1,46 @@ +/* + * 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: c64-fs-raw.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ +#ifndef __C64_FS_RAW_H__ +#define __C64_FS_RAW_H__ + +#include "c64-fs.h" + +int __fastcall__ c64_fs_read_raw(struct c64_fs_file *f, + char *buf, int len); + +int c64_fs_read_next(struct c64_fs_file *f, int len); + + +#endif /* __C64_FS_H__ */ diff --git a/platform/c64/loader/c64-fs-write.c b/platform/c64/loader/c64-fs-write.c new file mode 100644 index 000000000..a37c0a2e4 --- /dev/null +++ b/platform/c64/loader/c64-fs-write.c @@ -0,0 +1,121 @@ +/** + * \addtogroup c64fs + * @{ + */ + +/** + * \file + * Implementation of C64 file writes. + * \author Adam Dunkels + * + * The functions in this file are not included in the core Contiki + * code, but must be explicitly linked by an application that that + * wishes to be able to write to files. + */ + + +/* + * 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: c64-fs-write.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "c64-dio.h" +#include "c64-fs.h" +#include + +/* An *UGLY* implementation of c64_fs_write that only can be used to + overwrite a single block file. */ + +extern unsigned char _c64_fs_filebuf[256]; +extern unsigned char _c64_fs_filebuftrack, + _c64_fs_filebufsect; + + +/*-----------------------------------------------------------------------------------*/ +/** + * Write data to an open file. + * + * \note This function currently does not support writing to other than a single block file (cannot be more than 254 bytes long). + * + * \param f A pointer to a file descriptor previously opened with c64_fs_open(). + * + * \param buf A pointer to a buffer with data that should be written + * to the file. + * + * \param len The length of the data that should be written. + * + * \return The number of bytes actually written. + * + */ +/*-----------------------------------------------------------------------------------*/ +int __fastcall__ +c64_fs_write(register struct c64_fs_file *f, char *buf, int len) +{ + int i; + + if(len <= 0) { + return 0; + } + + /* Check if current block is already in buffer, and if not read it + from disk. */ + if(_c64_fs_filebuftrack != f->track || + _c64_fs_filebufsect != f->sect) { + _c64_fs_filebuftrack = f->track; + _c64_fs_filebufsect = f->sect; + c64_dio_read_block(_c64_fs_filebuftrack, + _c64_fs_filebufsect, + _c64_fs_filebuf); + } + + i = 256 - f->ptr; + if(len < i) { + i = len; + } + + memcpy(&_c64_fs_filebuf[f->ptr], buf, i); + + f->ptr += i; + if(_c64_fs_filebuf[0] == 0 && + f->ptr > _c64_fs_filebuf[1]) { + _c64_fs_filebuf[1] = f->ptr; + } + + c64_dio_write_block(_c64_fs_filebuftrack, + _c64_fs_filebufsect, + _c64_fs_filebuf); + + return i; +} +/*-----------------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/c64/loader/c64-fs.c b/platform/c64/loader/c64-fs.c new file mode 100644 index 000000000..c766e5fdb --- /dev/null +++ b/platform/c64/loader/c64-fs.c @@ -0,0 +1,411 @@ +/** + * \defgroup c64fs C64 file system and disk functions. + * @{ + * + * The C64 file system functions are divided into two categories: + * those that deal with C64 files and the C64 disk directory, and + * those that allow direct block access to the disk. The former + * functions can be used for accessing regular files, whereas the + * latter functions are used e.g. to download D64 files onto 1541 + * disks. + * + * \note The C64 filesystem functions currently only work with the + * 1541/1541-II/1571 and compatible drives, and not with the IDE64 + * hard disks or the 1581/FD2000 3.5" drives. + * + * + */ + +/** + * \file + * C64 file system operations interface for Contiki. + * \author Adam Dunkels + * + */ + +/* + * 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: c64-fs.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "c64-dio.h" +#include "c64-dio-asm.h" +#include "c64-fs.h" + +#include +#include + +struct directory_entry { + unsigned char type; + unsigned char track, sect; + unsigned char name[16]; + unsigned char reltrack, relsect, relreclen; + unsigned char unused1, unused2, unused3, unused4; + unsigned char tmptrack, tmpsect; + unsigned char blockslo, blockshi; +}; + +unsigned char _c64_fs_dirbuf[256]; +unsigned char _c64_fs_dirbuftrack = 0, _c64_fs_dirbufsect = 0; + +unsigned char _c64_fs_filebuf[256]; +unsigned char _c64_fs_filebuftrack = 0, _c64_fs_filebufsect = 0; + +static struct c64_fs_dirent lastdirent; + +static struct c64_fs_dir opendir; +static struct c64_fs_dirent opendirent; + +/*-----------------------------------------------------------------------------------*/ +/** + * Open a file. + * + * The file description must be allocated by the caller and a pointer + * to it is passed to this function. + * + * \param name A pointer to the name of the file to be opened. + * \param f A pointer to the file descriptor struct. + * + * \retval 0 If the file was successfully opened. + * \retval -1 If the file does not exist. + */ +/*-----------------------------------------------------------------------------------*/ +int +c64_fs_open(const char *name, register struct c64_fs_file *f) +{ + /* First check if we already have the file cached. If so, we don't + need to do an expensive directory lookup. */ + if(strncmp(lastdirent.name, name, 16) == 0) { + f->track = lastdirent.track; + f->sect = lastdirent.sect; + f->ptr = 2; + return 0; + } + + /* Not in cache, so we walk through directory instead. */ + c64_fs_opendir(&opendir); + + do { + c64_fs_readdir_dirent(&opendir, &opendirent); + if(strncmp(opendirent.name, name, 16) == 0) { + f->track = opendirent.track; + f->sect = opendirent.sect; + f->ptr = 2; + return 0; + } + } while(c64_fs_readdir_next(&opendir) == 0); + + /* The file was not found in the directory. We flush the directory + buffer cache now in order to prevent a nasty problem from + happening: If the first directory block of an empty disk was + cached, *all* subsequent file opens would return "file not + found". */ + _c64_fs_dirbuftrack = 0; /* There are no disk blocks on track 0. */ + return -1; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Read data from an open file. + * + * This function reads data from an open file into a buffer than must + * be allocated by the caller. + * + * \param f A pointer to a file descriptor structure that must have + * been opened with c64_fs_open(). + * + * \param buf A pointer to the buffer in which the data should be placed. + * + * \param len The maxiumum amount of bytes to read. + * + * \return The number of bytes that actually was read, or 0 if an end + * of file was encountered. + */ +/*-----------------------------------------------------------------------------------*/ +#if !NOASM +#pragma optimize(push, off) +#endif /* !NOASM */ +int __fastcall__ +c64_fs_read(register struct c64_fs_file *f, char *buf, int len) +{ + static int i; + + /* Check if current block is already in buffer, and if not read it + from disk. */ + +#if NOASM + if(f->track != _c64_fs_filebuftrack || + _c64_fs_filebufsect != f->sect) { + _c64_fs_filebuftrack = f->track; + _c64_fs_filebufsect = f->sect; + c64_dio_read_block(_c64_fs_filebuftrack, _c64_fs_filebufsect, + _c64_fs_filebuf); + } +#else /* NOASM */ + asm("ldy #%b", offsetof(struct c64_fs_file, track)); + asm("lda (regbank+%b),y", 4); + asm("cmp %v", _c64_fs_filebuftrack); + asm("bne doblock"); + + asm("ldy #%b", offsetof(struct c64_fs_file, sect)); + asm("lda (regbank+%b),y", 4); + asm("cmp %v", _c64_fs_filebufsect); + asm("bne doblock"); + + asm("jmp noblock"); + + asm("doblock:"); + + asm("ldy #%b", offsetof(struct c64_fs_file, track)); + asm("lda (regbank+%b),y", 4); + asm("sta %v", _c64_fs_filebuftrack); + asm("sta %v", c64_dio_asm_track); + + asm("ldy #%b", offsetof(struct c64_fs_file, sect)); + asm("lda (regbank+%b),y", 4); + asm("sta %v", _c64_fs_filebufsect); + asm("sta %v", c64_dio_asm_sector); + + asm("lda #<(%v)", _c64_fs_filebuf); + asm("sta %v", c64_dio_asm_ptr); + asm("lda #>(%v)", _c64_fs_filebuf); + asm("sta %v+1", c64_dio_asm_ptr); + + asm("jsr %v", c64_dio_asm_read_block); + + asm("noblock:"); + +#endif /* NOASM */ + + if(_c64_fs_filebuf[0] == 0 && + f->ptr == _c64_fs_filebuf[1]) { + return 0; /* EOF */ + } + + for(i = 0; i < len; ++i) { +#if NOASM + *buf = _c64_fs_filebuf[f->ptr]; + ++f->ptr; +#else /* NOASM */ + asm("ldy #%o+1", buf); + asm("jsr ldaxysp"); + asm("sta ptr2"); + asm("stx ptr2+1"); + + asm("ldy #%b", offsetof(struct c64_fs_file, ptr)); + asm("lda (regbank+%b),y", 4); + asm("tax"); + + asm("ldy #0"); + asm("lda %v,x", _c64_fs_filebuf); + asm("sta (ptr2),y"); + + asm("inx"); + asm("txa"); + asm("ldy #%b", offsetof(struct c64_fs_file, ptr)); + asm("sta (regbank+%b),y", 4); +#endif /* NOASM */ + + + if(_c64_fs_filebuf[0] == 0) { + if(f->ptr == _c64_fs_filebuf[1]) { + /* End of file reached, we return the amount of bytes read so + far. */ + return i + 1; + } + } else if(f->ptr == 0) { + + /* Read new block into buffer and set buffer state + accordingly. */ + _c64_fs_filebuftrack = f->track = _c64_fs_filebuf[0]; + _c64_fs_filebufsect = f->sect = _c64_fs_filebuf[1]; + f->ptr = 2; + c64_dio_read_block(_c64_fs_filebuftrack, + _c64_fs_filebufsect, _c64_fs_filebuf); + } + + ++buf; + } + return i; +} +#if !NOASM +#pragma optimize(pop) +#endif /* !NOASM */ +/*-----------------------------------------------------------------------------------*/ +/** + * Close an open file. + * + * \param f A pointer to a file descriptor struct that previously has + * been opened with c64_fs_open(). + */ +/*-----------------------------------------------------------------------------------*/ +void +c64_fs_close(struct c64_fs_file *f) +{ + +} +/*-----------------------------------------------------------------------------------*/ +/** + * \internal + * Read a directory buffer into the _c64_fs_dirbuf buffer. + * + * This function is shared between this and the c64-fs-raw module. + * + * \param track The track of the directory block. + * \param sect The sector of the directory block. + */ +/*-----------------------------------------------------------------------------------*/ +void +_c64_fs_readdirbuf(unsigned char track, unsigned char sect) +{ + if(_c64_fs_dirbuftrack == track && + _c64_fs_dirbufsect == sect) { + /* Buffer already contains requested block, return. */ + return; + } + c64_dio_read_block(track, sect, _c64_fs_dirbuf); + _c64_fs_dirbuftrack = track; + _c64_fs_dirbufsect = sect; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Open the disk directory for reading. + * + * The caller must supply a pointer to a directory descriptor. + * + * \param d A pointer to a directory description that must be + * allocated by the caller. + */ +/*-----------------------------------------------------------------------------------*/ +unsigned char +c64_fs_opendir(register struct c64_fs_dir *d) +{ + d->track = 18; + d->sect = 1; + d->ptr = 2; + + return 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Read the current directory entry. + * + * This function reads the directory entry to which the directory + * descriptor currently points into a struct c64_fs_dirent supplied by + * the caller. + * + * The function c64_fs_readdir_next() is used to move the directory + * entry pointer forward in the directory. + * + * \param d A pointer to a directory descriptor previously opened with c64_fs_opendir(). + * + * \param f A pointer to a directory entry that must have been + * previously allocated by the caller. + */ +/*-----------------------------------------------------------------------------------*/ +void +c64_fs_readdir_dirent(register struct c64_fs_dir *d, + register struct c64_fs_dirent *f) +{ + struct directory_entry *de; + int i; + register char *nameptr; + + _c64_fs_readdirbuf(d->track, d->sect); + de = (struct directory_entry *)&_c64_fs_dirbuf[d->ptr]; + nameptr = de->name; + for(i = 0; i < 16; ++i) { + if(*nameptr == 0xa0) { + *nameptr = 0; + break; + } + ++nameptr; + } + strncpy(f->name, de->name, 16); + f->track = de->track; + f->sect = de->sect; + f->size = de->blockslo + (de->blockshi >> 8); + memcpy(&lastdirent, f, sizeof(struct c64_fs_dirent)); +} +/*-----------------------------------------------------------------------------------*/ +/** + * Move the directory pointer forward. + * + * This function moves the directory entry pointer in the directory + * descriptor forward so that it points to the next file. + * + * \param d A pointer to a directory descriptor previously opened with + * c64_fs_opendir(). + * + * \retval 1 If there are no more directory entried in the directory. + * \retval 0 There were more directory entries and the pointer has + * been moved to point to the next one. + */ +/*-----------------------------------------------------------------------------------*/ +unsigned char +c64_fs_readdir_next(struct c64_fs_dir *d) +{ + struct directory_entry *de; + again: + _c64_fs_readdirbuf(d->track, d->sect); + if(d->ptr == 226) { + if(_c64_fs_dirbuf[0] == 0) { + return 1; + } + d->track = _c64_fs_dirbuf[0]; + d->sect = _c64_fs_dirbuf[1]; + d->ptr = 2; + } else { + d->ptr += 32; + } + + de = (struct directory_entry *)&_c64_fs_dirbuf[d->ptr]; + if(de->type == 0) { + goto again; + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Close a directory descriptor previously opened by c64_fs_opendir(). + * + * \param d A poitner to a directory descriptor previously opened with + * c64_fs_opendir(). + */ +/*-----------------------------------------------------------------------------------*/ +void +c64_fs_closedir(struct c64_fs_dir *d) +{ + +} +/*-----------------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/c64/loader/c64-fs.h b/platform/c64/loader/c64-fs.h new file mode 100644 index 000000000..9d647177d --- /dev/null +++ b/platform/c64/loader/c64-fs.h @@ -0,0 +1,97 @@ +/** + * \addtogroup c64fs + * @{ + */ + +/** + * \file + * Header file for the C64 filesystem functions. + * \author Adam Dunkels + * + */ + +/* + * 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: c64-fs.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ +#ifndef __C64_FS_H__ +#define __C64_FS_H__ + +#include "c64-dio.h" + +/** + * An opaque structure with no user visible elements that represents + * an open file. + */ +struct c64_fs_file { + unsigned char track, sect, ptr; +}; + +int c64_fs_open(const char *name, struct c64_fs_file *f); +void c64_fs_close(struct c64_fs_file *f); +int __fastcall__ c64_fs_read(struct c64_fs_file *f, + char *buf, int len); + +int __fastcall__ c64_fs_write(struct c64_fs_file *f, + char *buf, int len); + +/** + * An opaque structure with no user visible elements that represents a + * directory descriptor. + */ +struct c64_fs_dir { + unsigned char track, sect, ptr; +}; + +/** + * A C64 directory entry. + */ +struct c64_fs_dirent { + char name[17]; /**< The name of the directory entry. */ + unsigned short size; /**< The size of the directory entry in 256 byte blocks. */ + unsigned char track, + sect; +}; + + +unsigned char c64_fs_opendir(struct c64_fs_dir *d); + +void c64_fs_readdir_dirent(struct c64_fs_dir *d, + struct c64_fs_dirent *f); +unsigned char c64_fs_readdir_next(struct c64_fs_dir *d); + +void c64_fs_closedir(struct c64_fs_dir *d); + +/** @} */ + +#endif /* __C64_FS_H__ */ diff --git a/platform/c64/loader/cfs-1541.c b/platform/c64/loader/cfs-1541.c new file mode 100644 index 000000000..682dc2e14 --- /dev/null +++ b/platform/c64/loader/cfs-1541.c @@ -0,0 +1,67 @@ +/* + * 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 + * + * $Id: cfs-1541.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#include "contiki.h" + +#include "cfs.h" +#include "cfs-service.h" + + +static int s_open(char *n, int f); +static void s_close(int f); +static int s_read(int f, char *b, int l); +static int s_write(int f, char *b, int l); +static int s_opendir(struct cfs_dir *p, const char *n); +static int s_readdir(struct cfs_dir *p, struct cfs_dirent *e); +static int s_closedir(struct cfs_dir *p); + +static const struct cfs_service_interface interface = + { + CFS_SERVICE_VERSION, + s_open, + s_close, + s_read, + s_write, + s_opendir, + s_readdir, + s_closedir + }; + +EK_EVENTHANDLER(eventhandler, ev, data); +EK_POLLHANDLER(pollhandler); +EK_PROCESS(proc, CFS_SERVICE_NAME, EK_PRIO_NORMAL, + eventhandler, pollhandler, (void *)&state); + +/*---------------------------------------------------------------------------*/ + diff --git a/platform/c64/loader/cfs-cbm-posix.c b/platform/c64/loader/cfs-cbm-posix.c new file mode 100644 index 000000000..de07b8727 --- /dev/null +++ b/platform/c64/loader/cfs-cbm-posix.c @@ -0,0 +1,146 @@ +/* + * 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 + * + * $Id: cfs-cbm-posix.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#include "contiki.h" + +#include "log.h" +#include "cfs.h" +#include "cfs-service.h" + +#include +#include +#include +#include + + + +static int s_open(const char *n, int f); +static void s_close(int f); +static int s_read(int f, char *b, unsigned int l); +static int s_write(int f, char *b, unsigned int l); +static int s_opendir(struct cfs_dir *p, const char *n); +static int s_readdir(struct cfs_dir *p, struct cfs_dirent *e); +static int s_closedir(struct cfs_dir *p); + +static const struct cfs_service_interface interface = + { + CFS_SERVICE_VERSION, + s_open, + s_close, + s_read, + s_write, + s_opendir, + s_readdir, + s_closedir + }; + +EK_EVENTHANDLER(eventhandler, ev, data); +EK_PROCESS(proc, CFS_SERVICE_NAME ": KERNAL", EK_PRIO_NORMAL, + eventhandler, NULL, (void *)&interface); + +/*---------------------------------------------------------------------------*/ +LOADER_INIT_FUNC(cfs_cbm_init, arg) +{ + arg_free(arg); + ek_service_start(CFS_SERVICE_NAME, &proc); +} +/*---------------------------------------------------------------------------*/ +EK_EVENTHANDLER(eventhandler, ev, data) +{ + switch(ev) { + case EK_EVENT_INIT: + case EK_EVENT_REPLACE: + log_message("Starting KERNAL CFS", ""); + break; + case EK_EVENT_REQUEST_REPLACE: + ek_replace((struct ek_proc *)data, &interface); + break; + case EK_EVENT_REQUEST_EXIT: + ek_exit(); + break; + } +} +/*---------------------------------------------------------------------------*/ +static int +s_open(const char *n, int f) +{ + if(f == CFS_READ) { + return open(n, O_RDONLY); + } else { + return open(n, O_CREAT|O_RDWR); + } +} +/*---------------------------------------------------------------------------*/ +static void +s_close(int f) +{ + close(f); +} +/*---------------------------------------------------------------------------*/ +static int +s_read(int f, char *b, unsigned int l) +{ + return read(f, b, l); +} +/*---------------------------------------------------------------------------*/ +static int +s_write(int f, char *b, unsigned int l) +{ + return write(f, b, l); +} +/*---------------------------------------------------------------------------*/ +static int +s_opendir(struct cfs_dir *p, const char *n) +{ + return cbm_opendir(4, 8); +} +/*---------------------------------------------------------------------------*/ +static int +s_readdir(struct cfs_dir *p, struct cfs_dirent *e) +{ + struct cbm_dirent ce; + int ret; + ret = cbm_readdir(4, &ce); + strncpy(e->name, ce.name, sizeof(ce.name)); + e->size = ce.size; + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +s_closedir(struct cfs_dir *p) +{ + cbm_closedir(4); + return 1; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/loader/cfs-cbm.c b/platform/c64/loader/cfs-cbm.c new file mode 100644 index 000000000..13eae72b9 --- /dev/null +++ b/platform/c64/loader/cfs-cbm.c @@ -0,0 +1,123 @@ +/* + * 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 + * + * $Id: cfs-cbm.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#include "contiki.h" + +#include "cfs/cfs.h" +#include "cfs/cfs-service.h" + +#include +#include + +static int s_open(const char *n, int f); +static void s_close(int f); +static int s_read(int f, char *b, unsigned int l); +static int s_write(int f, char *b, unsigned int l); +static int s_opendir(struct cfs_dir *p, const char *n); +static int s_readdir(struct cfs_dir *p, struct cfs_dirent *e); +static int s_closedir(struct cfs_dir *p); + +SERVICE(cfs_cbm_service, cfs_service, +{ s_open, s_close, s_read, s_write, s_opendir, s_readdir, s_closedir }); + + +PROCESS(cfs_cbm_process, "CFS KERNAL service"); +PROCESS_THREAD(cfs_cbm_process, ev, data) { + PROCESS_BEGIN(); + + log_message("Starting KERNAL CFS", ""); + SERVICE_REGISTER(cfs_cbm_service); + + while(ev != PROCESS_EVENT_SERVICE_REMOVED && + ev != PROCESS_EVENT_EXIT) { + PROCESS_WAIT_EVENT(); + } + + SERVICE_REMOVE(cfs_cbm_service); + + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +static int +s_open(const char *n, int f) +{ + if(cbm_open(2, _curunit, f, n) == 0) { + return 2; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static void +s_close(int f) +{ + cbm_close(f); +} +/*---------------------------------------------------------------------------*/ +static int +s_read(int f, char *b, unsigned int l) +{ + return cbm_read(f, b, l); +} +/*---------------------------------------------------------------------------*/ +static int +s_write(int f, char *b, unsigned int l) +{ + return cbm_write(f, b, l); +} +/*---------------------------------------------------------------------------*/ +static int +s_opendir(struct cfs_dir *p, const char *n) +{ + return cbm_opendir(4, _curunit); +} +/*---------------------------------------------------------------------------*/ +static int +s_readdir(struct cfs_dir *p, struct cfs_dirent *e) +{ + struct cbm_dirent ce; + int ret; + ret = cbm_readdir(4, &ce); + strncpy(e->name, ce.name, sizeof(ce.name)); + e->size = ce.size; + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +s_closedir(struct cfs_dir *p) +{ + cbm_closedir(4); + return 1; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/loader/cfs-cbm.h b/platform/c64/loader/cfs-cbm.h new file mode 100644 index 000000000..7e287fcb0 --- /dev/null +++ b/platform/c64/loader/cfs-cbm.h @@ -0,0 +1,39 @@ +/* + * 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 + * + * $Id: cfs-cbm.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#ifndef __CFS_CBM_H__ +#define __CFS_CBM_H__ + + +#endif /* __CFS_CBM_H__ */ diff --git a/platform/c64/loader/cfs-init.c b/platform/c64/loader/cfs-init.c new file mode 100644 index 000000000..c4148d741 --- /dev/null +++ b/platform/c64/loader/cfs-init.c @@ -0,0 +1,93 @@ +/* + * 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 + * + * $Id: cfs-init.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#include "contiki.h" + +#include "cfs/cfs.h" +#include "cfs/cfs-service.h" + +#include +#include + +static int s_open(const char *n, int f); +static void s_close(int f); +static int s_read(int f, char *b, unsigned int l); +static int s_write(int f, char *b, unsigned int l) {return -1;} +static int s_opendir(struct cfs_dir *p, const char *n) {return -1;} +static int s_readdir(struct cfs_dir *p, struct cfs_dirent *e) {return -1;} +static int s_closedir(struct cfs_dir *p) {return -1;} + +SERVICE(cfs_posix_service, cfs_service, +{ s_open, s_close, s_read, s_write, s_opendir, s_readdir, s_closedir }); + +PROCESS(cfs_posix_process, "CFS POSIX service"); +PROCESS_THREAD(cfs_posix_process, ev, data) { + PROCESS_BEGIN(); + + SERVICE_REGISTER(cfs_posix_service); + + while(ev != PROCESS_EVENT_SERVICE_REMOVED && + ev != PROCESS_EVENT_EXIT) { + PROCESS_WAIT_EVENT(); + } + + SERVICE_REMOVE(cfs_posix_service); + + PROCESS_END(); +} + +/*---------------------------------------------------------------------------*/ +#include +static int +s_open(const char *n, int f) +{ + if(cbm_open(2, _curunit, CBM_READ, n) == 0) { + /* printf("Opening with _curunit %d\n", _curunit);*/ + return 2; + } + return -1; +} +/*---------------------------------------------------------------------------*/ +static void +s_close(int f) +{ + cbm_close(f); +} +/*---------------------------------------------------------------------------*/ +static int +s_read(int f, char *b, unsigned int l) +{ + return cbm_read(f, b, l); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/loader/cfs-init.h b/platform/c64/loader/cfs-init.h new file mode 100644 index 000000000..152be33ff --- /dev/null +++ b/platform/c64/loader/cfs-init.h @@ -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. 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 + * + * $Id: cfs-init.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#ifndef __CFS_INIT_H__ +#define __CFS_INIT_H__ + +#include "contiki.h" + +PROCESS_NAME(cfs_init_process); + +#endif /* __CFS_INIT_H__ */ diff --git a/platform/c64/loader/loader-arch.c b/platform/c64/loader/loader-arch.c new file mode 100644 index 000000000..1db87d86b --- /dev/null +++ b/platform/c64/loader/loader-arch.c @@ -0,0 +1,140 @@ +/** + * \file + * File loader implementation. + * \author Adam Dunkels + * + * This file implements dynamically loadable files for Contiki using + * the cc65 module loading system. The actual file operations are + * implemented in other files. + */ + +/* + * 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: loader-arch.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include +#include + +#include "cfs/cfs.h" + +#include "sys/loader.h" + +#include "loader-arch.h" + +static int __fastcall__ +do_read(int f, char *buf, unsigned int len) +{ + return cfs_read(f, buf, len); +} + +struct mod_ctrl ctrl = { + (void *)do_read /* Read from disk */ +}; + + +struct loader_arch_hdr { + char arch[8]; + char version[8]; + + char initfunc[1]; +}; + +/*-----------------------------------------------------------------------------------*/ +/** + * Load a program from disk and execute it. + * + * Code originally written by Ullrich von Bassewitz. + */ +/*-----------------------------------------------------------------------------------*/ +unsigned char +load(const char *name) +{ + unsigned char res; + + /* Now open the file */ + ctrl.callerdata = cfs_open(name, 0); + if(ctrl.callerdata < 0) { + /* Could not open the file, display an error and return */ + /* ### */ + return LOADER_ERR_OPEN; + } + + /* Load the module */ + res = mod_load(&ctrl); + + /* Close the input file */ + cfs_close(ctrl.callerdata); + + /* Check the return code */ + if(res != MLOAD_OK) { + /* Wrong module, out of memory or whatever. Print an error + * message and return. + */ + /* ### */ + return res; + } + + /* We've successfully loaded the module. */ + + return LOADER_OK; +} +/*-----------------------------------------------------------------------------------*/ +/** + * Load and start a program. + * + * \param name The name of the program file. + * \param arg A pointer that will be passed to the new process. + */ +/*-----------------------------------------------------------------------------------*/ +unsigned char +loader_arch_load(const char *name, char *arg) +{ + unsigned char r; + struct loader_arch_hdr *hdr; + + r = load(name); + if(r != MLOAD_OK) { + return r; + } + hdr = (struct loader_arch_hdr *)ctrl.module; + + /* Check the program header and see that version and architecture + matches. */ + + /* Call the init function. */ + ((void (*)(char *))hdr->initfunc)(arg); + + return LOADER_OK; +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/main.c b/platform/c64/main.c new file mode 100644 index 000000000..d12bc20ca --- /dev/null +++ b/platform/c64/main.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2002-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 operating system + * + * $Id: main.c,v 1.1 2006/06/17 22:41:25 adamdunkels Exp $ + * + */ + +#include "contiki.h" + +#include "ctk/ctk.h" +#include "ctk/ctk-draw.h" + +#include "program-handler.h" + + +#include "contiki-net.h" + +#include "configedit-dsc.h" +#include "directory-dsc.h" +#include "processes-dsc.h" + +#include "cfs-cbm.h" +#include "cfs-init.h" + + +#include + +PROCINIT(&tcpip_process, &resolv_process, /*&cfs_init_process,*/ + &ctk_process, &etimer_process, &program_handler_process); + +unsigned char +uip_fw_forward(void) +{ + return 0; +} +void +uip_fw_periodic(void) +{ + return; +} +/*---------------------------------------------------------------------------*/ +void +log_message(char *part1, char *part2) +{ + while(*part1 != 0) { + cbm_k_bsout(*part1++); + } + + while(*part2 != 0) { + cbm_k_bsout(*part2++); + } + + + cbm_k_bsout('\n'); +} +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + return clock(); +} +/*---------------------------------------------------------------------------*/ +void +main(void) +{ + + log_message("Starting ", CONTIKI_VERSION_STRING); + + process_init(); + + log_message(": TCP/IP", ""); + + procinit_init(); + + /* tcpip_init(NULL); + + resolv_init(NULL); */ + + log_message(": CTK GUI", ""); + /* ctk_init();*/ + + log_message(": Initial filesystem", ""); + /* cfs_init_init(NULL);*/ + + /* program_handler_init();*/ + + /* + program_handler_add(&directory_dsc, "Directory", 1); + program_handler_add(&configedit_dsc, "Configuration", 1); + program_handler_add(&processes_dsc, "Processes", 1); */ + + + log_message("Starting process scheduling", ""); + + while(1) { + if(process_run() == 0) { + program_handler_load("welcome.prg", NULL); + break; + } + } + + + while(1) { + process_run(); + } +} +/*---------------------------------------------------------------------------*/ +void +reset(void) +{ + asm("lda #$36"); + asm("sta $01"); + asm("jmp $fce2"); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/net/cs8900a.c b/platform/c64/net/cs8900a.c new file mode 100644 index 000000000..8ab5dbf33 --- /dev/null +++ b/platform/c64/net/cs8900a.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2001, 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 C64 RealAudio server demo project. + * + * $Id: cs8900a.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +/* cs8900a.c: device driver for the CS8900a chip in 8-bit mode. Mostly + written in 6502 assembler for speed. */ + +#include "cs8900a.h" +#include "contiki-net.h" + +extern u8_t *cs8900a_rxtxreg, + *cs8900a_txcmd, + *cs8900a_txlen, + *cs8900a_packetpp, + *cs8900a_ppdata; + +static u16_t len; +static u16_t cnt; + + +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +cs8900a_init(void) +{ + /* Turn on transmission and reception of frames. */ + /* PACKETPP = 0x0112; + PPDATA = 0x00c0; */ + asm("lda #$12"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda #$c0"); + asm("sta %v", cs8900a_ppdata); + asm("lda #$00"); + asm("sta %v+1", cs8900a_ppdata); + + /* Accept valid unicast+broadcast frames. */ + /* PACKETPP = 0x0104; + PPDATA = 0x0d05; */ + asm("lda #$04"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda #$05"); + asm("sta %v", cs8900a_ppdata); + asm("lda #$0d"); + asm("sta %v+1", cs8900a_ppdata); + + /* Set MAC address. */ + /* PACKETPP = 0x0158; + PPDATA = (ETHADDR1 << 8) | (ETHADDR0); */ + asm("lda #$58"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v", uip_ethaddr); + asm("sta %v", cs8900a_ppdata); + asm("lda %v+1", uip_ethaddr); + asm("sta %v+1", cs8900a_ppdata); + + /* PACKETPP = 0x015a; + PPDATA = (ETHADDR3 << 8) | (ETHADDR2); */ + asm("lda #$5a"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v+2", uip_ethaddr); + asm("sta %v", cs8900a_ppdata); + asm("lda %v+3", uip_ethaddr); + asm("sta %v+1", cs8900a_ppdata); + + /* PACKETPP = 0x015c; + PPDATA = (ETHADDR5 << 8) | (ETHADDR4); */ + asm("lda #$5c"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v+4", uip_ethaddr); + asm("sta %v", cs8900a_ppdata); + asm("lda %v+5", uip_ethaddr); + asm("sta %v+1", cs8900a_ppdata); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void +cs8900a_send(void) +{ + /* Transmit command. */ + asm("lda #$c0"); + asm("sta %v", cs8900a_txcmd); + asm("lda #$00"); + asm("sta %v+1", cs8900a_txcmd); + asm("lda %v", uip_len); + asm("sta %v", cs8900a_txlen); + asm("lda %v+1", uip_len); + asm("sta %v+1", cs8900a_txlen); + + asm("ldy #8"); +tryagain: + /* Check for avaliable buffer space. */ + asm("lda #$38"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v+1", cs8900a_ppdata); + asm("and #1"); + asm("bne %g", send); + + /* No space avaliable, skip a received frame and try again. */ + asm("lda #$02"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v", cs8900a_ppdata); + asm("ora #$40"); + asm("sta %v", cs8900a_ppdata); + + asm("dey"); + asm("bne %g", tryagain); + return; + + /* Send the frame. */ +send: + + /* First, send 14+40=54 bytes of header. */ + asm("ldy #0"); +sendloop1: + asm("lda %v,y", uip_buf); + asm("sta %v", cs8900a_rxtxreg); + asm("iny"); + asm("lda %v,y", uip_buf); + asm("sta %v+1", cs8900a_rxtxreg); + asm("iny"); + asm("cpy #%b", UIP_LLH_LEN + UIP_TCPIP_HLEN); + asm("bne %g", sendloop1); + + if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { + return; + } + + /* Next, send rest of the packet. */ + cnt = uip_len - (UIP_LLH_LEN + UIP_TCPIP_HLEN); + + asm("lda %v", cnt); + asm("lsr"); + asm("bcc %g", noinc); + asm("inc %v", cnt); + asm("bne %g", noinc); + asm("inc %v+1", cnt); +noinc: + + asm("lda %v", uip_appdata); + asm("sta ptr1"); + asm("lda %v+1", uip_appdata); + asm("sta ptr1+1"); + + asm("ldy #0"); +sendloop2: + asm("lda (ptr1),y"); + asm("sta %v", cs8900a_rxtxreg); + asm("iny"); + asm("lda (ptr1),y"); + asm("sta %v+1", cs8900a_rxtxreg); + asm("iny"); + asm("bne %g", check); + asm("inc ptr1+1"); +check: + asm("cpy %v", cnt); + asm("bne %g", sendloop2); + asm("dec %v+1", cnt); + asm("bpl %g", sendloop2); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +skip_frame(void) +{ + /* PACKETPP = 0x0102; + PPDATA = PPDATA | 0x0040; */ + asm("lda #$02"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v", cs8900a_ppdata); + asm("ora #$40"); + asm("sta %v", cs8900a_ppdata); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +u16_t +cs8900a_poll(void) +{ + /* Check receiver event register to see if there are any valid + unicast frames avaliable. */ + /* PACKETPP = 0x0124; + if(PPDATA & 0x000d == 0x0000) { + return 0; + } + */ + asm("lda #$24"); + asm("sta %v", cs8900a_packetpp); + asm("lda #$01"); + asm("sta %v+1", cs8900a_packetpp); + asm("lda %v+1", cs8900a_ppdata); + asm("and #$0d"); + asm("cmp #$00"); + asm("bne %g", noreturn); + /* No frame ready. */ + return 0; + +noreturn: + /* Process the incoming frame. */ + + /* Read receiver event and discard it. */ + /* RXTXREG; */ + asm("lda %v+1", cs8900a_rxtxreg); + asm("lda %v", cs8900a_rxtxreg); + + /* Read frame length. */ + /* cnt = len = RXTXREG; */ + asm("lda %v+1", cs8900a_rxtxreg); + asm("sta %v+1", len); + asm("sta %v+1", cnt); + asm("lda %v", cs8900a_rxtxreg); + asm("sta %v", len); + asm("sta %v", cnt); + + asm("lsr"); + asm("bcc %g", noinc); + asm("inc %v", cnt); + asm("bne %g", noinc); + asm("inc %v+1", cnt); +noinc: + + if(cnt > UIP_BUFSIZE) { + skip_frame(); + return 0; + } + + /* Read bytes into uip_buf. */ + asm("lda #<%v", uip_buf); + asm("sta ptr1"); + asm("lda #>%v", uip_buf); + asm("sta ptr1+1"); + + asm("ldy #0"); +readloop: + asm("lda %v", cs8900a_rxtxreg); + asm("sta (ptr1),y"); + asm("iny"); + asm("lda %v+1", cs8900a_rxtxreg); + asm("sta (ptr1),y"); + asm("iny"); + asm("bne %g", check); + asm("inc ptr1+1"); +check: + asm("cpy %v", cnt); + asm("bne %g", readloop); + asm("dec %v+1", cnt); + asm("bpl %g", readloop); + return len; +} +#pragma optimize(pop) diff --git a/platform/c64/net/cs8900a.h b/platform/c64/net/cs8900a.h new file mode 100644 index 000000000..949715920 --- /dev/null +++ b/platform/c64/net/cs8900a.h @@ -0,0 +1,44 @@ +/* + * 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 + * + * $Id: cs8900a.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ +#ifndef __CS8900A_H__ +#define __CS8900A_H__ + +#include "uip_arch.h" + +void cs8900a_init(void); +void cs8900a_send(void); +u16_t cs8900a_poll(void); + +#endif /* __CS8900A_H__ */ diff --git a/platform/c64/net/eth64-drv.c b/platform/c64/net/eth64-drv.c new file mode 100644 index 000000000..cf603a28f --- /dev/null +++ b/platform/c64/net/eth64-drv.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: eth64-drv.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "contiki-net.h" +#include "lan91c96.h" + +static u8_t output(void); + +static const struct uip_eth_addr addr = + {{0x00,0x00,0x00,0x64,0x64,0x64}}; + +SERVICE(eth64_drv_service, packet_service, { output };); + +PROCESS(eth64_drv_process, "ETH64 driver"); + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + uip_arp_out(); + lan91c96_send(); + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = lan91c96_poll(); + if(uip_len > 0) { + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + lan91c96_send(); + } + } + } + +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(eth64_drv_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + + uip_setethaddr(addr); + + lan91c96_init(); + + SERVICE_REGISTER(eth64_drv_service); + + process_poll(ð64_drv_process); + + while(1) { + PROCESS_YIELD(); + } + + PROCESS_END(); +} + + +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/net/eth64-dsc.c b/platform/c64/net/eth64-dsc.c new file mode 100644 index 000000000..605a82a80 --- /dev/null +++ b/platform/c64/net/eth64-dsc.c @@ -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: eth64-dsc.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon lan91c96_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(lan91c96_dsc, + "IDE64/ETH64 driver", + "lan91c96.drv", + lan91c96_init, + &lan91c96_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char lan91c96icon_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 lan91c96icon_textmap[9] = { + 'I', 'D', 'E', + ' ', '6', '4', + 'E', 'T', 'H' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon lan91c96_icon = + {CTK_ICON("ETH64 driver", lan91c96icon_bitmap, lan91c96icon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/net/eth64-dump-drv.c b/platform/c64/net/eth64-dump-drv.c new file mode 100644 index 000000000..bcace9c86 --- /dev/null +++ b/platform/c64/net/eth64-dump-drv.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: eth64-dump-drv.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "contiki-net.h" +#include "ctk/ctk.h" + +#include "lan91c96.h" + +static u8_t output(void); + +static const struct uip_eth_addr addr = + {{0x00,0x00,0x00,0x64,0x64,0x64}}; + +SERVICE(eth64_drv_service, packet_service, { output };); + +PROCESS(eth64_drv_process, "Eth64 driver"); + +#define DUMP_WIDTH 38 +#define DUMP_HEIGHT 20 +static struct ctk_window window; +static char dump[DUMP_WIDTH * DUMP_HEIGHT]; +static struct ctk_label dumplabel = + {CTK_LABEL(0, 0, DUMP_WIDTH, DUMP_HEIGHT, dump)}; +static void +dump_packet(void) +{ + memcpy(dump, &dump[DUMP_WIDTH], DUMP_WIDTH * (DUMP_HEIGHT - 1)); + tcpdump_print(&dump[DUMP_WIDTH * (DUMP_HEIGHT - 1)], DUMP_WIDTH); + CTK_WIDGET_REDRAW(&dumplabel); +} + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + + uip_arp_out(); + lan91c96_send(); + + dump_packet(); + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = lan91c96_poll(); + if(uip_len > 0) { + + dump_packet(); + + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + lan91c96_send(); + } + } + } + +} +/*---------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +init_eth64(void) +{ + asm("lda #1"); + asm("ora $de01"); + asm("sta $de01"); +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(eth64_drv_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + + uip_setethaddr(addr); + init_eth64(); + lan91c96_init(); + + ctk_window_new(&window, DUMP_WIDTH, DUMP_HEIGHT, "RR-Net dump"); + CTK_WIDGET_ADD(&window, &dumplabel); + ctk_window_open(&window); + + + SERVICE_REGISTER(eth64_drv_service); + + process_poll(ð64_drv_process); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT); + } + + ctk_window_close(&window); + + PROCESS_END(); +} + + +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/net/lan91c96.c b/platform/c64/net/lan91c96.c new file mode 100644 index 000000000..8963ebf9a --- /dev/null +++ b/platform/c64/net/lan91c96.c @@ -0,0 +1,453 @@ +/* + * uIP lan91c96 (smc9194) driver + * Based on cs8900a driver, copyrighted (c) 2001, by Adam Dunkels + * Copyright (c) 2003, Josef Soucek + * All rights reserved. + * + * Ethernet card for Commodore 64, based on lan91c96 chip + * is a device created by IDE64 Project team. + * More information: http://ide64.come.to + * + * 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. + * + * $Id: lan91c96.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "lan91c96.h" +#include "contiki-net.h" + +#include + +// #define DEBUG + +#define ETHBASE 0xde10 + +#define ETHBSR ETHBASE+0x0e /* Bank select register R/W (2B) */ + +/* Register bank 0 */ + +#define ETHTCR ETHBASE /* Transmition control register R/W (2B) */ +#define ETHEPHSR ETHBASE+2 /* EPH status register R/O (2B) */ +#define ETHRCR ETHBASE+4 /* Receive control register R/W (2B) */ +#define ETHECR ETHBASE+6 /* Counter register R/O (2B) */ +#define ETHMIR ETHBASE+8 /* Memory information register R/O (2B) */ +#define ETHMCR ETHBASE+0x0a /* Memory Config. reg. +0 R/W +1 R/O (2B) */ + +/* Register bank 1 */ + +#define ETHCR ETHBASE /* Configuration register R/W (2B) */ +#define ETHBAR ETHBASE+2 /* Base address register R/W (2B) */ +#define ETHIAR ETHBASE+4 /* Individual address register R/W (6B) */ +#define ETHGPR ETHBASE+0x0a /* General address register R/W (2B) */ +#define ETHCTR ETHBASE+0x0c /* Control register R/W (2B) */ + +/* Register bank 2 */ + +#define ETHMMUCR ETHBASE /* MMU command register W/O (1B) */ +#define ETHAUTOTX ETHBASE+1 /* AUTO TX start register R/W (1B) */ +#define ETHPNR ETHBASE+2 /* Packet number register R/W (1B) */ +#define ETHARR ETHBASE+3 /* Allocation result register R/O (1B) */ +#define ETHFIFO ETHBASE+4 /* FIFO ports register R/O (2B) */ +#define ETHPTR ETHBASE+6 /* Pointer register R/W (2B) */ +#define ETHDATA ETHBASE+8 /* Data register R/W (4B) */ +#define ETHIST ETHBASE+0x0c /* Interrupt status register R/O (1B) */ +#define ETHACK ETHBASE+0x0c /* Interrupt acknowledge register W/O (1B) */ +#define ETHMSK ETHBASE+0x0d /* Interrupt mask register R/W (1B) */ + +/* Register bank 3 */ + +#define ETHMT ETHBASE /* Multicast table R/W (8B) */ +#define ETHMGMT ETHBASE+8 /* Management interface R/W (2B) */ +#define ETHREV ETHBASE+0x0a /* Revision register R/W (2B) */ +#define ETHERCV ETHBASE+0x0c /* Early RCV register R/W (2B) */ + +#define BANK(num) asm("lda #%b", num); asm("sta %w", ETHBSR); + +#ifdef DEBUG +static void print_packet(u8_t *, u16_t); +#endif + +static u8_t packet_status; +static u16_t packet_length; + + +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void lan91c96_init(void) +{ + /* Check if high byte is 0x33 */ + asm("lda %w", ETHBSR+1); + asm("cmp #$33"); + asm("beq %g", L1); + + asm("inc $d021"); /* Error */ + +L1: + /* Reset ETH card */ + BANK(0); + asm("lda #%%10000000"); /* Software reset */ + asm("sta %w", ETHRCR+1); + + asm("lda #0"); + asm("sta %w", ETHRCR); + asm("sta %w", ETHRCR+1); + + /* delay */ + asm("ldy #0"); +L2: + asm("cmp ($ff,x)"); /* 6 cycles */ + asm("cmp ($ff,x)"); /* 6 cycles */ + asm("dey"); /* 2 cycles */ + asm("bne %g", L2); /* 3 cycles */ + /* 17*256=4352 => 4,4 ms */ + + /* Enable transmit and receive */ + asm("lda #%%10000001"); /* Enable transmit TXENA, PAD_EN */ + asm("sta %w", ETHTCR); + asm("lda #%%00000011"); /* Enable receive, strip CRC ??? */ + asm("sta %w", ETHRCR+1); + + BANK(1); + asm("lda %w", ETHCR+1); + asm("ora #%%00010000"); /* No wait (IOCHRDY) */ + asm("sta %w", ETHCR+1); + + asm("lda #%%00001001"); /* Auto release */ + asm("sta %w", ETHCTR+1); + + /* Set MAC address */ + asm("lda %v", uip_ethaddr); + asm("sta %w", ETHIAR); + asm("lda %v+1", uip_ethaddr); + asm("sta %w", ETHIAR+1); + asm("lda %v+2", uip_ethaddr); + asm("sta %w", ETHIAR+2); + asm("lda %v+3", uip_ethaddr); + asm("sta %w", ETHIAR+3); + asm("lda %v+4", uip_ethaddr); + asm("sta %w", ETHIAR+4); + asm("lda %v+5", uip_ethaddr); + asm("sta %w", ETHIAR+5); + + BANK(2); + asm("lda #%%00001111"); /* RCV INT, ALLOC INT, TX INT, TX EMPTY */ + asm("sta %w", ETHMSK); +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +u16_t lan91c96_poll(void) +{ +#ifdef DEBUG + BANK(0); + printf("RAM: %d ", ((*(unsigned int *)(ETHMIR)) & 0xff00)); + BANK(2); +#endif + + asm("lda %w", ETHIST); + asm("and #%%00000001"); /* RCV INT */ + asm("bne %g", L1); + + /* No packet available */ + return 0; + +L1: + +#ifdef DEBUG + printf("RCV: IRQ\n"); +#endif + + asm("lda #0"); + asm("sta %w", ETHPTR); + asm("lda #%%11100000"); /* RCV,AUTO INCR.,READ */ + asm("sta %w", ETHPTR+1); + + asm("lda %w", ETHDATA); /* Status word */ + asm("lda %w", ETHDATA); + asm("sta %v", packet_status); /* High byte only */ + + asm("lda %w", ETHDATA); /* Total number of bytes */ + asm("sta %v", packet_length); + asm("lda %w", ETHDATA); + asm("sta %v+1", packet_length); + + /* Last word contain 'last data byte' and 0x60 */ + /* or 'fill byte' and 0x40 */ + + packet_length -= 6; /* The packet contains 3 extra words */ + + asm("lda %v", packet_status); + asm("and #$10"); + asm("beq %g", L2); + + packet_length++; + +#ifdef DEBUG + printf("RCV: odd number of bytes\n"); +#endif + +L2: + +#ifdef DEBUG + printf("RCV: L:%d ST-HIGH:0x%02x ", packet_length, packet_status); +#endif + + if(packet_length > UIP_BUFSIZE) { + + /* Remove and release RX packet from FIFO */ + asm("lda #%%10000000"); + asm("sta %w", ETHMMUCR); + +#ifdef DEBUG + printf("RCV: UIP_BUFSIZE exceeded - packet dropped!\n"); +#endif + + return 0; + } + + asm("lda #<%v", uip_buf); + asm("sta ptr1"); + asm("lda #>%v", uip_buf); + asm("sta ptr1+1"); + + asm("lda %v+1", packet_length); + asm("sta tmp1"); + + asm("ldy #0"); +L3: + asm("lda %w", ETHDATA); + asm("sta (ptr1),y"); + asm("iny"); + asm("bne %g", L4); + asm("inc ptr1+1"); +L4: + asm("cpy %v", packet_length); + asm("bne %g", L3); + asm("dec tmp1"); + asm("bpl %g", L3); + + /* Remove and release RX packet from FIFO */ + asm("lda #%%10000000"); + asm("sta %w", ETHMMUCR); + +#ifdef DEBUG + print_packet(uip_buf, packet_length); +#endif + + return packet_length; +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#pragma optimize(push, off) +void lan91c96_send(void) +{ + /* First 14+40 (IP and TCP header) is send from uip_buf */ + /* than data from uip_appdata */ + +#ifdef DEBUG + printf("SND: send packet\n"); +#endif + + asm("lda %v+1", uip_len); + asm("ora #%%00100000"); /* Allocate memory for TX */ + asm("sta %w", ETHMMUCR); + + asm("ldy #8"); /* Wait... */ +L1: /* Wait for allocation ready */ + asm("lda %w", ETHIST); + asm("and #%%00001000"); /* ALLOC INT */ + asm("bne %g", L2); + asm("dey"); + asm("bne %g", L1); + +#ifdef DEBUG + printf("SND: ERR: memory alloc timeout\n"); +#endif + + return; + +L2: + +#ifdef DEBUG + printf("SND: packet memory allocated\n"); +#endif + + asm("lda #%%00001000"); /* Acknowledge int, is it necessary ??? */ + asm("sta %w", ETHACK); + + asm("lda %w", ETHARR); + asm("sta %w", ETHPNR); /* Set packet address */ + + asm("lda #0"); + asm("sta %w", ETHPTR); + asm("lda #%%01000000"); /* AUTO INCR. */ + asm("sta %w", ETHPTR+1); + +#ifdef DEBUG + printf("SND: L:%d ", uip_len); +#endif + + asm("lda #0"); /* Status written by CSMA */ + asm("sta %w", ETHDATA); + asm("sta %w", ETHDATA); + + asm("lda %v", uip_len); + asm("and #$01"); + asm("beq %g", L3); + + packet_length = uip_len + 5; + asm("jmp %g", L4); + +L3: + packet_length = uip_len + 6; /* +6 for status word, length and ctl byte */ + +L4: + +#ifdef DEBUG + printf("SND: L:%d ", packet_length); +#endif + + asm("lda %v", packet_length); + asm("sta %w", ETHDATA); + asm("lda %v+1", packet_length); + asm("sta %w", ETHDATA); + +#ifdef DEBUG + print_packet(uip_buf, uip_len); +#endif + + /* Send 14+40=54 bytes of header */ + + if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) { + +#ifdef DEBUG + printf("SND: short packet sent.\n"); +#endif + + asm("ldy #0"); +L5: + asm("lda %v,y", uip_buf); + asm("sta %w", ETHDATA); + asm("iny"); + asm("cpy %v", uip_len); + asm("bne %g", L5); + + } else { + + asm("ldy #0"); +L6: + asm("lda %v,y", uip_buf); + asm("sta %w", ETHDATA); + asm("iny"); + asm("cpy #%b", UIP_LLH_LEN + UIP_TCPIP_HLEN); + asm("bne %g", L6); + + packet_length = uip_len - (UIP_LLH_LEN + UIP_TCPIP_HLEN); + + asm("lda %v", uip_appdata); /* uip_appdata is pointer */ + asm("sta ptr1"); + asm("lda %v+1", uip_appdata); + asm("sta ptr1+1"); + + asm("ldy #0"); +L7: + asm("lda (ptr1),y"); + asm("sta %w", ETHDATA); + asm("iny"); + asm("bne %g", L8); + asm("inc ptr1+1"); +L8: + asm("cpy %v", packet_length); + asm("bne %g", L7); + asm("dec %v+1", packet_length); + asm("bpl %g", L7); + } + + asm("lda %v", packet_length); + asm("and #$01"); + asm("beq %g", L9); + + asm("lda #%%00100000"); + asm("sta %w", ETHDATA); /* Control byte */ + + asm("lda #%%11000000"); /* ENQUEUE PACKET - transmit packet */ + asm("sta %w", ETHMMUCR); + +#ifdef DEBUG + printf("\n## %02x", *(unsigned char *)(ETHIST)); +#endif + + return; + +L9: + asm("lda #0"); + asm("sta %w", ETHDATA); /* Fill byte */ + asm("sta %w", ETHDATA); /* Control byte */ + + asm("lda #%%11000000"); /* ENQUEUE PACKET - transmit packet */ + asm("sta %w", ETHMMUCR); + +#ifdef DEBUG + printf("\n## %02x\n", *(unsigned char *)(ETHIST)); +#endif + +} +#pragma optimize(pop) +/*-----------------------------------------------------------------------------------*/ +#ifdef DEBUG +static void print_packet(u8_t *buf, u16_t length) +{ + int i; + int remainder; + int lines; + u8_t a; + int cur; + int address=0; + + printf("\nPacket of length %d \n", length); + + lines = length / 8; + remainder = length % 8; + + for(i = 0; i < lines; i++) { + printf(":%04x ", address=i*8); + + for(cur = 0; cur < 8; cur++) { + a = *(buf++); + printf("%02x ", a); + } + printf("\n"); + } + + printf(":%04x ", address+8); + + for (i = 0; i < remainder; i++) { + a = *(buf++); + printf("%02x ", a); + } + printf("\n"); +} +#endif /* DEBUG */ diff --git a/platform/c64/net/lan91c96.h b/platform/c64/net/lan91c96.h new file mode 100644 index 000000000..e425cda41 --- /dev/null +++ b/platform/c64/net/lan91c96.h @@ -0,0 +1,45 @@ +/* + * 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 + * + * $Id: lan91c96.h,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + */ + +#ifndef __LAN91C96_H__ +#define __LAN91C96_H__ + +#include "uip_arch.h" + +void lan91c96_init(void); +void lan91c96_send(void); +u16_t lan91c96_poll(void); + +#endif /* __LAN91C96_H__ */ diff --git a/platform/c64/net/rrnet-drv.c b/platform/c64/net/rrnet-drv.c new file mode 100644 index 000000000..5811b464f --- /dev/null +++ b/platform/c64/net/rrnet-drv.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: rrnet-drv.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "contiki-net.h" +#include "cs8900a.h" + + +static u8_t output(void); + +static const struct uip_eth_addr addr = + {{0x00,0x00,0x00,0x64,0x64,0x64}}; + +SERVICE(rrnet_drv_service, packet_service, { output };); + +PROCESS(rrnet_drv_process, "RRNet driver"); + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + uip_arp_out(); + cs8900a_send(); + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = cs8900a_poll(); + if(uip_len > 0) { + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + cs8900a_send(); + } + } + } + +} +/*---------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +init_rrnet(void) +{ + asm("lda #1"); + asm("ora $de01"); + asm("sta $de01"); +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rrnet_drv_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + uip_setethaddr(addr); + init_rrnet(); + cs8900a_init(); + + SERVICE_REGISTER(rrnet_drv_service); + + process_poll(&rrnet_drv_process); + + while(1) { + PROCESS_YIELD(); + } + + PROCESS_END(); +} + + +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/net/rrnet-dsc.c b/platform/c64/net/rrnet-dsc.c new file mode 100644 index 000000000..f168e5692 --- /dev/null +++ b/platform/c64/net/rrnet-dsc.c @@ -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: rrnet-dsc.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon rrnet_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(rrnet_dsc, + "RR-Net driver", + "rrnet.drv", + rrnet_init, + &rrnet_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char rrneticon_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 rrneticon_textmap[9] = { + 'R', 'R', '-', + 'N', 'e', 't', + 'D', 'R', 'V' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon rrnet_icon = + {CTK_ICON("RR-Net driver", rrneticon_bitmap, rrneticon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/net/rrnet-dump-drv.c b/platform/c64/net/rrnet-dump-drv.c new file mode 100644 index 000000000..d78f74e7e --- /dev/null +++ b/platform/c64/net/rrnet-dump-drv.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: rrnet-dump-drv.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +#include "contiki-net.h" +#include "cs8900a.h" + +#include "ctk/ctk.h" + +static u8_t output(void); + +static const struct uip_eth_addr addr = + {{0x00,0x00,0x00,0x64,0x64,0x64}}; + +SERVICE(rrnet_drv_service, packet_service, { output };); + +PROCESS(rrnet_drv_process, "RRNet driver"); + +#define DUMP_WIDTH 38 +#define DUMP_HEIGHT 20 +static struct ctk_window window; +static char dump[DUMP_WIDTH * DUMP_HEIGHT]; +static struct ctk_label dumplabel = + {CTK_LABEL(0, 0, DUMP_WIDTH, DUMP_HEIGHT, dump)}; +static void +dump_packet(void) +{ + memcpy(dump, &dump[DUMP_WIDTH], DUMP_WIDTH * (DUMP_HEIGHT - 1)); + tcpdump_print(&dump[DUMP_WIDTH * (DUMP_HEIGHT - 1)], DUMP_WIDTH); + CTK_WIDGET_REDRAW(&dumplabel); +} + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + + uip_arp_out(); + cs8900a_send(); + + dump_packet(); + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = cs8900a_poll(); + if(uip_len > 0) { + + dump_packet(); + + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + cs8900a_send(); + } + } + } + +} +/*---------------------------------------------------------------------------*/ +#pragma optimize(push, off) +static void +init_rrnet(void) +{ + asm("lda #1"); + asm("ora $de01"); + asm("sta $de01"); +} +#pragma optimize(pop) +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rrnet_drv_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + + uip_setethaddr(addr); + init_rrnet(); + cs8900a_init(); + + ctk_window_new(&window, DUMP_WIDTH, DUMP_HEIGHT, "RR-Net dump"); + CTK_WIDGET_ADD(&window, &dumplabel); + ctk_window_open(&window); + + + SERVICE_REGISTER(rrnet_drv_service); + + process_poll(&rrnet_drv_process); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT); + } + + ctk_window_close(&window); + + PROCESS_END(); +} + + +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/net/rs232dev-ss.c b/platform/c64/net/rs232dev-ss.c new file mode 100644 index 000000000..a341f440b --- /dev/null +++ b/platform/c64/net/rs232dev-ss.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2001, 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: rs232dev-ss.c,v 1.1 2006/06/17 22:41:26 adamdunkels Exp $ + * + */ + +/* + * This is a generic implementation of the SLIP protocol over an RS232 + * (serial) device. While initially intented for the C64, the code can + * easily be ported to other platforms as well. + * + * Huge thanks to Ullrich von Bassewitz of cc65 fame for + * and endless supply of bugfixes, insightsful comments and + * suggestions, and improvements to this code! + */ + +#include "rs232silversurfer.h" +#include +#include + + /* This will include the system specific header files as well */ +#if defined(__CBM__) +# include +#elif defined(__ATARI__) +# include +#endif + +#include "uip.h" + +#define SLIP_END 0300 +#define SLIP_ESC 0333 +#define SLIP_ESC_END 0334 +#define SLIP_ESC_ESC 0335 + + +#define SIO_RECV(c) while(rs232_get(&c) == RS_ERR_NO_DATA) +#define SIO_POLL(c) (rs232_get(&c) != RS_ERR_NO_DATA) +#define SIO_SEND(c) while(rs232_put(c) == RS_ERR_OVERFLOW) + +#define MAX_SIZE (UIP_BUFSIZE - UIP_LLH_LEN) + +static u8_t slip_buf[MAX_SIZE + 2]; + +static u16_t len, tmplen; + +#if 1 +#define printf(x) +#else +#include +#endif + + +/*-----------------------------------------------------------------------------------*/ +static void +rs232_err(char err) +{ + switch(err) { + case RS_ERR_OK: + printf("RS232 OK\n"); + break; + case RS_ERR_NOT_INITIALIZED: + printf("RS232 not initialized\n"); + break; + case RS_ERR_BAUD_TOO_FAST: + printf("RS232 baud too fast\n"); + break; + case RS_ERR_BAUD_NOT_AVAIL: + printf("RS232 baud rate not available\n"); + break; + case RS_ERR_NO_DATA: + printf("RS232 nothing to read\n"); + break; + case RS_ERR_OVERFLOW: + printf("RS232 overflow\n"); + break; + } + +} +/*-----------------------------------------------------------------------------------*/ +/* + * rs232dev_send(): + * + * Sends the packet in the uip_buf and uip_appdata buffers. The first + * 40 bytes of the packet (the IP and TCP headers) are read from the + * uip_buf buffer, and the following bytes (the application data) are + * read from the uip_appdata buffer. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +rs232dev_send(void) +{ + u16_t i; + u8_t *ptr; + u8_t c; + + SIO_SEND(SLIP_END); + + ptr = &uip_buf[UIP_LLH_LEN]; + for(i = 0; i < uip_len; ++i) { + if(i == UIP_TCPIP_HLEN) { + ptr = uip_appdata; + } + c = *ptr++; + switch(c) { + case SLIP_END: + SIO_SEND(SLIP_ESC); + SIO_SEND(SLIP_ESC_END); + break; + case SLIP_ESC: + SIO_SEND(SLIP_ESC); + SIO_SEND(SLIP_ESC_ESC); + break; + default: + SIO_SEND(c); + break; + } + } + SIO_SEND(SLIP_END); +} +/*-----------------------------------------------------------------------------------*/ +/* + * rs232dev_poll(): + * + * Read all avaliable bytes from the RS232 interface into the slip_buf + * buffer. If no more bytes are avaliable, it returns with 0 to + * indicate that no packet was immediately ready. When a full packet + * has been read into the buffer, the packet is copied into the + * uip_buf buffer and the length of the packet is returned. + * + */ +/*-----------------------------------------------------------------------------------*/ +u16_t +rs232dev_poll(void) +{ + u8_t c; + static u8_t lastc; + + while(SIO_POLL(c)) { + /* printf("c %x\n", c);*/ + switch(c) { + case SLIP_ESC: + lastc = c; + break; + + case SLIP_END: + lastc = c; + /* End marker found, we copy our input buffer to the uip_buf + buffer and return the size of the packet we copied. */ + memcpy(&uip_buf[UIP_LLH_LEN], slip_buf, len); + tmplen = len; + len = 0; + return tmplen; + + default: + if(lastc == SLIP_ESC) { + lastc = c; + /* Previous read byte was an escape byte, so this byte will be + interpreted differently from others. */ + switch(c) { + case SLIP_ESC_END: + c = SLIP_END; + break; + case SLIP_ESC_ESC: + c = SLIP_ESC; + break; + } + } else { + lastc = c; + } + + + slip_buf[len] = c; + ++len; + + if(len > MAX_SIZE) { + len = 0; + } + + break; + } + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +/* + * rs232dev_init(): + * + * Initializes the RS232 device and sets the parameters of the device. + * + */ +/*-----------------------------------------------------------------------------------*/ +void +rs232dev_init(void) +{ + char err; + + err = rs232_init(0); + rs232_err(err); + err = rs232_params(RS_BAUD_9600 | RS_BITS_8 | RS_STOP_1, RS_PAR_NONE); + rs232_err(err); + + len = 0; + + return; +} +/*-----------------------------------------------------------------------------------*/ + diff --git a/platform/c64/net/rs232silversurfer.h b/platform/c64/net/rs232silversurfer.h new file mode 100644 index 000000000..9e9a49ffe --- /dev/null +++ b/platform/c64/net/rs232silversurfer.h @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2003, Groepaz/Hitmen. + * 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. + * + * rs232silversurfer.h + * + * Groepaz/Hitmen, 16.12.2001 + * + * This defines for the SilverSurver (16c550 UART) what Ullrichs rs232 module + * defines for the Swithlink/Turbo232 + * + * this driver operates in polling mode only atm ! + * + */ + +#ifndef _RS232silversurfer_H +#define _RS232silversurfer_H + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + +/* Baudrate settings */ +#define RS_BAUD_50 0x00 +#define RS_BAUD_110 0x10 +#define RS_BAUD_134_5 0x20 +#define RS_BAUD_300 0x30 +#define RS_BAUD_600 0x40 +#define RS_BAUD_1200 0x50 +#define RS_BAUD_2400 0x60 +#define RS_BAUD_4800 0x70 +#define RS_BAUD_9600 0x80 +#define RS_BAUD_19200 0x90 +#define RS_BAUD_38400 0xa0 +#define RS_BAUD_57600 0xb0 +#define RS_BAUD_115200 0xc0 +#define RS_BAUD_230400 0xd0 + +/* Stop bit settings */ +#define RS_STOP_1 0x00 +#define RS_STOP_2 0x04 + +/* Data bit settings */ +#define RS_BITS_5 0x00 +#define RS_BITS_6 0x01 +#define RS_BITS_7 0x02 +#define RS_BITS_8 0x03 + +/* Parity settings */ +#define RS_PAR_NONE 0x00 +#define RS_PAR_ODD 0x28 +#define RS_PAR_EVEN 0x38 +#define RS_PAR_MARK 0x48 +#define RS_PAR_SPACE 0x48 + +/* Bit masks to mask out things from the status returned by rs232_status */ +#define RS_STATUS_IRQ 0x01 /* (iir) IRQ condition */ +#define RS_STATUS_OVERRUN 0x02 /* (lsr) Overrun error */ +#define RS_STATUS_PE 0x04 /* (lsr) Parity error */ +#define RS_STATUS_FE 0x08 /* (lsr) Framing error */ +#define RS_STATUS_DSR 0x10 /* (msr>>1) NOT data set ready */ +#define RS_STATUS_THRE 0x20 /* (lsr) Transmit holding reg. empty */ +#define RS_STATUS_DCD 0x40 /* (msr>>1) NOT data carrier detect */ +#define RS_STATUS_RDRF 0x80 /* Receiver data register full */ + +/* Error codes returned by all functions */ +#define RS_ERR_OK 0x00 /* Not an error - relax */ +#define RS_ERR_NOT_INITIALIZED 0x01 /* Module not initialized */ +#define RS_ERR_BAUD_TOO_FAST 0x02 /* Cannot handle baud rate */ +#define RS_ERR_BAUD_NOT_AVAIL 0x03 /* Baud rate not available */ +#define RS_ERR_NO_DATA 0x04 /* Nothing to read */ +#define RS_ERR_OVERFLOW 0x05 /* No room in send buffer */ + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + +unsigned char __fastcall__ rs232_init (char hacked); +/* Initialize the serial port, install the interrupt handler. The parameter + * has no effect for now and should be set to 0. + */ + +unsigned char __fastcall__ rs232_params (unsigned char params, unsigned char parity); +/* Set the port parameters. Use a combination of the #defined values above. */ + +unsigned char __fastcall__ rs232_done (void); +/* Close the port, deinstall the interrupt hander. You MUST call this function + * before terminating the program, otherwise the machine may crash later. If + * in doubt, install an exit handler using atexit(). The function will do + * nothing, if it was already called. + */ + +unsigned char __fastcall__ rs232_get (char* b); +/* Get a character from the serial port. If no characters are available, the + * function will return RS_ERR_NO_DATA, so this is not a fatal error. + */ + +unsigned char __fastcall__ rs232_put (char b); +/* Send a character via the serial port. There is a transmit buffer, but + * transmitting is not done via interrupt. The function returns + * RS_ERR_OVERFLOW if there is no space left in the transmit buffer. + */ + +unsigned char __fastcall__ rs232_pause (void); +/* Assert flow control and disable interrupts. */ + +unsigned char __fastcall__ rs232_unpause (void); +/* Re-enable interrupts and release flow control */ + +unsigned char __fastcall__ rs232_status (unsigned char* status, + unsigned char* errors); +/* Return the serial port status. */ + +/* End of rs232silversurfer.h */ +#endif + + + diff --git a/platform/c64/net/tfe-drv.c b/platform/c64/net/tfe-drv.c new file mode 100644 index 000000000..d393d42de --- /dev/null +++ b/platform/c64/net/tfe-drv.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: tfe-drv.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + * + */ + +#include "contiki-net.h" +#include "cs8900a.h" + +static u8_t output(void); + +static const struct uip_eth_addr addr = + {{0x00,0x00,0x00,0x64,0x64,0x64}}; + +SERVICE(tfe_drv_service, packet_service, { output };); + +PROCESS(tfe_drv_process, "TFE driver"); + +/*---------------------------------------------------------------------------*/ +static u8_t +output(void) +{ + uip_arp_out(); + cs8900a_send(); + + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = cs8900a_poll(); + if(uip_len > 0) { + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + cs8900a_send(); + } + } + } + +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(tfe_drv_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + + uip_setethaddr(addr); + + cs8900a_init(); + + SERVICE_REGISTER(tfe_drv_service); + + process_poll(&tfe_drv_process); + + while(1) { + PROCESS_YIELD(); + } + + PROCESS_END(); +} + + +/*---------------------------------------------------------------------------*/ diff --git a/platform/c64/net/tfe-dsc.c b/platform/c64/net/tfe-dsc.c new file mode 100644 index 000000000..189f84e8c --- /dev/null +++ b/platform/c64/net/tfe-dsc.c @@ -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: tfe-dsc.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + * + */ + +#include "sys/dsc.h" + +extern struct ctk_icon tfe_icon; +/*-----------------------------------------------------------------------------------*/ +DSC(tfe_dsc, + "The Final Ethernet driver", + "tfe.drv", + tfe_init, + &tfe_icon); +/*-----------------------------------------------------------------------------------*/ +#if CTK_CONF_ICON_BITMAPS +static unsigned char tfeicon_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 tfeicon_textmap[9] = { + 'T', 'C', 'P', + '/', 'I', 'P', + 'T', 'F', 'E' +}; +#endif /* CTK_CONF_ICON_TEXTMAPS */ + +#if CTK_CONF_ICONS +static struct ctk_icon tfe_icon = + {CTK_ICON("TFE driver", tfeicon_bitmap, tfeicon_textmap)}; +#endif /* CTK_CONF_ICONS */ +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/c64/net/tfe-dump-drv.c b/platform/c64/net/tfe-dump-drv.c new file mode 100644 index 000000000..5b6c7e1c8 --- /dev/null +++ b/platform/c64/net/tfe-dump-drv.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2001-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 uIP TCP/IP stack. + * + * $Id: tfe-dump-drv.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + * + */ + +#include "contiki-net.h" +#include "cs8900a.h" + +static void output(u8_t *hdr, u16_t hdrlen, u8_t *data, u16_t datalen); + +/* 00:0E:3A is the OUI of Cirrus Logic, 64:64:64 just means C64 */ +static const struct uip_eth_addr addr = + {{0x00,0x0e,0x3a,0x64,0x64,0x64}}; + +static const struct packet_service_state state = + { + PACKET_SERVICE_VERSION, + output + }; + +EK_EVENTHANDLER(eventhandler, ev, data); +EK_POLLHANDLER(pollhandler); +EK_PROCESS(proc, PACKET_SERVICE_NAME ": TFE", EK_PRIO_NORMAL, + eventhandler, pollhandler, (void *)&state); + +#include "tcpdump.h" +#include +#include "ctk/ctk.h" + +#define DUMP_WIDTH 38 +#define DUMP_HEIGHT 20 +static struct ctk_window window; +static char dump[DUMP_WIDTH * DUMP_HEIGHT]; +static struct ctk_label dumplabel = + {CTK_LABEL(0, 0, DUMP_WIDTH, DUMP_HEIGHT, dump)}; +static void +dump_packet(void) +{ + memcpy(dump, &dump[DUMP_WIDTH], DUMP_WIDTH * (DUMP_HEIGHT - 1)); + tcpdump_print(&dump[DUMP_WIDTH * (DUMP_HEIGHT - 1)], DUMP_WIDTH); + CTK_WIDGET_REDRAW(&dumplabel); +} +/*---------------------------------------------------------------------------*/ +LOADER_INIT_FUNC(tfe_dump_drv_init, arg) +{ + arg_free(arg); + ek_service_start(PACKET_SERVICE_NAME, &proc); +} +/*---------------------------------------------------------------------------*/ +static void +output(u8_t *hdr, u16_t hdrlen, u8_t *data, u16_t datalen) +{ + uip_arp_out(); + cs8900a_send(); + dump_packet(); +} +/*---------------------------------------------------------------------------*/ + +EK_EVENTHANDLER(eventhandler, ev, data) +{ + switch(ev) { + case EK_EVENT_INIT: + case EK_EVENT_REPLACE: + ctk_window_new(&window, DUMP_WIDTH, DUMP_HEIGHT, "TFE dump"); + CTK_WIDGET_ADD(&window, &dumplabel); + ctk_window_open(&window); + uip_setethaddr(addr); + cs8900a_init(); + break; + case EK_EVENT_REQUEST_REPLACE: + ctk_window_close(&window); + ek_replace((struct ek_proc *)data, NULL); + LOADER_UNLOAD(); + break; + case EK_EVENT_REQUEST_EXIT: + ctk_window_close(&window); + ek_exit(); + LOADER_UNLOAD(); + break; + default: + break; + } +} + +/*---------------------------------------------------------------------------*/ +EK_POLLHANDLER(pollhandler) +{ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = cs8900a_poll(); + if(uip_len > 0) { + dump_packet(); + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + if(BUF->type == HTONS(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + tcpip_input(); + } else if(BUF->type == HTONS(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + cs8900a_send(); + } + } + } + +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/esb/Makefile.esb b/platform/esb/Makefile.esb new file mode 100644 index 000000000..0ab4149e0 --- /dev/null +++ b/platform/esb/Makefile.esb @@ -0,0 +1,31 @@ +# $Id: Makefile.esb,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + +SENSORS = sensors.c irq.c button-sensor.c pir-sensor.c vib-sensor.c \ + sound-sensor.c radio-sensor.c ctsrts-sensor.c battery-sensor.c \ + temperature-sensor.c +ESB = ir.c beep.c ds1629.c tr1001-drv.c tr1001.c esb-sensors.c +CONTIKI_TARGET_DIRS = . dev apps net loader +CONTIKI_TARGET_MAIN = contiki-esb-main.c + +CONTIKI_TARGET_SOURCEFILES += $(SENSORS) $(ESB) \ + contiki-esb-default-init-lowlevel.c \ + contiki-esb-default-init-apps.c contiki-esb-default-init-net.c \ + rs232.c fader.c $(CONTIKI_TARGET_MAIN) + +PROJECT_OBJECTFILES += $(OBJECTDIR)/contiki-esb-main.o + +MCU=msp430x149 +include $(CONTIKI)/cpu/msp430/Makefile.msp430 + +contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/,node-id.o symbols.o} +# $(AR) rcf $@ $^ + +ifndef BASE_IP +BASE_IP := 172.16.1.1 +endif + +send: $(CONTIKI)/tools/codeprop.c + cc -Wall $^ -o send + +%.send: %.cm send + send $(BASE_IP) $< diff --git a/platform/esb/contiki-conf.h b/platform/esb/contiki-conf.h new file mode 100644 index 000000000..8eb6f3ac4 --- /dev/null +++ b/platform/esb/contiki-conf.h @@ -0,0 +1,104 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#define IRQ_PORT1 0x01 +#define IRQ_PORT2 0x02 +#define IRQ_ADC 0x03 + +#define EEPROMFS_ADDR_NODECONF 0x0000 +#define EEPROMFS_ADDR_CODERECV 0x0040 +#define EEPROMFS_ADDR_CODEPROP 0x0040 + +#define EEPROMFS_ADDR_TESTDATA 0x0042 +#define EEPROMFS_ADDR_NUMTESTDATA 0x0040 + +#define EEPROMFS_ADDR_SENSORLOG 0x0400 +#define EEPROMFS_SIZE_SENSORLOG 0x0200 + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 + +#define CC_CONF_INLINE inline + +#define CC_CONF_VA_ARGS 1 + + +typedef unsigned short clock_time_t; +#define CLOCK_CONF_SECOND 8 + +void clock_delay(unsigned int us2); + +void clock_wait(int ms10); + +void clock_set_seconds(unsigned long s); +unsigned long clock_seconds(void); + +#include "ctk/ctk-vncarch.h" + +#define LOG_CONF_ENABLED 0 + +/** + * The 8-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * char" works for most compilers. + */ +typedef unsigned char u8_t; + +/** + * The 16-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * short" works for most compilers. + */ +typedef unsigned short u16_t; + +/** + * The 32-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * long" works for most compilers. + */ +typedef unsigned long u32_t; + +/** + * The statistics data type. + * + * This datatype determines how high the statistics counters are able + * to count. + */ +typedef unsigned short uip_stats_t; + + +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 8 +#define UIP_CONF_BUFFER_SIZE 140 +#define UIP_CONF_RECEIVE_WINDOW 140 + +#define UIP_CONF_LLH_LEN 6 + +#define UIP_CONF_RESOLV_ENTRIES 1 + +#define UIP_CONF_PINGADDRCONF 1 + +#define UIP_CONF_LOGGING 0 + +#define UIP_CONF_UDP_CONNS 6 + +#define UIP_CONF_FWCACHE_SIZE 1 + +#define UIP_CONF_BROADCAST 1 + +#define LOADER_CONF_ARCH "loader/loader-arch.h" + +#define ELFLOADER_CONF_DATAMEMORY_SIZE 100 +#define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x1000 + +/* LEDs ports. */ +#define LEDS_PxDIR P2DIR +#define LEDS_PxOUT P2OUT +#define LEDS_CONF_RED 0x01 +#define LEDS_CONF_GREEN 0x02 +#define LEDS_CONF_YELLOW 0x04 + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/esb/contiki-esb-default-contiki-conf.h b/platform/esb/contiki-esb-default-contiki-conf.h new file mode 100644 index 000000000..626b7c082 --- /dev/null +++ b/platform/esb/contiki-esb-default-contiki-conf.h @@ -0,0 +1,88 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#define IRQ_PORT1 0x01 +#define IRQ_PORT2 0x02 +#define IRQ_ADC 0x03 + +#define EEPROMFS_ADDR_NODECONF 0x0000 +#define EEPROMFS_ADDR_CODERECV 0x0040 +#define EEPROMFS_ADDR_CODEPROP 0x0040 + +#define EEPROMFS_ADDR_TESTDATA 0x0042 +#define EEPROMFS_ADDR_NUMTESTDATA 0x0040 + +#define EEPROMFS_ADDR_SENSORLOG 0x0400 +#define EEPROMFS_SIZE_SENSORLOG 0x0200 + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 + +#define CC_CONF_INLINE inline + +#define CC_CONF_VA_ARGS 1 + + +typedef unsigned short clock_time_t; +#define CLOCK_CONF_SECOND 8 + +void clock_delay(unsigned int us2); + +void clock_wait(int ms10); + +void clock_set_seconds(unsigned long s); +unsigned long clock_seconds(void); + +#include "ctk/ctk-vncarch.h" + +#define LOG_CONF_ENABLED 0 + +/** + * The 8-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * char" works for most compilers. + */ +typedef unsigned char u8_t; + +/** + * The 16-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * short" works for most compilers. + */ +typedef unsigned short u16_t; + +/** + * The statistics data type. + * + * This datatype determines how high the statistics counters are able + * to count. + */ +typedef unsigned short uip_stats_t; + + +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 8 +#define UIP_CONF_BUFFER_SIZE 140 +#define UIP_CONF_RECEIVE_WINDOW 140 + +#define UIP_CONF_LLH_LEN 6 + +#define UIP_CONF_RESOLV_ENTRIES 1 + +#define UIP_CONF_PINGADDRCONF 1 + +#define UIP_CONF_LOGGING 0 + +#define UIP_CONF_UDP_CONNS 6 + +#define UIP_CONF_FWCACHE_SIZE 1 + +#define UIP_CONF_BROADCAST 1 + + +#define ELFLOADER_CONF_DATAMEMORY_SIZE 100 +#define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x1000 + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/esb/contiki-esb-default-init-apps.c b/platform/esb/contiki-esb-default-init-apps.c new file mode 100644 index 000000000..0489d011c --- /dev/null +++ b/platform/esb/contiki-esb-default-init-apps.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-esb-default-init-apps.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + */ +void +init_apps(void) +{ +} diff --git a/platform/esb/contiki-esb-default-init-lowlevel.c b/platform/esb/contiki-esb-default-init-lowlevel.c new file mode 100644 index 000000000..fb87eec26 --- /dev/null +++ b/platform/esb/contiki-esb-default-init-lowlevel.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-esb-default-init-lowlevel.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + */ +#include "contiki-esb.h" +#include "dev/esb-sensors.h" + +static void init_ports_toberemoved() { + ////////// Port 1 //// + P1SEL = 0x00; + P1DIR = 0x81; // Outputs: P10=IRSend, P17=RS232RTS + // Inputs: P11=Light, P12=IRRec, P13=PIR, P14=Vibration, + // P15=Clockalarm, P16=RS232CTS + P1OUT = 0x00; + + ////////// Port 2 //// + P2SEL = 0x00; // No Sels + P2DIR = 0x7F; // Outpus: P20..P23=Leds+Beeper, P24..P26=Poti + // Inputs: P27=Taster + P2OUT = 0x77; + + ////////// Port 3 //// + P3SEL = 0xE0; // Sels for P34..P37 to activate UART, + P3DIR = 0x5F; // Inputs: P30..P33=CON4, P35/P37=RXD Transceiver/RS232 + // OutPuts: P36/P38=TXD Transceiver/RS232 + P3OUT = 0xE0; // Output a Zero on P34(TXD Transceiver) and turn SELECT off when receiving!!! + + ////////// Port 4 //// + P4SEL = 0x00; // CON5 Stecker + P4DIR = 0xFF; + P4OUT = 0x00; + + ////////// Port 5 //// + P5SEL = 0x00; // P50/P51= Clock SDA/SCL, P52/P53/P54=EEPROM SDA/SCL/WP + P5DIR = 0xDA; // P56/P57=Transceiver CNTRL0/1 + P5OUT = 0x0F; + + ////////// Port 6 //// + P6SEL = 0x00; // P60=Microphone, P61=PIR digital (same as P13), P62=PIR analog + P6DIR = 0x00; // P63=extern voltage, P64=battery voltage, P65=Receive power + P6OUT = 0x00; +} + +void +init_lowlevel(void) +{ + init_ports_toberemoved(); + esb_sensors_init(); + esb_sensors_on(); + leds_init(); + rs232_init(); + tr1001_init(); +} diff --git a/platform/esb/contiki-esb-default-init-net.c b/platform/esb/contiki-esb-default-init-net.c new file mode 100644 index 000000000..1eb8997ef --- /dev/null +++ b/platform/esb/contiki-esb-default-init-net.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-esb-default-init-net.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + */ + +#include "contiki-esb.h" + +static struct uip_fw_netif tr1001if = + {UIP_FW_NETIF(0,0,0,0, 0,0,0,0, tr1001_drv_send)}; + +static struct uip_fw_netif slipif = + {UIP_FW_NETIF(172,16,0,0, 255,255,255,0, slip_send)}; + +#define NODE_ID (node_id & 0xFF) + +void +init_net(void) +{ + u16_t hostaddr[2]; + + rs232_set_input(slip_input_byte); + + process_start(&tr1001_drv_process, NULL); + process_start(&slip_process, NULL); + + if (NODE_ID > 0) { + /* node id is set, construct an ip address based on the node id */ + uip_ipaddr(hostaddr, 172, 16, 1, NODE_ID); + uip_sethostaddr(hostaddr); + } + uip_fw_register(&slipif); + uip_fw_default(&tr1001if); +} diff --git a/platform/esb/contiki-esb-main.c b/platform/esb/contiki-esb-main.c new file mode 100644 index 000000000..71ae20cee --- /dev/null +++ b/platform/esb/contiki-esb-main.c @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-esb-main.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + */ + +#include +#include +#include +#include + +#include "sys/procinit.h" +#include "sys/autostart.h" +#include "contiki-esb.h" + +#include "cfs/cfs-eeprom.h" + +SENSORS(&button_sensor, &sound_sensor, &vib_sensor, + &pir_sensor, &radio_sensor, &battery_sensor, &ctsrts_sensor, + &temperature_sensor); + +PROCINIT(&sensors_process, &ir_process, &etimer_process, + &tcpip_process, &uip_fw_process, &cfs_eeprom_process); + +#define ENABLE_AUTOSTART 0 + +PROCESS(contiki_esb_main_init_process, "Contiki ESB init process"); + +PROCESS_THREAD(contiki_esb_main_init_process, ev, data) +{ + PROCESS_BEGIN(); + + procinit_init(); + + PROCESS_PAUSE(); + + init_net(); + + PROCESS_PAUSE(); + + init_apps(); + + PROCESS_PAUSE(); + + autostart_start((struct process **) autostart_processes); + + beep_spinup(); + leds_on(LEDS_ALL); + clock_delay(100); + leds_off(LEDS_ALL); + + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + msp430_cpu_init(); + + init_lowlevel(); + + clock_init(); + + process_init(); + + random_init(0); + + uip_init(); + uip_fw_init(); + + process_start(&contiki_esb_main_init_process, NULL); + + /* watchdog_init();*/ + + /* beep();*/ + + while(1) { + /* watchdog_restart();*/ + while(process_run() > 0); + LPM_SLEEP(); + } + + + return 0; +} +/*---------------------------------------------------------------------------*/ +char *arg_alloc(char size) {return NULL;} +void arg_init(void) {} +void arg_free(char *arg) {} +/*---------------------------------------------------------------------------*/ + +int +putchar(int c) +{ + rs232_send(c); + return c; +} + +void +uip_log(char *m) +{ + printf("uIP log: '%s'\n", m); +} diff --git a/platform/esb/contiki-esb.h b/platform/esb/contiki-esb.h new file mode 100644 index 000000000..8b9013c1a --- /dev/null +++ b/platform/esb/contiki-esb.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-esb.h,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + */ +#ifndef __CONTIKI_ESB_H__ +#define __CONTIKI_ESB_H__ + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" + +#include "lib/sensors.h" +#include "dev/hwconf.h" + +#include "dev/lpm.h" + +#include "codeprop.h" + +#include "dev/rs232.h" + +#include "dev/serial.h" +#include "dev/slip.h" +#include "dev/tr1001.h" +#include "net/tr1001-drv.h" + +#include "node-id.h" + +#include "dev/vib-sensor.h" +#include "dev/pir-sensor.h" +#include "dev/button-sensor.h" +#include "dev/radio-sensor.h" +#include "dev/sound-sensor.h" +#include "dev/battery-sensor.h" +#include "dev/temperature-sensor.h" +#include "dev/ctsrts-sensor.h" + +#include "dev/beep.h" + +#include "dev/ir.h" + +#include "dev/leds.h" + +void msp430_cpu_init(void); +void init_lowlevel(void); +void init_apps(void); +void init_net(void); + + +#endif /* __CONTIKI_ESB_H__ */ diff --git a/platform/esb/core.c b/platform/esb/core.c new file mode 100644 index 000000000..abc55fcc2 --- /dev/null +++ b/platform/esb/core.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: core.c,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + */ +#include "contiki-esb.h" +#include "codeprop-tmp.h" +#include +#include + +AUTOSTART_PROCESSES(&codeprop_process); + +int core_dummy_4711(int len) { + char t[1]; + int l = snprintf(t, sizeof(t), "%d", len % 9); + printf("%d\n", l / 2); + return len / 4; +} diff --git a/platform/esb/doc/contiki-esb.txt b/platform/esb/doc/contiki-esb.txt new file mode 100644 index 000000000..4361ce880 --- /dev/null +++ b/platform/esb/doc/contiki-esb.txt @@ -0,0 +1,72 @@ +/** + +\mainpage The Contiki Operating System + +\author Adam Dunkels + +The Contiki operating system is a highly portable, minimalistic +operating system for a variety of resource constrained systems with +memory size on the order of a few kilobytes. Contiki provides a simple +event-driven kernel with optional preemptive multithreading, +interprocess communication using message passing signals, a dynamic +process structure and support for loading and unloading programs, +native TCP/IP support using the uIP TCP/IP stack, and a graphical +subsystem with either direct graphic support for directly connected +terminals or networked virtual display with VNC or Telnet. + +Contiki is written in the C programming language and is freely +available as open source under a BSD-style license. More information +about Contiki can be found at the Contiki home page: +http://www.sics.se/~adam/contiki/ + +The ESB (Embedded Sensor Board) is a prototype wireless sensor network +device developed at Freie Universität Berlin. The ESB consists of a +Texas Instruments MSP430 low-power microcontroller with 2k RAM and 60k +flash ROM, a TR1001 radio transceiver, a 32k serial EEPROM, an RS232 port, a +JTAG port, a beeper, and a number of sensors (passive IR, active IR +sender/receiver, vibration/tilt, microphone, temperature). + +The Contiki/ESB port brings support for TCP/IP, loadable programs +(over-the-air programming), event-based multitasking, and cooperative +multi-threading (preemptive threading is implemented but not yet fully +tested) to the ESB. The Contiki/ESB port contains drivers for most of +the sensors. The drivers were mostly adapted from sources written by +FU Berlin. + +\sa \ref esb "The Scatterweb/ESB board" + +\section contiki-esb-threads Processes, multi-threading and protothreads + +Contiki is based on an event-driven kernel but provides support for +both multi-threading and a lightweight stackless thread-like construct +called protothreads. + +\sa \ref process "Contiki processes" +\sa \ref mt "Contiki multi-threading" +\sa \ref pt "Protothreads" + +\section contiki-sensors Sensor interfaces + +\section contiki-esb-communication Communication + +Contiki includes the uIP TCP/IP stack (http://www.sics.se/~adam/uip/) +that provides Contiki with TCP/IP networking support. uIP provides the +protocols TCP, UDP, IP, and ARP. + +In Contiki, the TCP/IP stack typically is used for all communication. + +\sa \ref uip "The uIP TCP/IP stack documentation" +\sa \ref tcpip "The Contiki/uIP interface" +\sa \ref psock "Protosockets library" + +\section contiki-esb-lib Libraries + +Contiki provides a set of convenience libraries for memory management +and linked list operations. + +\sa \ref etimer "Event timer library" +\sa \ref timer "Simple timer library" +\sa \ref memb "Memory block management" +\sa \ref list "Linked list library" + +*/ \ No newline at end of file diff --git a/platform/esb/doc/doc.txt b/platform/esb/doc/doc.txt new file mode 100644 index 000000000..9c6e3365c --- /dev/null +++ b/platform/esb/doc/doc.txt @@ -0,0 +1,7 @@ +/** + +\defgroup doc Documentation +@{ +*/ + +/** @} */ diff --git a/platform/esb/doc/esb.txt b/platform/esb/doc/esb.txt new file mode 100644 index 000000000..4614dab58 --- /dev/null +++ b/platform/esb/doc/esb.txt @@ -0,0 +1,28 @@ +/** \addtogroup platform + * @{ **/ + +/** +\defgroup esb The ESB Embedded Sensor Board + +The ESB (Embedded Sensor Board) is a prototype wireless sensor network +device developed at Freie Universität Berlin. + + + +The ESB consists of a Texas Instruments MSP430 low-power +microcontroller with 2k RAM and 60k flash ROM, a TR1001 radio +transceiver, a 32k serial EEPROM, an RS232 port, a JTAG port, a +beeper, and a number of sensors (passive IR, active IR +sender/receiver, vibration/tilt, microphone, temperature). + + +The Contiki/ESB port contains drivers for most of the sensors. The +drivers were mostly adapted from sources from FU Berlin. + +@{ + +*/ + + +/** @} */ +/** @} */ diff --git a/platform/esb/doc/getting-started.txt b/platform/esb/doc/getting-started.txt new file mode 100644 index 000000000..83eaa2f2a --- /dev/null +++ b/platform/esb/doc/getting-started.txt @@ -0,0 +1,28 @@ +/** +\addtogroup doc +@{ +*/ + +/** + +\defgroup getting-started Getting started with Contiki +@{ + +\section getting-started-intro Introduction + +What is Contiki? + +What is its relation to the ESB? + +How are programs written for it? + +\section getting-started-example An example program - blinker + +\subsection getting-started-compiling Compiling blinker + +\subsection getting-started-running Running blinker + +\subsection getting-started-simulation Running blinker in the simulator + + +*/ \ No newline at end of file diff --git a/platform/esb/doc/quickref.txt b/platform/esb/doc/quickref.txt new file mode 100644 index 000000000..dbcadbb98 --- /dev/null +++ b/platform/esb/doc/quickref.txt @@ -0,0 +1,68 @@ +/** +\defgroup quickref Function quick reference +@{ + +\section sensors Sensor functions + +Some sensors generate events when the sensors change. It is always +possible to query the state of a sensor through a set of query functions. + +\subsection quickref-sensors-events Sensor events + +- \ref sensors_event_button_down - the button has been pressed +- \ref sensors_event_button_up - the button has been depressed +- \ref sensors_event_humidity - a change in humidity has been detected +- \ref sensors_event_light - a change in light has been detected +- \ref sensors_event_motion - motion has been detected +- \ref sensors_event_sound - sound has been detected +- \ref sensors_event_temperature - temperature has changed +- \ref sensors_event_vibration - vibration has been detected + +\subsection quickref-sensors-query Sensor query functions + +- sensors_battery() - query the battery voltage level +- sensors_button() - query the on-board button +- sensors_mic() - query the microphone +- sensors_pir() - query the passive IR sensor (motion detector) +- sensors_radiosignal() - query the radio signal strength +- sensors_temp() - query the temperature sensor +- sensors_vib() - query the vibration sensor + +\section quickref-leds LED functions + +- leds_on() - turn LEDs on +- leds_off() - turn LEDs off +- leds_invert() - invert LEDs +- leds_blink() - blink all LEDs + +\section quickref-beeper Beeper functions + +- beep() - click the beeper +- beep_beep() - beep +- beep_down() - pitchbend down beep +- beep_quick() - a number of quick beeps +- beep_spinup() - pitchbend up beep + +\section quickref-timers Timer functions + +Contiki supports two types of timers: event timers and simple +timers. Event timers generates an event when the timer expires, +whereas the simple timer has to be actively queried to check when it +has expired. + +\subsection quickref-etimer Event timers + +- etimer_expired() - check if an event timer has expired +- etimer_set() - set an event timer +- etimer_reset() - set an expired event timer to the next interval +- etimer_restart() - restart an event timer from the current point in time + +\subsection quickref-timer Simple timers + +- timer_expired() - check if a simple timer has expired +- timer_set() - set a simple timer +- timer_reset() - set a simple event timer to the next interval +- timer_restart() - restart a simple timer from the current point in time + + +*//** @{ */ \ No newline at end of file diff --git a/platform/esb/doc/slipintro.txt b/platform/esb/doc/slipintro.txt new file mode 100644 index 000000000..9211d1a28 --- /dev/null +++ b/platform/esb/doc/slipintro.txt @@ -0,0 +1,126 @@ +/** \addtogroup esb +@{ */ +/** +\defgroup slipintro Introduction to Over The Air Reprogramming under Windows +\author Joakim Eriksson, Niclas Finne +@{ + +\section slipintro-intro Introduction + +This is a brief introduction how to program ESB sensor nodes over +radio under Windows. It is assumed that you already have the +environment setup for programming ESB sensor nodes using JTAG cable. + +\section slipintro-configuring Configuring SLIP under Windows XP + +This section describes how to setup a SLIP connection under Windows. A +SLIP connection forwards TCP/IP traffic to/from the sensor nodes and +lets you communicate with them using standard network tools such as +\c ping. + + +-# Click start button and choose 'My Computer'. Right-click 'My +Network Places' and choose 'Properties'. +-# Click 'Create a new connection'. +-# Select 'Set up an advanced connection'. +-# Select 'Connect directly to another computer'. +-# Select 'Guest'. +-# Select a name for the slip connection (for example 'ESB'). +-# Select the serial port to use when communicating with the sensor +node. +-# Add the connection by clicking 'Finish'. +-# A connection window will open. Choose 'Properties'. +-# Click on 'Configure...' and deselect all selected +buttons. Choose the speed 57600 bps. +-# Close the modem configuration window, and go to the 'Options' +tab in the ESB properties. Deselect all except 'Display +progress...'. +-# Go to the 'Networking' tab. Change to 'SLIP: Unix Connection' +and deselect all except the first two items in the connection item +list. +-# Select 'Internet Protocol (TCP/IP)' and click +'Properties'. Enter the IP address '172.16.0.1'. +-# Click 'Advanced' and deselect all checkboxes in the 'Advanced +TCP/IP Settings'. Go to the 'WINS' tab and deselect 'Enable LMHOSTS +lookup' if it is selected. Also select 'Disable NetBIOS over +TCP/IP'. + + + + +\section slipintro-setup Setup ESB for over the air programming + +-# Make sure you have the latest contiki, contiki-msp430, and +contiki-esb (older versions of contiki might not work with SLIP under +Windows) +-# Install the contiki kernel by running +\code +make core.u +\endcode +-# Attach the ESB node to the serial port and make sure it is +turned on. Select your ESB SLIP connection in your 'Network +Connections' and choose 'Connect' (or double click on it). If +everything works Windows should say that you have a new connection. +-# Set the IP address for the node by pinging it (it will claim the +IP address of the first ping it hears). Note that the slip interface +has IP address 172.16.0.1 but the node will have the IP address +172.16.1.1. +\code +ping 172.16.1.1 +\endcode + +If everything works the node should click and reply to the pings. + +\section slipintro-send Send programs over the air + +Contiki applications to be installed via radio are compiled somewhat +different compared to normal applications. + +Each node needs an IP address for OTA to work. A node id can be +specified when you upload the contiki kernel to a node and this is +used to construct an IP address for the node. If you specify 2 as +node id, the node will have the IP address 172.16.1.2. Each node +should have its own unique node id. + +You need to compile a core and upload it onto the nodes. All nodes +must run the same core. Move to the directory '\c contiki-esb' and +run + +\code +make +make core.u nodeid=X +\endcode + +to upload the core to your nodes. Use the number 1, 2, 3, etc, +as the node id (\c X) for the nodes. This will give the nodes the IP +addresses 172.16.1.1, 172.16.1.2, etc. + +Then you need a program to send the application to connected +nodes. Compile it by running + +\code +make send +\endcode + +Make sure you have a node with IP address 172.16.1.1 connected to your +serial port and have SLIP activated. Then compile and send a +testprogram by running + +\code +make beeper.ce +./send 172.16.1.1 beeper.ce +\endcode + +*/ +/** @} */ +/** @} */ diff --git a/platform/esb/doc/winintro.txt b/platform/esb/doc/winintro.txt new file mode 100644 index 000000000..de30a57e1 --- /dev/null +++ b/platform/esb/doc/winintro.txt @@ -0,0 +1,164 @@ +/** +\addtogroup esb +@{ +*/ + +/** + +\defgroup winintro Introduction to Contiki development under Microsoft Windows +\author Joakim Eriksson, Niclas Finne +@{ + +\section winintro-intro Introduction + +This is a brief introduction to Contik/ESB programming under Windows +using cygwin and some other free software tools. + +\section winintro-installing Installing the development environment + +This sections describes how to install all the necessary software +to get started with ESB programming. + +\subsection winintro-installing-cygwin Cygwin - a Linux-like environment for Windows + +The first "need to have" software is the cygwin environment that can +be found at http://www.cygwin.com. Click on the icon "Install +Cygwin Now" to the right to get the installation started. + +Choose "Install from Internet" and then specify where you want to +install cygwin (recommended installation path: \c +C:$\backslash$cygwin). Continue with the installation until you are +asked to select packages. Most packages can be left as "Default" but +there is one package that are not installed by default. Install the +following package by clicking at "Default" until it changes to +"Install": + +- Devel - contains things for developers (make, etc). + + + +When cygwin is installed there should be a cygwin icon that starts +up a cygwin bash when clicked on. Whenever it is time to compile and +send programs to the ESB nodes it will be done from a cygwin shell. + +\subsection winintro-installing-editor C programming editor + +If you do not already have a nice programming editor it is a good +idea to download and install one. The Crimson editor is a nice +windows based editor that is both easy to get started with and +fairly powerful. + +Crimson Editor can be found at: +http://www.crimsoneditor.com/ + +The editor is useful both when editing C programs and when +modifying scripts and configuration files. + +\subsection winintro-installing-compiler MSP430 Compiler and tools} + +The MSP430 compiler (a version of gcc) is needed to compile the +programs to the MSP430 microprocessor that is used on the ESB +sensor nodes. We have made a webpage which describe how to get the compilers +and other tools for programming the ESB nodes, see: +http://www.sics.se/sensornets/esblab/ + +Download and install the GCC toolchain for MSP430 +(recommended installation path: C:$\backslash$MSP430$\backslash$): +\c mspgcc-20041112.exe. + +You will also need some tools for sending the compiled programs +over to the ESB nodes. Install the +IAR Embedded Workbench (Kickstart Version) package +(recommended installation path: C:$\backslash$MSP430$\backslash$IARSystems): +\c fet_r304.exe. + +When the above software is installed you also need to set-up the +PATH so that all of the necessary tools can be reached. In cygwin +this is done by the following line (given that you have installed +at recommended locations): + + +export PATH=\$PATH:/cygdrive/c/MSP430/IARSystems/ew23:\newline +/cygdrive/c/MSP430/IARSystems/ew23/430/bin:/cygdrive/c/MSP430/mspgcc/bin + + +This line can also be added to the .profile startup file in your cygwin +home directory \newline +(C:$\backslash$cygwin$\backslash$home$\backslash$$\backslash$.profile\end). + +If your home directory is located elsewhere you can find it by +starting cygwin and running \c cd followed by \c pwd. + +\subsection winintro-installing-contiki The Contiki operating system, including examples and labs + +When programming the ESB sensor nodes it is very useful to have an +operating system that takes care of some of the low-level tasks and +also gives you as a programmer APIs for things like events, hardware +and networking. We will use the Contiki operating system developed by +Adam Dunkels, SICS, which is very well suited when programming small +embedded systems. + +Download Contiki for ESB nodes from the same page as before (Contiki +ESB). + +Unzip the Contiki OS at (for example) C:$\backslash$ +and you will get the following directories: + +- esblab/contiki - the contiki operating system +- esblab/contiki-esb - the contiki operating system drivers, etc for the ESB +- esblab/contiki-esb/labs - the example and lab files + +\section winintro-testing Testing the tools + +Now everything necessary to start developing Contiki-based sensor net +applications should be installed. Start cygwin and change to the +directory \c labs/intro. Then call make esbintro. + +If you get an error about multiple cygwin dlls when compiling, you +need to delete \c cygwin1.dll from the MSP430 GCC toolchain (\c +C:$\backslash$MSP430$\backslash$bin$\backslash$cygwin1.dll). + +Connect a node and turn it on. Upload the test application by calling +\c make esbintro.u. + +\subsection winintro-testing-development Development tools + +- make will compile and make a executable file ready for +sending to the ESB nodes. Depending on the SPEC it might even startup +the application that sends the executable to the node. During this +course you would typically write things like "make + esbintro.u" to get the file esbintro.c compiled, linked and +sent out to the ESB node + +- cw23 starts up the CSPY program that sends programs to the +ESB nodes and allow debugging (usually started by the \c make + + +\subsection winintro-testing-shell Some basic shell commands + +- cd change to a specified directory (same as in DOS) +- pwd shows your current directory +- ls list the directory +- mkdir creates a new directory +- cp copies a file + +\subsection winintro-testing-excercises + + * compile and start the \c esbintro application (remember to change + directory to contiki-esb before you run \c make) + * modify the C code and make the yellow led be on when the red is + off (and vice versa). The code is in the \c contiki-esb/labs/intro +folder. Hint: Add another line controlling the yellow led in the section: +\code + if (timer_expired(&timer)) { + timer_reset(&timer); + leds_red(on ? LEDS_ON : LEDS_OFF); + on = !on; + } +\endcode + +*/ +/** @} */ +/** @} */ + diff --git a/platform/esb/node-id.h b/platform/esb/node-id.h new file mode 100644 index 000000000..a90b24cec --- /dev/null +++ b/platform/esb/node-id.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: node-id.h,v 1.1 2006/06/17 22:41:27 adamdunkels Exp $ + */ + +#ifndef __NODE_ID_H__ +#define __NODE_ID_H__ + +extern const unsigned short node_id; + +#endif /* __NODE_ID_H__ */ diff --git a/platform/esb/symbols.c b/platform/esb/symbols.c new file mode 100644 index 000000000..6a8851c6c --- /dev/null +++ b/platform/esb/symbols.c @@ -0,0 +1,289 @@ +#include "loader/symbols.h" +const struct symbols symbols[] = { +{"InterruptVectors", (char *)0x0000ffe0}, +{"Timer_B1", (char *)0x000042ec}, +{"__bss_end", (char *)0x00000808}, +{"__bss_start", (char *)0x000002fa}, +{"__ctors_end", (char *)0x0000113a}, +{"__ctors_start", (char *)0x0000113a}, +{"__data_start", (char *)0x00000200}, +{"__divmodhi4", (char *)0x0000977e}, +{"__dtors_end", (char *)0x0000113a}, +{"__dtors_start", (char *)0x0000113a}, +{"__stack", (char *)0x00000a00}, +{"__udivmodhi4", (char *)0x00009762}, +{"__udivmodsi4", (char *)0x000097b4}, +{"__umulsi3hw", (char *)0x0000973a}, +{"_edata", (char *)0x000002fa}, +{"_etext", (char *)0x000097de}, +{"_unexpected_1_", (char *)0x0000113a}, +{"_vectors_end", (char *)0x00010000}, +{"arg_alloc", (char *)0x00001254}, +{"arg_free", (char *)0x0000125a}, +{"arg_init", (char *)0x00001258}, +{"autostart_exit", (char *)0x00001e32}, +{"autostart_processes", (char *)0x00000200}, +{"autostart_start", (char *)0x00001e02}, +{"battery_sensor", (char *)0x000040d4}, +{"beep", (char *)0x000044f2}, +{"beep_alarm", (char *)0x00004474}, +{"beep_beep", (char *)0x000044d8}, +{"beep_down", (char *)0x000044fc}, +{"beep_long", (char *)0x000045c6}, +{"beep_off", (char *)0x00004538}, +{"beep_on", (char *)0x00004532}, +{"beep_quick", (char *)0x0000459e}, +{"beep_spinup", (char *)0x0000453e}, +{"button_sensor", (char *)0x00003d7c}, +{"cfs_eeprom_process", (char *)0x000002d4}, +{"cfs_eeprom_service", (char *)0x000002cc}, +{"cfs_find_service", (char *)0x00001e8a}, +{"cfs_nullservice", (char *)0x0000024c}, +{"clock_delay", (char *)0x00004aba}, +{"clock_init", (char *)0x00004a92}, +{"clock_seconds", (char *)0x00004ade}, +{"clock_set", (char *)0x00004a7c}, +{"clock_set_seconds", (char *)0x00004adc}, +{"clock_time", (char *)0x00004a76}, +{"clock_wait", (char *)0x00004ac0}, +{"codeprop_process", (char *)0x0000022e}, +{"codeprop_set_rate", (char *)0x00001298}, +{"codeprop_start_broadcast", (char *)0x000019bc}, +{"codeprop_start_program", (char *)0x000019d8}, +{"contiki_esb_main_init_process", (char *)0x00000224}, +{"crc16_add", (char *)0x00008cee}, +{"ctsrts_rts_clear", (char *)0x00003fb4}, +{"ctsrts_rts_set", (char *)0x00003fbc}, +{"ctsrts_sensor", (char *)0x00004070}, +{"ds1629_init", (char *)0x000047bc}, +{"ds1629_start", (char *)0x000047c2}, +{"ds1629_temperature", (char *)0x000047c8}, +{"eeprom_read", (char *)0x00008702}, +{"eeprom_write", (char *)0x0000877e}, +{"elfloader_arch_allocate_ram", (char *)0x00006612}, +{"elfloader_arch_allocate_rom", (char *)0x00006618}, +{"elfloader_arch_relocate", (char *)0x000066a0}, +{"elfloader_arch_write_text", (char *)0x00006630}, +{"elfloader_autostart_processes", (char *)0x0000077a}, +{"elfloader_init", (char *)0x0000529c}, +{"elfloader_load", (char *)0x000052da}, +{"elfloader_unknown", (char *)0x0000075c}, +{"esb_sensors_init", (char *)0x000085d4}, +{"esb_sensors_off", (char *)0x000085ea}, +{"esb_sensors_on", (char *)0x000085e2}, +{"etimer_adjust", (char *)0x000020a0}, +{"etimer_expiration_time", (char *)0x000020ba}, +{"etimer_expired", (char *)0x000020ac}, +{"etimer_next_expiration_time", (char *)0x000020d4}, +{"etimer_pending", (char *)0x000020c8}, +{"etimer_process", (char *)0x00000254}, +{"etimer_request_poll", (char *)0x00002030}, +{"etimer_reset", (char *)0x0000207c}, +{"etimer_restart", (char *)0x0000208e}, +{"etimer_set", (char *)0x0000206a}, +{"etimer_start_time", (char *)0x000020c4}, +{"etimer_stop", (char *)0x000020e6}, +{"flash_clear", (char *)0x00008852}, +{"flash_done", (char *)0x00008842}, +{"flash_setup", (char *)0x0000880e}, +{"flash_write", (char *)0x00008884}, +{"hc_compress", (char *)0x00008d30}, +{"hc_inflate", (char *)0x00008db8}, +{"hc_init", (char *)0x00008d2e}, +{"htons", (char *)0x0000318c}, +{"init_apps", (char *)0x00004848}, +{"init_lowlevel", (char *)0x00004832}, +{"init_net", (char *)0x0000484a}, +{"ir_data", (char *)0x000042b0}, +{"ir_event_received", (char *)0x0000075a}, +{"ir_irq", (char *)0x000043cc}, +{"ir_poll", (char *)0x000042b6}, +{"ir_process", (char *)0x00000292}, +{"ir_send", (char *)0x00004216}, +{"irq_adc", (char *)0x00003b34}, +{"irq_adc12_activate", (char *)0x00003bfc}, +{"irq_adc12_active", (char *)0x00003ca8}, +{"irq_adc12_deactivate", (char *)0x00003c52}, +{"irq_init", (char *)0x00003b5e}, +{"irq_p1", (char *)0x00003adc}, +{"irq_p2", (char *)0x00003b08}, +{"leds_arch_get", (char *)0x00004f1a}, +{"leds_arch_init", (char *)0x00004f0c}, +{"leds_arch_set", (char *)0x00004f48}, +{"leds_blink", (char *)0x00004ce2}, +{"leds_get", (char *)0x00004cf8}, +{"leds_green", (char *)0x00004ed0}, +{"leds_init", (char *)0x00004cb4}, +{"leds_invert", (char *)0x00004e28}, +{"leds_off", (char *)0x00004d94}, +{"leds_on", (char *)0x00004d00}, +{"leds_red", (char *)0x00004ef8}, +{"leds_toggle", (char *)0x00004e22}, +{"leds_yellow", (char *)0x00004ee4}, +{"lpm_off", (char *)0x00004afc}, +{"lpm_on", (char *)0x00004af6}, +{"lpm_status", (char *)0x000002ba}, +{"main", (char *)0x00001210}, +{"me_decode16", (char *)0x000088c0}, +{"me_decode8", (char *)0x000088de}, +{"me_decode_tab", (char *)0x00008aee}, +{"me_encode", (char *)0x000088b6}, +{"me_encode_tab", (char *)0x000088ee}, +{"me_valid", (char *)0x000088e6}, +{"me_valid_tab", (char *)0x00008bee}, +{"memchr", (char *)0x00009462}, +{"memcmp", (char *)0x000094d4}, +{"memcpy", (char *)0x00009508}, +{"memmove", (char *)0x000095e4}, +{"memset", (char *)0x000096c0}, +{"msp430_cpu_init", (char *)0x00004a18}, +{"msp430_init_dco", (char *)0x00004996}, +{"node_id", (char *)0x00006a46}, +{"pir_sensor", (char *)0x00003df8}, +{"printf", (char *)0x00008e52}, +{"process_alloc_event", (char *)0x00001ac4}, +{"process_current", (char *)0x0000023a}, +{"process_exit", (char *)0x00001c12}, +{"process_init", (char *)0x00001c1c}, +{"process_list", (char *)0x00000238}, +{"process_poll", (char *)0x00001dba}, +{"process_post", (char *)0x00001d48}, +{"process_post_synch", (char *)0x00001da8}, +{"process_run", (char *)0x00001d0c}, +{"process_start", (char *)0x00001ace}, +{"procinit", (char *)0x00000216}, +{"procinit_init", (char *)0x00001dd0}, +{"putchar", (char *)0x0000125c}, +{"puts", (char *)0x00009434}, +{"radio_off", (char *)0x00007f22}, +{"radio_on", (char *)0x00007f30}, +{"radio_sensor", (char *)0x00003f82}, +{"radio_sensor_signal", (char *)0x00000758}, +{"random_init", (char *)0x00006716}, +{"random_rand", (char *)0x0000671c}, +{"recir_getAddress", (char *)0x00004262}, +{"recir_getCode", (char *)0x00004258}, +{"recir_getError", (char *)0x00004294}, +{"recir_getToggle", (char *)0x0000427c}, +{"rs232_init", (char *)0x000048de}, +{"rs232_print", (char *)0x0000496e}, +{"rs232_rx_usart1", (char *)0x000048a0}, +{"rs232_send", (char *)0x00004904}, +{"rs232_set_input", (char *)0x0000498a}, +{"rs232_set_speed", (char *)0x00004916}, +{"sensors", (char *)0x00000204}, +{"sensors_add_irq", (char *)0x000038fa}, +{"sensors_changed", (char *)0x0000396a}, +{"sensors_event", (char *)0x00000755}, +{"sensors_find", (char *)0x0000397e}, +{"sensors_first", (char *)0x00003958}, +{"sensors_flags", (char *)0x000005ba}, +{"sensors_handle_irq", (char *)0x0000391a}, +{"sensors_next", (char *)0x0000395e}, +{"sensors_process", (char *)0x00000288}, +{"sensors_remove_irq", (char *)0x0000390a}, +{"sensors_select", (char *)0x000039d4}, +{"sensors_selecting_proc", (char *)0x000005a8}, +{"sensors_unselect", (char *)0x00003a04}, +{"service_find", (char *)0x00007e22}, +{"service_register", (char *)0x00007db6}, +{"service_remove", (char *)0x00007dde}, +{"slip_arch_writeb", (char *)0x00004990}, +{"slip_input_byte", (char *)0x00006972}, +{"slip_process", (char *)0x000002de}, +{"slip_send", (char *)0x0000674c}, +{"sound_pause", (char *)0x00000756}, +{"sound_sensor", (char *)0x00003f1e}, +{"splhigh_", (char *)0x00004a26}, +{"splx_", (char *)0x00004a2e}, +{"strcmp", (char *)0x0000947e}, +{"strncmp", (char *)0x000094a2}, +{"symbols", (char *)0x0000793a}, +{"symtab_lookup", (char *)0x000066e4}, +{"tcp_attach", (char *)0x0000329c}, +{"tcp_connect", (char *)0x0000321a}, +{"tcp_listen", (char *)0x00003270}, +{"tcp_unlisten", (char *)0x00003244}, +{"tcpip_event", (char *)0x00000754}, +{"tcpip_input", (char *)0x00003444}, +{"tcpip_output", (char *)0x00003206}, +{"tcpip_poll_tcp", (char *)0x00003464}, +{"tcpip_poll_udp", (char *)0x00003456}, +{"tcpip_process", (char *)0x00000266}, +{"tcpip_set_forwarding", (char *)0x000031ba}, +{"tcpip_uipcall", (char *)0x00003472}, +{"temperature_sensor", (char *)0x00004154}, +{"timer_expired", (char *)0x00001ece}, +{"timer_reset", (char *)0x00001eb6}, +{"timer_restart", (char *)0x00001ebe}, +{"timer_set", (char *)0x00001ea2}, +{"timera1", (char *)0x00004a32}, +{"tr1001_clear_packets", (char *)0x00008594}, +{"tr1001_default_rxhandler_pt", (char *)0x00008086}, +{"tr1001_drv_process", (char *)0x000002ec}, +{"tr1001_drv_request_poll", (char *)0x00007eb8}, +{"tr1001_drv_send", (char *)0x00007ec2}, +{"tr1001_drv_set_slip_dump", (char *)0x00007ed4}, +{"tr1001_init", (char *)0x0000800a}, +{"tr1001_packets_dropped", (char *)0x0000858e}, +{"tr1001_packets_ok", (char *)0x00008588}, +{"tr1001_poll", (char *)0x000084c2}, +{"tr1001_rxbuf", (char *)0x0000077c}, +{"tr1001_rxhandler", (char *)0x0000805e}, +{"tr1001_rxstate", (char *)0x000002f8}, +{"tr1001_send", (char *)0x00008430}, +{"tr1001_set_speed", (char *)0x0000852c}, +{"tr1001_set_txpower", (char *)0x00007fb4}, +{"tr1001_sstrength", (char *)0x00008582}, +{"tr1001_sstrength_value", (char *)0x0000859e}, +{"udp_attach", (char *)0x000032a8}, +{"udp_broadcast_new", (char *)0x000032d2}, +{"udp_new", (char *)0x000032b4}, +{"uip_acc32", (char *)0x000005c8}, +{"uip_add32", (char *)0x0000213c}, +{"uip_appdata", (char *)0x000005d0}, +{"uip_broadcast_addr", (char *)0x0000212e}, +{"uip_buf", (char *)0x00000670}, +{"uip_chksum", (char *)0x000021e4}, +{"uip_conn", (char *)0x000005d2}, +{"uip_connect", (char *)0x000022c6}, +{"uip_conns", (char *)0x000005d4}, +{"uip_draddr", (char *)0x00000664}, +{"uip_ethaddr", (char *)0x0000025e}, +{"uip_flags", (char *)0x000005cc}, +{"uip_fw_default", (char *)0x00003840}, +{"uip_fw_forward", (char *)0x00003772}, +{"uip_fw_init", (char *)0x0000356e}, +{"uip_fw_output", (char *)0x0000371c}, +{"uip_fw_periodic", (char *)0x00003846}, +{"uip_fw_process", (char *)0x0000027e}, +{"uip_fw_register", (char *)0x00003834}, +{"uip_fw_service", (char *)0x00000276}, +{"uip_hostaddr", (char *)0x0000066c}, +{"uip_init", (char *)0x0000225a}, +{"uip_ipchksum", (char *)0x000021f6}, +{"uip_len", (char *)0x000005c4}, +{"uip_listen", (char *)0x000024d4}, +{"uip_listenports", (char *)0x00000654}, +{"uip_log", (char *)0x0000127a}, +{"uip_netmask", (char *)0x00000668}, +{"uip_process", (char *)0x00002536}, +{"uip_sappdata", (char *)0x000005c6}, +{"uip_send", (char *)0x00003190}, +{"uip_setipid", (char *)0x00002136}, +{"uip_slen", (char *)0x000006fe}, +{"uip_tcpchksum", (char *)0x00002250}, +{"uip_udp_conn", (char *)0x000005ce}, +{"uip_udp_conns", (char *)0x00000700}, +{"uip_udp_new", (char *)0x000023ca}, +{"uip_unlisten", (char *)0x000024ac}, +{"vector_ffe2", (char *)0x00003b08}, +{"vector_ffe6", (char *)0x000048a0}, +{"vector_ffe8", (char *)0x00003adc}, +{"vector_ffea", (char *)0x00004a32}, +{"vector_ffee", (char *)0x00003b34}, +{"vector_fff2", (char *)0x0000805e}, +{"vector_fff8", (char *)0x000042ec}, +{"vib_sensor", (char *)0x00003e86}, +{"vuprintf", (char *)0x00008ec8}, +{(void *)0, 0} }; diff --git a/platform/ethernut1/Makefile.ethernut1 b/platform/ethernut1/Makefile.ethernut1 new file mode 100644 index 000000000..6a85eb58a --- /dev/null +++ b/platform/ethernut1/Makefile.ethernut1 @@ -0,0 +1,16 @@ +CONTIKI_TARGET_DIRS = . dev apps net loader +CONTIKI_TARGET_MAIN = ethernut-main.o + +CONTIKI_SOURCEFILES += slip.c rs232.c serial.c ethernut-main.c \ + rtl8019-drv.c rtl8019.c rtl8019dev.c debug.c delay.c + +CONTIKIAVR=$(CONTIKI)/cpu/avr +CONTIKIBOARD=. + +APPS+=webserver telnetd #program-handler shell + +include $(CONTIKIAVR)/Makefile.avr + +%.u: %.$(TARGET) + avrdude -P /dev/cuaa0 -c stk500 -p atmega128 -v -e + avrdude -P /dev/cuaa0 -c stk500 -p atmega128 -v -U flash:w:$< diff --git a/platform/ethernut1/contiki-conf.h b/platform/ethernut1/contiki-conf.h new file mode 100644 index 000000000..a809bb45b --- /dev/null +++ b/platform/ethernut1/contiki-conf.h @@ -0,0 +1,156 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 + +typedef unsigned short clock_time_t; +#define CLOCK_CONF_SECOND 1000 + +void clock_delay(unsigned int us2); + +void clock_wait(int ms10); + +void clock_set_seconds(unsigned long s); +unsigned long clock_seconds(void); + + +/* + * This file is used for setting various compile time settings for the + * CTK GUI toolkit. +*/ + +#include "ctk/ctk-vncarch.h" + +/* Defines which key that is to be used for activating the menus */ +#define CTK_CONF_MENU_KEY CH_F1 + +/* Defines which key that is to be used for switching the frontmost + window. */ +#define CTK_CONF_WINDOWSWITCH_KEY CH_ESC + +/* Defines which key that is to be used for switching to the next + widget. */ +#define CTK_CONF_WIDGETDOWN_KEY CH_TAB + +/* Defines which key that is to be used for switching to the prevoius + widget. */ +#define CTK_CONF_WIDGETUP_KEY 1 + +/* Toggles support for icons. */ +#define CTK_CONF_ICONS 1 /* 107 bytes */ + +/* Toggles support for icon bitmaps. */ +#define CTK_CONF_ICON_BITMAPS 1 + +/* Toggles support for icon textmaps. */ +#define CTK_CONF_ICON_TEXTMAPS 1 + +/* Toggles support for movable windows. */ +#define CTK_CONF_WINDOWMOVE 1 /* 333 bytes */ + +/* Toggles support for closable windows. */ +#define CTK_CONF_WINDOWCLOSE 1 /* 14 bytes */ + +/* Toggles support for menus. */ +#define CTK_CONF_MENUS 1 /* 1384 bytes */ + +/* Toggles mouse support (must have support functions in the +architecture specific files to work). */ +#define CTK_CONF_MOUSE_SUPPORT 1 + +/* Defines the default width of a menu. */ +#define CTK_CONF_MENUWIDTH 16 +/* The maximum number of menu items in each menu. */ +#define CTK_CONF_MAXMENUITEMS 10 + + +/* Maximum number of clients to the telnet server */ +#define CTK_TERM_CONF_MAX_TELNET_CLIENTS 3 + +/* Telnet server port */ +#define CTK_TERM_CONF_TELNET_PORT 23 + +/* Serial server output buffer size */ +#define CTK_TERM_CONF_SERIAL_BUFFER_SIZE 300 + +/* Maximum number of clients to the terminal module. + Should be set to CTK_TERM_CONF_MAX_TELNET_CLIENTS or + CTK_TERM_CONF_MAX_TELNET_CLIENTS+1 if the serial server is used too +*/ +#define CTK_TERM_CONF_MAX_CLIENTS (CTK_TERM_CONF_MAX_TELNET_CLIENTS+1) + +#define CTK_VNCSERVER_CONF_NUMCONNS 8 + +#define CTK_VNCSERVER_CONF_MAX_ICONS 8 + +#define EMAIL_CONF_WIDTH 48 +#define EMAIL_CONF_HEIGHT 16 + +#define IRC_CONF_WIDTH 78 +#define IRC_CONF_HEIGHT 20 + +#define IRC_CONF_SYSTEM_STRING "ethernut" + + +#define LIBCONIO_CONF_SCREEN_WIDTH 70 +#define LIBCONIO_CONF_SCREEN_HEIGHT 40 + + + +#define LOG_CONF_ENABLED 0 + +#define PROGRAM_HANDLER_CONF_MAX_NUMDSCS 10 + +#define TELNETD_CONF_LINELEN 64 +#define TELNETD_CONF_NUMLINES 16 + + +#define UIP_CONF_MAX_CONNECTIONS 10 +#define UIP_CONF_MAX_LISTENPORTS 10 +#define UIP_CONF_BUFFER_SIZE 100 + +#define UIP_CONF_TCP_SPLIT 1 + +#define UIP_CONF_UDP_CONNS 6 + +#define UIP_CONF_FWCACHE_SIZE 1 + +#define UIP_CONF_BROADCAST 1 + + +/* The size of the HTML viewing area. */ +#define WWW_CONF_WEBPAGE_WIDTH 46 +#define WWW_CONF_WEBPAGE_HEIGHT 25 + +/* The size of the "Back" history. */ +#define WWW_CONF_HISTORY_SIZE 8 + +/* Defines the maximum length of an URL */ +#define WWW_CONF_MAX_URLLEN 160 + +/* The maxiumum number of widgets (i.e., hyperlinks, form elements) on + a page. */ +#define WWW_CONF_MAX_NUMPAGEWIDGETS 30 + +/* Turns
        support on or off; must be on for forms to work. */ +#define WWW_CONF_RENDERSTATE 1 + +/* Toggles support for HTML forms. */ +#define WWW_CONF_FORMS 1 + +/* Maximum lengths for various HTML form parameters. */ +#define WWW_CONF_MAX_FORMACTIONLEN 80 +#define WWW_CONF_MAX_FORMNAMELEN 40 +#define WWW_CONF_MAX_INPUTNAMELEN 40 +#define WWW_CONF_MAX_INPUTVALUELEN 40 + +#define WWW_CONF_PAGEVIEW 1 + +typedef unsigned char u8_t; +typedef unsigned short u16_t; +typedef unsigned long u32_t; +typedef unsigned short uip_stats_t; + + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/ethernut1/ethernut-main.c b/platform/ethernut1/ethernut-main.c new file mode 100644 index 000000000..b3fa6780c --- /dev/null +++ b/platform/ethernut1/ethernut-main.c @@ -0,0 +1,101 @@ + +/* Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * 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: ethernut-main.c,v 1.1 2006/06/17 22:41:28 adamdunkels Exp $ + * + */ + +#include "contiki.h" +#include "contiki-net.h" +#include "webserver-nogui.h" +#include "telnetd.h" + +#include "dev/rtl8019-drv.h" + +#include +#include +#include +#include + +PROCINIT(&etimer_process, &tcpip_process, &rtl8019_drv_process, + &telnetd_process); + +static const struct uip_eth_addr ethaddr = {{0x00,0x06,0x98,0x01,0x02,0x29}}; + +int +main(void) +{ + uip_ipaddr_t addr; + + /* + * GCC depends on register r1 set to 0. + */ + asm volatile ("clr r1"); + + /* + * No interrupts used. + */ + cli(); + + /* + * Enable external data and address + * bus. + */ + MCUCR = _BV(SRE) | _BV(SRW); + + clock_init(); + rs232_init(); + sei(); + + + process_init(); + + uip_ipaddr(addr, 193,10,67,152); + uip_sethostaddr(addr); + + uip_setethaddr(ethaddr); + + procinit_init(); + + rs232_print("Initialized\n"); + + while(1) { + process_run(); + } + + return 0; +} + +void +putchar(int c) +{ + rs232_send(c); +} diff --git a/platform/ethernut2/Makefile.ethernut2 b/platform/ethernut2/Makefile.ethernut2 new file mode 100644 index 000000000..7f2c2d531 --- /dev/null +++ b/platform/ethernut2/Makefile.ethernut2 @@ -0,0 +1,10 @@ +CONTIKI_TARGET_DIRS = . dev apps net loader +CONTIKI_TARGET_MAIN = ethernut-main.o + +CONTIKI_SOURCEFILES += slip.c rs232.c serial.c ethernut-main.c + + +CONTIKIAVR=$(CONTIKI)/cpu/avr +CONTIKIBOARD=. +MCU=atmega128 +include $(CONTIKIAVR)/Makefile.avr diff --git a/platform/ethernut2/contiki-conf.h b/platform/ethernut2/contiki-conf.h new file mode 100644 index 000000000..bd92af78c --- /dev/null +++ b/platform/ethernut2/contiki-conf.h @@ -0,0 +1,159 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 + +typedef unsigned short clock_time_t; +#define CLOCK_CONF_SECOND 1000 + +#define NUT_CPU_FREQ 14745600UL +#define AVR_CLK_COUNT (NUT_CPU_FREQ / (128L * CLOCK_CONF_SECOND) + 0.5) + +void clock_delay(unsigned int us2); + +void clock_wait(int ms10); + +void clock_set_seconds(unsigned long s); +unsigned long clock_seconds(void); + + +/* + * This file is used for setting various compile time settings for the + * CTK GUI toolkit. +*/ + +#include "ctk/ctk-vncarch.h" + +/* Defines which key that is to be used for activating the menus */ +#define CTK_CONF_MENU_KEY CH_F1 + +/* Defines which key that is to be used for switching the frontmost + window. */ +#define CTK_CONF_WINDOWSWITCH_KEY CH_ESC + +/* Defines which key that is to be used for switching to the next + widget. */ +#define CTK_CONF_WIDGETDOWN_KEY CH_TAB + +/* Defines which key that is to be used for switching to the prevoius + widget. */ +#define CTK_CONF_WIDGETUP_KEY 1 + +/* Toggles support for icons. */ +#define CTK_CONF_ICONS 1 /* 107 bytes */ + +/* Toggles support for icon bitmaps. */ +#define CTK_CONF_ICON_BITMAPS 1 + +/* Toggles support for icon textmaps. */ +#define CTK_CONF_ICON_TEXTMAPS 1 + +/* Toggles support for movable windows. */ +#define CTK_CONF_WINDOWMOVE 1 /* 333 bytes */ + +/* Toggles support for closable windows. */ +#define CTK_CONF_WINDOWCLOSE 1 /* 14 bytes */ + +/* Toggles support for menus. */ +#define CTK_CONF_MENUS 1 /* 1384 bytes */ + +/* Toggles mouse support (must have support functions in the +architecture specific files to work). */ +#define CTK_CONF_MOUSE_SUPPORT 1 + +/* Defines the default width of a menu. */ +#define CTK_CONF_MENUWIDTH 16 +/* The maximum number of menu items in each menu. */ +#define CTK_CONF_MAXMENUITEMS 10 + + +/* Maximum number of clients to the telnet server */ +#define CTK_TERM_CONF_MAX_TELNET_CLIENTS 3 + +/* Telnet server port */ +#define CTK_TERM_CONF_TELNET_PORT 23 + +/* Serial server output buffer size */ +#define CTK_TERM_CONF_SERIAL_BUFFER_SIZE 300 + +/* Maximum number of clients to the terminal module. + Should be set to CTK_TERM_CONF_MAX_TELNET_CLIENTS or + CTK_TERM_CONF_MAX_TELNET_CLIENTS+1 if the serial server is used too +*/ +#define CTK_TERM_CONF_MAX_CLIENTS (CTK_TERM_CONF_MAX_TELNET_CLIENTS+1) + +#define CTK_VNCSERVER_CONF_NUMCONNS 8 + +#define CTK_VNCSERVER_CONF_MAX_ICONS 8 + +#define EMAIL_CONF_WIDTH 48 +#define EMAIL_CONF_HEIGHT 16 + +#define IRC_CONF_WIDTH 78 +#define IRC_CONF_HEIGHT 20 + +#define IRC_CONF_SYSTEM_STRING "ethernut" + + +#define LIBCONIO_CONF_SCREEN_WIDTH 70 +#define LIBCONIO_CONF_SCREEN_HEIGHT 40 + + + +#define LOG_CONF_ENABLED 0 + +#define PROGRAM_HANDLER_CONF_MAX_NUMDSCS 10 + +#define TELNETD_CONF_LINELEN 32 +#define TELNETD_CONF_NUMLINES 16 + + +#define UIP_CONF_MAX_CONNECTIONS 10 +#define UIP_CONF_MAX_LISTENPORTS 10 +#define UIP_CONF_BUFFER_SIZE 100 + +#define UIP_CONF_TCP_SPLIT 1 + +#define UIP_CONF_UDP_CONNS 6 + +#define UIP_CONF_FWCACHE_SIZE 1 + +#define UIP_CONF_BROADCAST 1 + + +/* The size of the HTML viewing area. */ +#define WWW_CONF_WEBPAGE_WIDTH 46 +#define WWW_CONF_WEBPAGE_HEIGHT 25 + +/* The size of the "Back" history. */ +#define WWW_CONF_HISTORY_SIZE 8 + +/* Defines the maximum length of an URL */ +#define WWW_CONF_MAX_URLLEN 160 + +/* The maxiumum number of widgets (i.e., hyperlinks, form elements) on + a page. */ +#define WWW_CONF_MAX_NUMPAGEWIDGETS 30 + +/* Turns
        support on or off; must be on for forms to work. */ +#define WWW_CONF_RENDERSTATE 1 + +/* Toggles support for HTML forms. */ +#define WWW_CONF_FORMS 1 + +/* Maximum lengths for various HTML form parameters. */ +#define WWW_CONF_MAX_FORMACTIONLEN 80 +#define WWW_CONF_MAX_FORMNAMELEN 40 +#define WWW_CONF_MAX_INPUTNAMELEN 40 +#define WWW_CONF_MAX_INPUTVALUELEN 40 + +#define WWW_CONF_PAGEVIEW 1 + +typedef unsigned char u8_t; +typedef unsigned short u16_t; +typedef unsigned long u32_t; +typedef unsigned short uip_stats_t; + + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/ethernut2/ethernut-main.c b/platform/ethernut2/ethernut-main.c new file mode 100644 index 000000000..9226d78a9 --- /dev/null +++ b/platform/ethernut2/ethernut-main.c @@ -0,0 +1,100 @@ + +/* Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * 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: ethernut-main.c,v 1.1 2006/06/17 22:41:28 adamdunkels Exp $ + * + */ + +#include "contiki.h" +#include "contiki-net.h" +#include "dev/serial.h" +#include "dev/slip.h" +#include "dev/rs232.h" +#include "telnetd.h" + +#include +/*static void setup_xram(void) __attribute__ ((naked)) \ + __attribute__ ((section (".init1"))); + +static void +setup_xram(void) +{ + outp(BV(SRE) | BV(SRW), MCUCR); +}*/ + +static struct uip_fw_netif slipif = + {UIP_FW_NETIF(0,0,0,0, 0,0,0,0, slip_send)}; + +PROCESS(serial_test, "Serial test"); + +PROCESS_THREAD(serial_test, ev, data) +{ + PROCESS_BEGIN(); + + while(1) { + PROCESS_WAIT_EVENT_UNTIL(ev == serial_event_message); + rs232_print(data); + } + PROCESS_END(); +} + +PROCINIT(&etimer_process, &serial_process, &slip_process, + &uip_fw_process); + +int +main(void) +{ + uip_ipaddr_t addr; + + clock_init(); + rs232_init(); + rs232_set_input(slip_input_byte); + + sei(); + + /* Initialize drivers and event kernal */ + process_init(); + + uip_ipaddr(addr, 172,16,0,2); + uip_sethostaddr(addr); + + procinit_init(); + autostart_start(autostart_processes); + uip_fw_default(&slipif); + + rs232_print_p(PSTR("Initialized\n")); + + while(1) { + process_run(); + } + + return 0; +} diff --git a/platform/gtk/Makefile b/platform/gtk/Makefile new file mode 100644 index 000000000..dd2be6426 --- /dev/null +++ b/platform/gtk/Makefile @@ -0,0 +1,38 @@ +# Copyright (c) 2002-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: Makefile,v 1.1 2006/06/17 22:41:28 adamdunkels Exp $ +# + +all: contiki-main + +CONTIKI=../.. +APPS=program-handler calc dhcp webbrowser editor ftp process-list shell irc netconf +TARGET=gtk +-include $(CONTIKI)/Makefile.include diff --git a/platform/gtk/background.png b/platform/gtk/background.png new file mode 100644 index 000000000..bd53886ba Binary files /dev/null and b/platform/gtk/background.png differ diff --git a/platform/gtk/clock.c b/platform/gtk/clock.c new file mode 100644 index 000000000..e3fcf5a4f --- /dev/null +++ b/platform/gtk/clock.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: clock.c,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "sys/clock.h" +/*---------------------------------------------------------------------------*/ +#include + +clock_time_t +clock_time(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +/*---------------------------------------------------------------------------*/ diff --git a/platform/gtk/contiki-conf.h b/platform/gtk/contiki-conf.h new file mode 100644 index 000000000..21cb30b3a --- /dev/null +++ b/platform/gtk/contiki-conf.h @@ -0,0 +1,174 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL + + + +typedef unsigned long clock_time_t; +#define CLOCK_CONF_SECOND 1000 + + + +#include "ctk-arch.h" + +#define CTK_CONF_MOUSE_SUPPORT 1 + +#define CTK_CONF_MENU_KEY CH_F1 + +#define CTK_CONF_WINDOWSWITCH_KEY CH_F3 + +#define CTK_CONF_WIDGETDOWN_KEY CH_TAB + +#define CTK_CONF_WIDGETUP_KEY CH_F5 + +#define CTK_CONF_ICONS 1 + +#define CTK_CONF_ICON_BITMAPS 1 + +#define CTK_CONF_ICON_TEXTMAPS 1 + +#define CTK_CONF_WINDOWMOVE 1 + +#define CTK_CONF_WINDOWCLOSE 1 + +#define CTK_CONF_MENUS 1 + +#define CTK_CONF_MENUWIDTH 16 +#define CTK_CONF_MAXMENUITEMS 10 + +#define CTK_CONF_WIDGET_FLAGS 1 + + + +#define COLOR_BLACK 0 +#define COLOR_WHITE 1 + +#define BORDERCOLOR COLOR_BLACK +#define SCREENCOLOR COLOR_BLACK +#define BACKGROUNDCOLOR COLOR_BLACK + +#define WINDOWCOLOR_FOCUS COLOR_WHITE +#define WINDOWCOLOR COLOR_WHITE + +#define DIALOGCOLOR COLOR_WHITE + +#define WIDGETCOLOR_HLINK COLOR_WHITE +#define WIDGETCOLOR_FWIN COLOR_WHITE +#define WIDGETCOLOR COLOR_WHITE +#define WIDGETCOLOR_DIALOG COLOR_WHITE +#define WIDGETCOLOR_FOCUS COLOR_WHITE + +#define MENUCOLOR COLOR_WHITE +#define OPENMENUCOLOR COLOR_WHITE +#define ACTIVEMENUITEMCOLOR COLOR_WHITE + + +#define CTK_VNCSERVER_CONF_NUMCONNS 10 + +#define CTK_VNCSERVER_CONF_MAX_ICONS 16 + + + + +#define EMAIL_CONF_WIDTH 76 +#define EMAIL_CONF_HEIGHT 25 + + +#define IRC_CONF_WIDTH 78 +#define IRC_CONF_HEIGHT 21 + +#define IRC_CONF_SYSTEM_STRING "GTK simulation" + + +#define LIBCONIO_CONF_SCREEN_WIDTH 80 +#define LIBCONIO_CONF_SCREEN_HEIGHT 45 + + + +#define LOG_CONF_ENABLED 0 + + +#define PROGRAM_HANDLER_CONF_MAX_NUMDSCS 10 + + +#define SHELL_GUI_CONF_XSIZE 46 +#define SHELL_GUI_CONF_YSIZE 22 + + + +#define TELNETD_CONF_LINELEN 36 +#define TELNETD_CONF_NUMLINES 16 + + +/** + * The 8-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * char" works for most compilers. + */ +typedef unsigned char u8_t; + +/** + * The 16-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * short" works for most compilers. + */ +typedef unsigned short u16_t; + +typedef unsigned long u32_t; + +/** + * The statistics data type. + * + * This datatype determines how high the statistics counters are able + * to count. + */ +typedef unsigned short uip_stats_t; + + + +#define UIP_CONF_MAX_CONNECTIONS 40 +#define UIP_CONF_MAX_LISTENPORTS 40 +#define UIP_CONF_BUFFER_SIZE 420 + +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN + +#define UIP_CONF_TCP_SPLIT 1 + +#define UIP_CONF_LOGGING 1 + +#define UIP_CONF_UDP_CHECKSUMS 1 + + + + + +#define VNC_CONF_REFRESH_ROWS 8 + + +#define WWW_CONF_WEBPAGE_WIDTH 76 +#define WWW_CONF_WEBPAGE_HEIGHT 30 + +#define WWW_CONF_HISTORY_SIZE 40 + +#define WWW_CONF_MAX_URLLEN 200 + +#define WWW_CONF_MAX_NUMPAGEWIDGETS 80 + +#define WWW_CONF_RENDERSTATE 1 + +#define WWW_CONF_FORMS 1 + +#define WWW_CONF_MAX_FORMACTIONLEN 200 +#define WWW_CONF_MAX_FORMNAMELEN 200 +#define WWW_CONF_MAX_INPUTNAMELEN 200 +#define WWW_CONF_MAX_INPUTVALUELEN 240 + +#define WWW_CONF_PAGEVIEW 1 + + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/gtk/contiki-main.c b/platform/gtk/contiki-main.c new file mode 100644 index 000000000..59fe25a0d --- /dev/null +++ b/platform/gtk/contiki-main.c @@ -0,0 +1,197 @@ +/* + * 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: contiki-main.c,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + * + */ + + +#include +#include + +#include "contiki.h" +#include "contiki-net.h" + +#include "ctk/ctk.h" + +#include "ctk/ctk-vncserver.h" +#include "ctk/ctk-termtelnet.h" + +#include "cfs/cfs-posix.h" + +#include "tapdev-service.h" +#include "program-handler.h" +#include "webserver.h" +#include "ctk-gtksim-service.h" + +#include "about-dsc.h" +#include "calc-dsc.h" +#include "dhcp-dsc.h" +#include "editor-dsc.h" +#include "email-dsc.h" +#include "ftp-dsc.h" +#include "irc-dsc.h" +#include "netconf-dsc.h" +#include "process-list-dsc.h" +#include "shell-dsc.h" +#include "vnc-dsc.h" +#include "www-dsc.h" + +#include "cmdd.h" + + +u8_t tapdev_send(void); +static struct uip_fw_netif tapif = + {UIP_FW_NETIF(0,0,0,0, 0,0,0,0, tapdev_send)}; + + +PROCESS(init_process, "Init"); + +PROCESS_THREAD(init_process, ev, data) +{ + u16_t addr[2]; + + PROCESS_BEGIN(); + + uip_ipaddr(addr, 192,168,2,2); + uip_sethostaddr(addr); + + uip_ipaddr(addr, 192,168,2,1); + uip_setdraddr(addr); + + uip_ipaddr(addr, 255,255,255,0); + uip_setnetmask(addr); + + printf("init\n"); + + program_handler_add(&netconf_dsc, "Network setup", 1); + program_handler_add(&ftp_dsc, "FTP client", 1); + program_handler_add(&editor_dsc, "Editor", 1); + program_handler_add(&www_dsc, "Web browser", 1); + program_handler_add(&processes_dsc, "Processes", 1); + program_handler_add(&shell_dsc, "Command shell", 1); + program_handler_add(&calc_dsc, "Calculator", 1); + /* program_handler_add(&email_dsc, "E-mail", 1);*/ + + program_handler_add(&irc_dsc, "IRC", 1); + /* program_handler_add(&vnc_dsc, "VNC client", 1);*/ + + program_handler_add(&dhcp_dsc, "DHCP client", 1); + + uip_fw_default(&tapif); + + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} + + +PROCINIT(&tcpip_process, &ctk_process, &tapdev_process, + &ctk_gtksim_service_process, &resolv_process, + &program_handler_process, + &uip_fw_process, &cfs_posix_process, + &init_process); + +static gint +idle_callback(gpointer data) +{ + process_run(); + return TRUE; +} +/*-----------------------------------------------------------------------------------*/ +int +main(int argc, char **argv) +{ + u16_t addr[2]; + + + gtk_init(&argc, &argv); + + process_init(); + + procinit_init(); + + uip_ipaddr(addr, 192,168,2,2); + uip_sethostaddr(addr); + + uip_ipaddr(addr, 192,168,2,1); + uip_setdraddr(addr); + + uip_ipaddr(addr, 255,255,255,0); + uip_setnetmask(addr); + + /* program_handler_add(&netconf_dsc, "Network setup", 1); + program_handler_add(&ftp_dsc, "FTP client", 1); + program_handler_add(&editor_dsc, "Editor", 1); + program_handler_add(&www_dsc, "Web browser", 1); + program_handler_add(&processes_dsc, "Processes", 1); + program_handler_add(&shell_dsc, "Command shell", 1); + program_handler_add(&calc_dsc, "Calculator", 1);*/ + /* program_handler_add(&email_dsc, "E-mail", 1);*/ + + /* program_handler_add(&irc_dsc, "IRC", 1);*/ + /* program_handler_add(&vnc_dsc, "VNC client", 1);*/ + + /* program_handler_add(&dhcp_dsc, "DHCP client", 1);*/ + + uip_fw_default(&tapif); + + gtk_timeout_add(20, idle_callback, NULL); + gtk_main(); + + + return 0; + + argv = argv; + argc = argc; +} +/*-----------------------------------------------------------------------------------*/ +#undef LITTLE_ENDIAN +#undef BIG_ENDIAN +#undef BYTE_ORDER +#undef HTONS + +/*-----------------------------------------------------------------------------------*/ + +void nntpc_done(int i) {} + +void log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} + +void +uip_log(char *m) +{ + printf("%s\n", m); +} diff --git a/platform/gtk/ctk/conio.h b/platform/gtk/ctk/conio.h new file mode 100644 index 000000000..e221d6282 --- /dev/null +++ b/platform/gtk/ctk/conio.h @@ -0,0 +1,47 @@ +/* + * 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: conio.h,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + * + */ +#ifndef __CONIO_H__ +#define __CONIO_H__ + + +#define CH_ULCORNER '+' +#define CH_URCORNER '+' +#define CH_LLCORNER '+' +#define CH_LRCORNER '+' + +#include "libconio.h" + +#endif /* __CONIO_H__ */ + diff --git a/platform/gtk/ctk/ctk-arch.h b/platform/gtk/ctk/ctk-arch.h new file mode 100644 index 000000000..70b132ed9 --- /dev/null +++ b/platform/gtk/ctk/ctk-arch.h @@ -0,0 +1,45 @@ +/* + * 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. + * + * $Id: ctk-arch.h,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + * + */ + +#ifndef __CTK_ARCH_H__ +#define __CTK_ARCH_H__ + +#if WITH_CTKVNC +#include "ctk-vncarch.h" +#else +#include "ctk-gtksim.h" +#endif + +#define ctk_arch_isprint(x) isprint(x) + +#endif /* __CTK_ARCH_H__ */ diff --git a/platform/gtk/ctk/ctk-gtksim-conio.c b/platform/gtk/ctk/ctk-gtksim-conio.c new file mode 100644 index 000000000..20d4e8539 --- /dev/null +++ b/platform/gtk/ctk/ctk-gtksim-conio.c @@ -0,0 +1,359 @@ +/* + * 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. All advertising materials mentioning features or use of this + * software must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-gtksim-conio.c,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + * + */ + +/* This file provides a very simple implementation of CTK using the + GTK (Gimp toolkit) under FreeBSD/Linux. */ + +#include + +#include "libconio.h" + +#include "ctk/ctk.h" +#include "ctk-draw.h" + +#include +#include +#include + +#define FONT_HEIGHT 14 +#define FONT_WIDTH 8 +#define FONT_HEIGHT_BASELINE 11 + +#define SCREEN_WIDTH LIBCONIO_CONF_SCREEN_WIDTH +#define SCREEN_HEIGHT LIBCONIO_CONF_SCREEN_HEIGHT + +static GdkPixmap *pixmap = NULL; +static GtkWidget *drawing_area; +static GdkFont *font; + +static int mouse_x, mouse_y, mouse_button; + +/*-----------------------------------------------------------------------------------*/ +void +ctk_arch_draw_char(char c, + unsigned char x, unsigned char y, + unsigned char reversed, + unsigned char color) +{ + char str[2]; + + str[0] = c; + str[1] = 0; + + if(reversed) { + gdk_draw_rectangle(pixmap, + drawing_area->style->black_gc, + TRUE, + x * FONT_WIDTH, + y * FONT_HEIGHT, + FONT_WIDTH, FONT_HEIGHT); + + gdk_draw_string(pixmap, + font, + drawing_area->style->white_gc, + x * FONT_WIDTH, FONT_HEIGHT_BASELINE + y * FONT_HEIGHT, + str); + } else { + gdk_draw_rectangle(pixmap, + drawing_area->style->white_gc, + TRUE, + x * FONT_WIDTH, + y * FONT_HEIGHT, + FONT_WIDTH, FONT_HEIGHT); + + gdk_draw_string(pixmap, + font, + drawing_area->style->black_gc, + x * FONT_WIDTH, FONT_HEIGHT_BASELINE + y * FONT_HEIGHT, + str); + } + + gdk_draw_pixmap(drawing_area->window, + drawing_area->style->fg_gc[GTK_WIDGET_STATE (drawing_area)], + pixmap, + x * FONT_WIDTH, + y * FONT_HEIGHT, + x * FONT_WIDTH, + y * FONT_HEIGHT, + FONT_WIDTH, FONT_HEIGHT); + +} +/*-----------------------------------------------------------------------------------*/ +#define NUMKEYS 100 +static ctk_arch_key_t keys[NUMKEYS]; +static int firstkey, lastkey; + +unsigned char +ctk_arch_keyavail(void) +{ + return firstkey != lastkey; +} +/*-----------------------------------------------------------------------------------*/ +ctk_arch_key_t +ctk_arch_getkey(void) +{ + ctk_arch_key_t key; + key = keys[firstkey]; + + if(firstkey != lastkey) { + ++firstkey; + if(firstkey >= NUMKEYS) { + firstkey = 0; + } + } + + return key; +} +/*-----------------------------------------------------------------------------------*/ +static gint +configure_event(GtkWidget *widget, GdkEventConfigure *event) +{ + if(pixmap != NULL) { + gdk_pixmap_unref(pixmap); + } + + pixmap = gdk_pixmap_new(widget->window, + widget->allocation.width, + widget->allocation.height, + -1); + + if(pixmap == NULL) { + printf("gdk_pixmap_new == NULL\n"); + exit(1); + } + gdk_draw_rectangle(pixmap, + widget->style->white_gc, + TRUE, + 0, 0, + widget->allocation.width, + widget->allocation.height); + + return TRUE; +} + +/* Redraw the screen from the backing pixmap */ +static gint +expose_event (GtkWidget * widget, GdkEventExpose * event) +{ + /* draw_screen();*/ + gdk_draw_pixmap(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE (widget)], + pixmap, + event->area.x, event->area.y, + event->area.x, event->area.y, + event->area.width, event->area.height); + return FALSE; +} + +static gint +key_press_event (GtkWidget * widget, GdkEventKey * event) +{ + if(event->keyval == GDK_Shift_L || + event->keyval == GDK_Shift_R) { + return TRUE; + } + keys[lastkey] = event->keyval; + ++lastkey; + if(lastkey >= NUMKEYS) { + lastkey = 0; + } + + return TRUE; +} + +static gint +key_release_event (GtkWidget * widget, GdkEventKey * event) +{ + return TRUE; +} + +static gint +motion_notify_event (GtkWidget * widget, GdkEventMotion * event) +{ + mouse_x = event->x; + mouse_y = event->y; + return TRUE; +} + +static gint +button_press_event (GtkWidget * widget, GdkEventButton * event) +{ + mouse_button = event->button; + return TRUE; +} + +static gint +button_release_event (GtkWidget * widget, GdkEventButton * event) +{ + mouse_button = 0; + return TRUE; +} + +static void +quit(void) +{ + gtk_exit(0); +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_gtksim_init(int *argc, char **argv[]) +{ + GtkWidget *window; +#if 0 + GtkWidget *vbox; +#endif + + gtk_init(argc, argv); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(window, "Contiki GTKsim"); + +#if 0 + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER (window), vbox); + gtk_widget_show(vbox); +#endif + gtk_signal_connect(GTK_OBJECT (window), "destroy", + GTK_SIGNAL_FUNC (quit), NULL); + + /* Create the drawing area */ + + drawing_area = gtk_drawing_area_new(); + gtk_drawing_area_size(GTK_DRAWING_AREA (drawing_area), + SCREEN_WIDTH * FONT_WIDTH, + SCREEN_HEIGHT * FONT_HEIGHT); +#if 0 + gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0); +#else + gtk_container_add(GTK_CONTAINER(window), drawing_area); +#endif + + gtk_widget_show(drawing_area); + + /* Load a fixed width font. */ + /* font = gdk_font_load("-*-gamow-medium-r-*-*-*-90-*-*-*-*-*-*");*/ + /* font = gdk_font_load("-*-courier-*-r-normal-*-14-*-*-*-m-*-iso8859-1");*/ + font = gdk_font_load("-*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-1"); + if(font != NULL) { + printf("Font loaded OK\n"); + } else { + printf("Font loading failed\n"); + exit(1); + } + + + /* Signals used to handle backing pixmap */ + + gtk_signal_connect(GTK_OBJECT (drawing_area), "expose_event", + (GtkSignalFunc) expose_event, NULL); + gtk_signal_connect(GTK_OBJECT (drawing_area), "configure_event", + (GtkSignalFunc) configure_event, NULL); + + /* Event signals */ + + gtk_signal_connect(GTK_OBJECT (window), "key_press_event", + (GtkSignalFunc) key_press_event, NULL); + gtk_signal_connect(GTK_OBJECT (window), "key_release_event", + (GtkSignalFunc) key_release_event, NULL); + + gtk_signal_connect(GTK_OBJECT (drawing_area), "motion_notify_event", + (GtkSignalFunc) motion_notify_event, NULL); + + gtk_signal_connect(GTK_OBJECT (drawing_area), "button_press_event", + (GtkSignalFunc) button_press_event, NULL); + + gtk_signal_connect(GTK_OBJECT (drawing_area), "button_release_event", + (GtkSignalFunc) button_release_event, NULL); + + gtk_widget_set_events(drawing_area, gtk_widget_get_events (drawing_area) + | GDK_KEY_PRESS_MASK + | GDK_KEY_RELEASE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK); + + gtk_widget_show(window); + +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_init(void) +{ + +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_x(void) +{ + return mouse_x; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_y(void) +{ + return mouse_y; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_xtoc(unsigned short x) +{ + return x / FONT_WIDTH; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_ytoc(unsigned short y) +{ + return y / FONT_HEIGHT; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_button(void) +{ + return mouse_button; +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_hide(void) +{ +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_show(void) +{ +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/gtk/ctk/ctk-gtksim-draw.c b/platform/gtk/ctk/ctk-gtksim-draw.c new file mode 100644 index 000000000..868ff1878 --- /dev/null +++ b/platform/gtk/ctk/ctk-gtksim-draw.c @@ -0,0 +1,172 @@ + +#include "ctk-gtksim.h" + +#include "ctk-gtksim-draw.h" + +#define RASTER_X 8 + +#define FONT_BASELINE 8 + +struct ctk_gtksim_draw_font { + /* GdkFont *font;*/ + PangoFontDescription *font; +}; + +struct ctk_gtksim_draw_color { + GdkGC *color; +}; + +struct ctk_gtksim_draw_font ctk_gtksim_draw_font_normal, + ctk_gtksim_draw_font_bold, + ctk_gtksim_draw_font_menu, + ctk_gtksim_draw_font_monospace, + ctk_gtksim_draw_font_monospace_bold; + +struct ctk_gtksim_draw_color ctk_gtksim_draw_color_white, + ctk_gtksim_draw_color_lightgray, + ctk_gtksim_draw_color_midgray, + ctk_gtksim_draw_color_darkgray, + ctk_gtksim_draw_color_ddarkgray, + ctk_gtksim_draw_color_black, + ctk_gtksim_draw_color_blue; + +/*static GdkFont *font, *ctk_gtksim_draw_font_bold, *menufont, *ctk_gtksim_draw_font_monospace;*/ + +static PangoLayout *layout; + +/*--------------------------------------------------------------------------*/ +int +ctk_gtksim_draw_string_width(struct ctk_gtksim_draw_font *font, + char *str, int monospace) +{ + int width; + if(monospace) { + return strlen(str) * RASTER_X; + } else { + pango_layout_set_text(layout, str, -1); + pango_layout_set_font_description(layout, font->font); + pango_layout_get_size(layout, &width, NULL); + return width / PANGO_SCALE; + /* return gdk_string_width(font->font, str);*/ + } +} +/*--------------------------------------------------------------------------*/ +void +ctk_gtksim_draw_string(struct ctk_gtksim_draw_font *font, + struct ctk_gtksim_draw_color *color, + int x, int y, char *str, + int monospace) +{ + int i; + char text[2]; + + pango_layout_set_font_description(layout, font->font); + + if(monospace) { + text[1] = 0; + for(i = 0; i < strlen(str); ++i) { + text[0] = str[i]; + pango_layout_set_text(layout, text, 1); + + gdk_draw_layout(ctk_gtksim_pixmap, color->color, + x, y, layout); + /* gdk_draw_string(ctk_gtksim_pixmap, font->font, color->color, + x, y + FONT_BASELINE, text);*/ + x += RASTER_X; + } + } else { + pango_layout_set_text(layout, str, -1); + + gdk_draw_layout(ctk_gtksim_pixmap, color->color, + x, y, layout); + /* gdk_draw_string(ctk_gtksim_pixmap, font->font, color->color, + x, y + FONT_BASELINE, str);*/ + } +} +/*--------------------------------------------------------------------------*/ +static GdkGC * +get_color(unsigned short r, unsigned short g, unsigned short b) +{ + GdkGCValues values; + GdkColor color; + + color.pixel = 0; + color.red = r; + color.green = g; + color.blue = b; + + if(gdk_colormap_alloc_color(gdk_colormap_get_system(), + &color, FALSE, TRUE)) { + } + + values.foreground = color; + + return gdk_gc_new_with_values(ctk_gtksim_drawing_area->window, + &values, + GDK_GC_FOREGROUND); +} +/*--------------------------------------------------------------------------*/ +void +ctk_gtksim_draw_init(void) +{ + /* + ctk_gtksim_draw_font_normal.font = + gdk_font_load("-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*"); + if(ctk_gtksim_draw_font_normal.font != NULL) { + printf("ctk-gtksim-service: Font loaded OK\n"); + } else { + printf("ctk-gtksim-service: Font loading failed\n"); + exit(1); + } + + ctk_gtksim_draw_font_bold.font = + gdk_font_load("-*-helvetica-bold-r-*-*-10-*-*-*-*-*-*-*"); + if(ctk_gtksim_draw_font_bold.font != NULL) { + printf("ctk-gtksim-service: Font loaded OK\n"); + } else { + printf("ctk-gtksim-service: Font loading failed\n"); + exit(1); + } + + ctk_gtksim_draw_font_menu.font = + gdk_font_load("-*-helvetica-bold-r-*-*-12-*-*-*-*-*-*-*"); + if(ctk_gtksim_draw_font_menu.font != NULL) { + printf("ctk-gtksim-service: Font loaded OK\n"); + } else { + printf("ctk-gtksim-service: Font loading failed\n"); + exit(1); + } + + ctk_gtksim_draw_font_monospace.font = + gdk_font_load("-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*"); + if(ctk_gtksim_draw_font_monospace.font != NULL) { + printf("ctk-gtksim-service: Font loaded OK\n"); + } else { + printf("ctk-gtksim-service: Font loading failed\n"); + exit(1); + } + */ + ctk_gtksim_draw_color_blue.color = get_color(0, 0, 0xffff); + ctk_gtksim_draw_color_white.color = get_color(0xffff, 0xffff, 0xffff); + ctk_gtksim_draw_color_lightgray.color = get_color(0xefff, 0xefff, 0xefff); + ctk_gtksim_draw_color_midgray.color = get_color(0xdfff, 0xdfff, 0xdfff); + ctk_gtksim_draw_color_darkgray.color = get_color(0xcfff, 0xcfff, 0xcfff); + ctk_gtksim_draw_color_ddarkgray.color = get_color(0xafff, 0xafff, 0xafff); + ctk_gtksim_draw_color_black.color = get_color(0, 0, 0); + + layout = pango_layout_new(gtk_widget_get_pango_context(ctk_gtksim_drawing_area)); + + ctk_gtksim_draw_font_normal.font = + pango_font_description_from_string("Arial 8"); + ctk_gtksim_draw_font_bold.font = + pango_font_description_from_string("Arial bold 8"); + ctk_gtksim_draw_font_menu.font = + pango_font_description_from_string("Arial bold 9"); + ctk_gtksim_draw_font_monospace.font = + pango_font_description_from_string("Monospace 8"); + ctk_gtksim_draw_font_monospace_bold.font = + pango_font_description_from_string("Monospace bold 8"); + + +} +/*--------------------------------------------------------------------------*/ diff --git a/platform/gtk/ctk/ctk-gtksim-draw.h b/platform/gtk/ctk/ctk-gtksim-draw.h new file mode 100644 index 000000000..ffb783cbb --- /dev/null +++ b/platform/gtk/ctk/ctk-gtksim-draw.h @@ -0,0 +1,37 @@ +#ifndef __CTK_GTKSIM_DRAW_H__ +#define __CTK_GTKSIM_DRAW_H__ + +struct ctk_gtksim_draw_font; + +extern struct ctk_gtksim_draw_font ctk_gtksim_draw_font_normal, + ctk_gtksim_draw_font_bold, + ctk_gtksim_draw_font_menu, + ctk_gtksim_draw_font_monospace, + ctk_gtksim_draw_font_monospace_bold; + +struct ctk_gtksim_draw_color; + +extern struct ctk_gtksim_draw_color ctk_gtksim_draw_color_white, + ctk_gtksim_draw_color_lightgray, + ctk_gtksim_draw_color_midgray, + ctk_gtksim_draw_color_darkgray, + ctk_gtksim_draw_color_ddarkgray, + ctk_gtksim_draw_color_black, + ctk_gtksim_draw_color_blue; + +void ctk_gtksim_draw_init(void); + +int ctk_gtksim_draw_string_width(struct ctk_gtksim_draw_font *font, + char *str, int monospace); + +void ctk_gtksim_draw_string(struct ctk_gtksim_draw_font *font, + struct ctk_gtksim_draw_color *color, + int x, int y, char *str, + int monospace); + +void ctk_gtksim_draw_line(struct ctk_gtksim_draw_color *color, + int x1, int y1, + int x2, int y2); + + +#endif /* __CTK_GTKSIM_DRAW_H__ */ diff --git a/platform/gtk/ctk/ctk-gtksim-service.c b/platform/gtk/ctk/ctk-gtksim-service.c new file mode 100644 index 000000000..5c070053c --- /dev/null +++ b/platform/gtk/ctk/ctk-gtksim-service.c @@ -0,0 +1,869 @@ + +#include "ctk/ctk-draw-service.h" + +#include "ctk-gtksim-draw.h" +#include "ctk-gtksim.h" + +#include + + +#define WINDOWBORDER_WIDTH 1 +#define WINDOWBORDER_HEIGHT 1 +#define WINDOWTITLE_HEIGHT 3 +#define MENU_HEIGHT 1 +#define MENUBAR_HEIGHT 12 + +#define FONT_BASELINE 12 + +#define MENUBAR_FONT_BASELINE 7 + +#define RASTER_X 8 +#define RASTER_Y 14 + +#define BUTTON_HEIGHT 12 +#define BUTTON_X_BORDER 4 +#define BUTTON_Y_BORDER 1 + +#define TEXTENTRY_HEIGHT 12 +#define TEXTENTRY_X_BORDER 4 +#define TEXTENTRY_Y_BORDER 1 + +static GdkGC *white, *lightgray, *midgray, *darkgray, *ddarkgray, *black, + *blue; + +static GdkPixbuf *background, *windowborder, *menubar; + +static void +draw_widget(struct ctk_widget *w, + unsigned char winx, + unsigned char winy, + unsigned char clipx, + unsigned char clipy, + unsigned char clipy1, + unsigned char clipy2, + unsigned char focus); + +/*--------------------------------------------------------------------------*/ +static GdkGC * +get_color(unsigned short r, unsigned short g, unsigned short b) +{ + GdkGCValues values; + GdkColor color; + + color.pixel = 0; + color.red = r; + color.green = g; + color.blue = b; + + if(gdk_colormap_alloc_color(gdk_colormap_get_system(), + &color, FALSE, TRUE)) { + } + + values.foreground = color; + + return gdk_gc_new_with_values(ctk_gtksim_drawing_area->window, + &values, + GDK_GC_FOREGROUND); +} +/*--------------------------------------------------------------------------*/ +static void +s_ctk_draw_init(void) +{ + GtkWidget *image; + + image = gtk_image_new_from_file(CTK_GTKSIM_SERVICE_PNGDIR "/background.png"); + background = gtk_image_get_pixbuf(GTK_IMAGE(image)); + + image = gtk_image_new_from_file(CTK_GTKSIM_SERVICE_PNGDIR "/windowborder.png"); + windowborder = gtk_image_get_pixbuf(GTK_IMAGE(image)); + + image = gtk_image_new_from_file(CTK_GTKSIM_SERVICE_PNGDIR "/menubar.png"); + menubar = gtk_image_get_pixbuf(GTK_IMAGE(image)); + + ctk_gtksim_init(); + ctk_gtksim_draw_init(); + + + blue = get_color(0, 0, 0xffff); + white = get_color(0xffff, 0xffff, 0xffff); + lightgray = get_color(0xefff, 0xefff, 0xefff); + midgray = get_color(0xdfff, 0xdfff, 0xdfff); + darkgray = get_color(0xcfff, 0xcfff, 0xcfff); + ddarkgray = get_color(0xafff, 0xafff, 0xafff); + black = get_color(0, 0, 0); + + +} +/*--------------------------------------------------------------------------*/ +static void +s_ctk_draw_clear(unsigned char y1, unsigned char y2) +{ + if(background == NULL) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + darkgray, + TRUE, + 0, + y1 * RASTER_Y + MENUBAR_HEIGHT, + CTK_GTKSIM_SCREEN_WIDTH, + (y2 - y1) * RASTER_Y); + } else { + gdk_draw_pixbuf(ctk_gtksim_pixmap, + darkgray, + background, + 0, + y1 * RASTER_Y, + 0, + y1 * RASTER_Y + MENUBAR_HEIGHT, + CTK_GTKSIM_SCREEN_WIDTH, + (y2 - y1) * RASTER_Y, + GDK_RGB_DITHER_NONE, 0, 0); + } +} +/*--------------------------------------------------------------------------*/ +static void +s_ctk_draw_clear_window(struct ctk_window *window, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + int x, y; + + x = window->x; + y = window->y + MENU_HEIGHT; + + /* Clear window */ + if(focus & CTK_FOCUS_WINDOW) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + white, + TRUE, + x * RASTER_X - 1, + y * RASTER_Y - 1 + MENUBAR_HEIGHT, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X + 2, + (window->h + WINDOWTITLE_HEIGHT + + WINDOWBORDER_HEIGHT) * RASTER_Y + 2); + } else { + gdk_draw_rectangle(ctk_gtksim_pixmap, + lightgray, + TRUE, + x * RASTER_X - 1, + y * RASTER_Y - 1 + MENUBAR_HEIGHT, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X + 2, + (window->h + WINDOWTITLE_HEIGHT + + WINDOWBORDER_HEIGHT) * RASTER_Y + 2); + } +} +/*--------------------------------------------------------------------------*/ +static void +s_ctk_draw_window(struct ctk_window *window, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + struct ctk_widget *w; + unsigned char wfocus; + int x, y, x1, y1, x2, y2; + + x = window->x; + y = window->y + MENU_HEIGHT; + + x1 = x + WINDOWBORDER_WIDTH; + y1 = y + WINDOWTITLE_HEIGHT; + x2 = x1 + window->w; + y2 = y1 + window->h; + + /* Draw window border */ + gdk_draw_rectangle(ctk_gtksim_pixmap, + darkgray, + FALSE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X, + (window->h + WINDOWTITLE_HEIGHT + + WINDOWBORDER_HEIGHT) * RASTER_Y); + + if(ctk_mode_get() == CTK_MODE_WINDOWMOVE) { + if(focus & CTK_FOCUS_WINDOW) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + white, + TRUE, + x * RASTER_X + 1, + y * RASTER_Y + MENUBAR_HEIGHT + 1, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X - 2, + (window->h + WINDOWTITLE_HEIGHT + + WINDOWBORDER_HEIGHT) * RASTER_Y - 2); + } else { + gdk_draw_rectangle(ctk_gtksim_pixmap, + midgray, + TRUE, + x * RASTER_X + 1, + y * RASTER_Y + MENUBAR_HEIGHT + 1, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X - 2, + (window->h + WINDOWTITLE_HEIGHT + + WINDOWBORDER_HEIGHT) * RASTER_Y - 2); + } + return; + } + + if(windowborder == NULL) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + midgray, + TRUE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X, + WINDOWTITLE_HEIGHT * RASTER_Y); + } else { + gdk_draw_pixbuf(ctk_gtksim_pixmap, + midgray, + windowborder, + 0, 0, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X, + WINDOWTITLE_HEIGHT * RASTER_Y, + GDK_RGB_DITHER_NONE, 0, 0); + } + + + gdk_draw_line(ctk_gtksim_pixmap, + darkgray, + x * RASTER_X, + (y + WINDOWTITLE_HEIGHT) * RASTER_Y - 1 + MENUBAR_HEIGHT, + (x + window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X, + (y + WINDOWTITLE_HEIGHT) * RASTER_Y - 1 + MENUBAR_HEIGHT); + + + /* Draw inactive widgets. */ + for(w = window->inactive; w != NULL; w = w->next) { + draw_widget(w, x1, y1, x2, y2, + clipy1, clipy2, + focus); + } + + /* Draw active widgets. */ + for(w = window->active; w != NULL; w = w->next) { + wfocus = focus; + if(w == window->focused) { + wfocus |= CTK_FOCUS_WIDGET; + } + + draw_widget(w, x1, y1, x2, y2, + clipy1, clipy2, + wfocus); + } + + ctk_gtksim_set_redrawflag(); +} +/*--------------------------------------------------------------------------*/ +static void +s_ctk_draw_dialog(struct ctk_window *window) +{ + struct ctk_widget *w; + unsigned char wfocus, focus; + int x, y, x1, y1, x2, y2; + + focus = CTK_FOCUS_DIALOG; + + x = window->x; + y = window->y + MENU_HEIGHT; + + x1 = x + WINDOWBORDER_WIDTH; + y1 = y + WINDOWTITLE_HEIGHT; + x2 = x1 + window->w; + y2 = y1 + window->h; + + /* Draw window border */ + gdk_draw_rectangle(ctk_gtksim_pixmap, + black, + FALSE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X, + (window->h + WINDOWTITLE_HEIGHT + + WINDOWBORDER_HEIGHT) * RASTER_Y); + + + + gdk_draw_rectangle(ctk_gtksim_pixmap, + white, + TRUE, + x * RASTER_X + 1, + y * RASTER_Y + 1 + MENUBAR_HEIGHT, + (window->w + 2 * WINDOWBORDER_WIDTH) * RASTER_X - 2, + (window->h + WINDOWTITLE_HEIGHT + + WINDOWBORDER_HEIGHT) * RASTER_Y - 2); + + /* Draw inactive widgets. */ + for(w = window->inactive; w != NULL; w = w->next) { + draw_widget(w, x1, y1, x2, y2, + y1, y2, + focus); + } + + /* Draw active widgets. */ + for(w = window->active; w != NULL; w = w->next) { + wfocus = focus; + if(w == window->focused) { + wfocus |= CTK_FOCUS_WIDGET; + } + + draw_widget(w, x1, y1, x2, y2, + y1, y2, + wfocus); + } + + ctk_gtksim_set_redrawflag(); + +} +/*--------------------------------------------------------------------------*/ +static void +draw_widget(struct ctk_widget *w, + unsigned char winx, unsigned char winy, + unsigned char clipx, + unsigned char clipy, + unsigned char clipy1, + unsigned char clipy2, + unsigned char focus) +{ + unsigned char text[1000]; + unsigned char x, y; + int width, xpos; + int i, j; + GdkGC *bgcol, *buttoncol, *color, *inv_color; + struct ctk_gtksim_draw_font *buttonfont, *textfont, *textfont_bold; + int monospace; + unsigned char *bitmap; + + x = winx + w->x; + y = winy + w->y; + + if(focus & CTK_FOCUS_WINDOW) { + bgcol = white; + } else { + bgcol = lightgray; + } + + if(focus & CTK_FOCUS_WINDOW) { + buttoncol = lightgray; + } else { + buttoncol = midgray; + } + + monospace = w->flags & CTK_WIDGET_FLAG_MONOSPACE; + if(monospace) { + textfont = &ctk_gtksim_draw_font_monospace; + textfont_bold = &ctk_gtksim_draw_font_monospace_bold; + } else { + textfont = &ctk_gtksim_draw_font_normal; + textfont_bold = &ctk_gtksim_draw_font_bold; + } + + switch(w->type) { + case CTK_WIDGET_SEPARATOR: + gdk_draw_line(ctk_gtksim_pixmap, + darkgray, + x * RASTER_X, + y * RASTER_Y + RASTER_Y / 2 + MENUBAR_HEIGHT, + (x + w->w) * RASTER_X, + y * RASTER_Y + RASTER_Y / 2 + MENUBAR_HEIGHT); + break; + case CTK_WIDGET_LABEL: + gdk_draw_rectangle(ctk_gtksim_pixmap, + bgcol, + TRUE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + w->w * RASTER_X, + w->h * RASTER_Y); + for(i = 0; i < w->h; ++i) { + strncpy(text, &w->widget.label.text[i * w->w], w->w); + for(j = 0; j < w->w; ++j) { + if(text[j] >= 0x80) { + text[j] = text[j] & 0x7f; + } + if(text[j] == 0) { + text[j] = ' '; + } + } + text[w->w] = 0; + ctk_gtksim_draw_string(textfont, + &ctk_gtksim_draw_color_black, + RASTER_X * x, + RASTER_Y * (y + i) + MENUBAR_HEIGHT, + text, monospace); + + strncpy(text, &w->widget.label.text[i * w->w], w->w); + for(j = 0; j < w->w; ++j) { + if(text[j] >= 0x80) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + black, + FALSE, + (x + j) * RASTER_X - 2, + y * RASTER_Y + MENUBAR_HEIGHT, + RASTER_X + 2, + BUTTON_HEIGHT + 1); + } + } + } + + break; + case CTK_WIDGET_BUTTON: + if(w == (struct ctk_widget *)&w->window->titlebutton) { + buttonfont = &ctk_gtksim_draw_font_bold; + } else { + buttonfont = textfont; + } + + ++x; + + width = ctk_gtksim_draw_string_width(buttonfont, + w->widget.button.text, + monospace); + if(focus == (CTK_FOCUS_WIDGET|CTK_FOCUS_WINDOW) || + focus == (CTK_FOCUS_WIDGET|CTK_FOCUS_DIALOG)) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + black, + FALSE, + x * RASTER_X - BUTTON_X_BORDER, + y * RASTER_Y - BUTTON_Y_BORDER + MENUBAR_HEIGHT, + w->w * RASTER_X + BUTTON_X_BORDER * 2, + BUTTON_HEIGHT + BUTTON_Y_BORDER); + /* gdk_draw_rectangle(ctk_gtksim_pixmap, + ctk_gtksim_drawing_area->style->black_gc, + FALSE, + x * RASTER_X - BUTTON_X_BORDER - 1, + y * RASTER_Y - BUTTON_Y_BORDER - 1, + w->w * RASTER_X + BUTTON_X_BORDER * 2 + 1, + RASTER_Y + BUTTON_Y_BORDER * 2 + 1);*/ + } else { + gdk_draw_rectangle(ctk_gtksim_pixmap, + darkgray, + FALSE, + x * RASTER_X - BUTTON_X_BORDER, + y * RASTER_Y - BUTTON_Y_BORDER + MENUBAR_HEIGHT, + w->w * RASTER_X + BUTTON_X_BORDER * 2, + BUTTON_HEIGHT + BUTTON_Y_BORDER); + } + gdk_draw_rectangle(ctk_gtksim_pixmap, + buttoncol, + TRUE, + x * RASTER_X - BUTTON_X_BORDER + 1, + y * RASTER_Y + MENUBAR_HEIGHT, + w->w * RASTER_X + BUTTON_X_BORDER * 2 - 2, + BUTTON_HEIGHT); + + gdk_draw_line(ctk_gtksim_pixmap, + ddarkgray, + x * RASTER_X - BUTTON_X_BORDER + 1, + y * RASTER_Y + BUTTON_HEIGHT - 1 + MENUBAR_HEIGHT, + x * RASTER_X + w->w * RASTER_X + BUTTON_X_BORDER - 1, + y * RASTER_Y + BUTTON_HEIGHT - 1 + MENUBAR_HEIGHT); + gdk_draw_line(ctk_gtksim_pixmap, + ddarkgray, + x * RASTER_X + w->w * RASTER_X + BUTTON_X_BORDER - 1, + y * RASTER_Y + BUTTON_HEIGHT - 1 + MENUBAR_HEIGHT, + x * RASTER_X + w->w * RASTER_X + BUTTON_X_BORDER - 1, + y * RASTER_Y + MENUBAR_HEIGHT); + + if(w != &w->window->closebutton) { + ctk_gtksim_draw_string(buttonfont, + &ctk_gtksim_draw_color_black, + RASTER_X * x + + (w->w * RASTER_X) / 2 - width / 2, + RASTER_Y * y + MENUBAR_HEIGHT, + w->widget.button.text, + monospace); + } + break; + case CTK_WIDGET_HYPERLINK: + strncpy(text, w->widget.hyperlink.text, w->w); + text[w->w] = 0; + width = ctk_gtksim_draw_string_width(textfont, text, monospace); + gdk_draw_rectangle(ctk_gtksim_pixmap, + bgcol, + TRUE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + width, + RASTER_Y); + if(focus & CTK_FOCUS_WIDGET) { + ctk_gtksim_draw_string(textfont_bold, + &ctk_gtksim_draw_color_blue, + RASTER_X * x, + RASTER_Y * y + MENUBAR_HEIGHT, + text, monospace); + } else { + ctk_gtksim_draw_string(textfont, + &ctk_gtksim_draw_color_blue, + RASTER_X * x, + RASTER_Y * y + MENUBAR_HEIGHT, + text, monospace); + } + gdk_draw_line(ctk_gtksim_pixmap, + blue, + x * RASTER_X, + y * RASTER_Y + FONT_BASELINE + 1 + MENUBAR_HEIGHT, + x * RASTER_X + width, + y * RASTER_Y + FONT_BASELINE + 1 + MENUBAR_HEIGHT); + + break; + case CTK_WIDGET_TEXTENTRY: + strncpy(text, w->widget.textentry.text, sizeof(text)); + text[w->widget.textentry.xpos] = 0; + width = ctk_gtksim_draw_string_width(textfont, text, monospace); + gdk_draw_rectangle(ctk_gtksim_pixmap, + darkgray, + FALSE, + x * RASTER_X - TEXTENTRY_X_BORDER + RASTER_X, + y * RASTER_Y - TEXTENTRY_Y_BORDER + MENUBAR_HEIGHT, + w->w * RASTER_X + TEXTENTRY_X_BORDER * 2 - 1, + TEXTENTRY_HEIGHT + TEXTENTRY_Y_BORDER); + gdk_draw_rectangle(ctk_gtksim_pixmap, + bgcol, + TRUE, + x * RASTER_X + RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + w->w * RASTER_X, + TEXTENTRY_HEIGHT); + ctk_gtksim_draw_string(textfont, + &ctk_gtksim_draw_color_black, + RASTER_X * x + RASTER_X, + RASTER_Y * y + MENUBAR_HEIGHT, + w->widget.textentry.text, + monospace); + if(focus == (CTK_FOCUS_WIDGET|CTK_FOCUS_WINDOW) || + focus == (CTK_FOCUS_WIDGET|CTK_FOCUS_DIALOG)) { + gdk_draw_line(ctk_gtksim_pixmap, + black, + x * RASTER_X + width + RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + x * RASTER_X + width + RASTER_X, + y * RASTER_Y + TEXTENTRY_HEIGHT - 1 + MENUBAR_HEIGHT); + } + break; + case CTK_WIDGET_ICON: + width = ctk_gtksim_draw_string_width(&ctk_gtksim_draw_font_normal, + w->widget.icon.title, monospace); + + if(x * RASTER_X + width >= CTK_GTKSIM_SCREEN_WIDTH - RASTER_X) { + xpos = CTK_GTKSIM_SCREEN_WIDTH - width - RASTER_X; + } else { + xpos = x * RASTER_X; + } + + if((focus & CTK_FOCUS_WIDGET) == 0) { + color = black; + inv_color = bgcol; + } else { + color = bgcol; + inv_color = black; + } + + bitmap = w->widget.icon.bitmap; + if (bitmap != NULL) { + int k, c; + + for (c = 0; c < 9; ++c) { + for (i = 0; i < 8; ++i) { + unsigned char b = bitmap[i + c * 8]; + for (k = 0; k < 8; k++) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + ((b >> k) & 1) > 0 ? color : inv_color, + TRUE, + x * RASTER_X + 8 * (c % 3) + (8 - k), + y * RASTER_Y + MENUBAR_HEIGHT + + 8 * (c / 3) + i, + 1, 1); + } + } + } + } else { + gdk_draw_rectangle(ctk_gtksim_pixmap, + color, + TRUE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + 24, 24); + } + + /* if((focus & CTK_FOCUS_WIDGET) == 0) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + bgcol, + TRUE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + 24, 24); + } else { + gdk_draw_rectangle(ctk_gtksim_pixmap, + black, + TRUE, + x * RASTER_X, + y * RASTER_Y + MENUBAR_HEIGHT, + 24, 24); + }*/ + + /* gdk_draw_rectangle(ctk_gtksim_pixmap, + white, + TRUE, + xpos, + RASTER_Y * y + 24 + 1 + MENUBAR_HEIGHT, + width, + RASTER_Y);*/ + + ctk_gtksim_draw_string(textfont, + &ctk_gtksim_draw_color_black, + xpos + 1, + RASTER_Y * y + 24 + 1 + MENUBAR_HEIGHT, + w->widget.icon.title, + monospace); + ctk_gtksim_draw_string(textfont, + &ctk_gtksim_draw_color_white, + xpos, + RASTER_Y * y + 24 + MENUBAR_HEIGHT, + w->widget.icon.title, + monospace); + + + break; + case CTK_WIDGET_BITMAP: + bitmap = w->widget.bitmap.bitmap; + if(bitmap != NULL) { + int bx, by; + int k; + int xtmp; + + color = black; + inv_color = bgcol; + + for(by = 0; by < w->h; ++by) { + for(bx = 0; bx < w->w; ++bx) { + for (i = 0; i < 8; ++i) { + unsigned char b = bitmap[i + (by * w->w + bx) * 8]; + for (k = 0; k < 8; k++) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + ((b >> k) & 1) > 0 ? color : inv_color, + TRUE, + x * RASTER_X + 8 * bx + (8 - k), + y * RASTER_Y + MENUBAR_HEIGHT + + 8 * by + i, + 1, 1); + } + } + } + } + } + break; + default: + break; + } +} + +/*--------------------------------------------------------------------------*/ +static void +s_ctk_draw_widget(struct ctk_widget *w, + unsigned char focus, + unsigned char clipy1, + unsigned char clipy2) +{ + struct ctk_window *win = w->window; + unsigned char posx, posy; + + posx = win->x + WINDOWBORDER_WIDTH; + posy = win->y + WINDOWTITLE_HEIGHT + MENU_HEIGHT; + + if(w == win->focused) { + focus |= CTK_FOCUS_WIDGET; + } + + draw_widget(w, posx, posy, + posx + win->w, + posy + win->h, + clipy1, clipy2, + focus); + + ctk_gtksim_set_redrawflag(); +} +/*--------------------------------------------------------------------------*/ +static void +draw_menu(struct ctk_menu *m, int x, int open) +{ + int i; + int xpos; + + if(x >= CTK_GTKSIM_SCREEN_WIDTH / RASTER_X - 16) { + xpos = CTK_GTKSIM_SCREEN_WIDTH / RASTER_X - 16; + } else { + xpos = x; + } + + if(open) { + + gdk_draw_rectangle(ctk_gtksim_pixmap, + black, + TRUE, + RASTER_X * x, 0, + m->titlelen * RASTER_X, + RASTER_Y + MENUBAR_HEIGHT); + + ctk_gtksim_draw_string(&ctk_gtksim_draw_font_menu, + &ctk_gtksim_draw_color_white, + RASTER_X * x + 2, + MENUBAR_FONT_BASELINE, + m->title, 0); + + gdk_draw_rectangle(ctk_gtksim_pixmap, + white, + TRUE, + xpos * RASTER_X, + RASTER_Y * MENU_HEIGHT + MENUBAR_HEIGHT, + (xpos + 16) * RASTER_X, + (m->nitems) * RASTER_Y); + + for(i = 0; i < m->nitems; ++i) { + if(i == m->active) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + black, + TRUE, + RASTER_X * xpos, + (MENU_HEIGHT + i) * RASTER_Y + MENUBAR_HEIGHT, + (xpos + 16) * RASTER_X, + RASTER_Y); + ctk_gtksim_draw_string(&ctk_gtksim_draw_font_normal, + &ctk_gtksim_draw_color_white, + RASTER_X * xpos + 2, + (MENU_HEIGHT + i) * RASTER_Y + + MENUBAR_HEIGHT, + m->items[i].title, 0); + + } else { + ctk_gtksim_draw_string(&ctk_gtksim_draw_font_normal, + &ctk_gtksim_draw_color_black, + RASTER_X * xpos + 2, + (MENU_HEIGHT + i) * RASTER_Y + MENUBAR_HEIGHT, + m->items[i].title, 0); + } + + } + } else { + /* gdk_draw_rectangle(ctk_gtksim_pixmap, + white, + TRUE, + RASTER_X * x, 0, + m->titlelen * RASTER_X, RASTER_Y);*/ + + ctk_gtksim_draw_string(&ctk_gtksim_draw_font_menu, + &ctk_gtksim_draw_color_black, + RASTER_X * x, MENUBAR_FONT_BASELINE, + m->title, 0); + + } +} +/*--------------------------------------------------------------------------*/ +static void +s_ctk_draw_menus(struct ctk_menus *menus) +{ + struct ctk_menu *m; + int x; + + if(menubar != NULL) { + gdk_draw_pixbuf(ctk_gtksim_pixmap, + darkgray, + menubar, + 0, 0, + 0, 0, + CTK_GTKSIM_SCREEN_WIDTH, + RASTER_Y + MENUBAR_HEIGHT, + GDK_RGB_DITHER_NONE, 0, 0); + } + + x = 1; + for(m = menus->menus->next; m != NULL; m = m->next) { + draw_menu(m, x, m == menus->open); + x += strlen(m->title); + } + + x = CTK_GTKSIM_SCREEN_WIDTH / RASTER_X - strlen(menus->menus->title); + draw_menu(menus->menus, x, menus->menus == menus->open); + + + + /* gdk_draw_line(ctk_gtksim_pixmap, + ctk_gtksim_drawing_area->style->black_gc, + 0, RASTER_Y, + CTK_GTKSIM_SCREEN_WIDTH, + RASTER_Y);*/ + + ctk_gtksim_set_redrawflag(); +} +/*--------------------------------------------------------------------------*/ +static unsigned char +s_ctk_draw_width(void) +{ + return CTK_GTKSIM_SCREEN_WIDTH / RASTER_X; +} +/*--------------------------------------------------------------------------*/ +static unsigned char +s_ctk_draw_height(void) +{ + return CTK_GTKSIM_SCREEN_HEIGHT / RASTER_Y; +} +/*--------------------------------------------------------------------------*/ +static unsigned short +s_ctk_mouse_xtoc(unsigned short x) +{ + return x / RASTER_X; +} +/*--------------------------------------------------------------------------*/ +static unsigned short +s_ctk_mouse_ytoc(unsigned short y) +{ + if(y < MENUBAR_HEIGHT) { + return 0; + } else { + return (y - MENUBAR_HEIGHT) / RASTER_Y; + } +} +/*--------------------------------------------------------------------------*/ +SERVICE(ctk_gtksim_service, ctk_draw_service, +{ + WINDOWBORDER_WIDTH, + WINDOWBORDER_HEIGHT, + WINDOWTITLE_HEIGHT, + s_ctk_draw_init, + s_ctk_draw_clear, + s_ctk_draw_clear_window, + s_ctk_draw_window, + s_ctk_draw_dialog, + s_ctk_draw_widget, + s_ctk_draw_menus, + s_ctk_draw_width, + s_ctk_draw_height, + s_ctk_mouse_xtoc, + s_ctk_mouse_ytoc, +}); + +PROCESS(ctk_gtksim_service_process, "CTK GTK driver"); + +PROCESS_THREAD(ctk_gtksim_service_process, ev, data) { + + PROCESS_BEGIN(); + + SERVICE_REGISTER(ctk_gtksim_service); + + ctk_draw_init(); + + ctk_desktop_redraw(NULL); + + while(ev != PROCESS_EVENT_SERVICE_REMOVED && + ev != PROCESS_EVENT_EXIT) { + process_poll(&ctk_gtksim_service_process); + PROCESS_WAIT_EVENT(); + ctk_gtksim_redraw(); + + } + + SERVICE_REMOVE(ctk_gtksim_service); + + PROCESS_END(); +} +/*--------------------------------------------------------------------------*/ diff --git a/platform/gtk/ctk/ctk-gtksim-service.h b/platform/gtk/ctk/ctk-gtksim-service.h new file mode 100644 index 000000000..eaa059639 --- /dev/null +++ b/platform/gtk/ctk/ctk-gtksim-service.h @@ -0,0 +1,8 @@ +#ifndef __CTK_GTKSIM_SERVICE_H__ +#define __CTK_GTKSIM_SERVICE_H__ + +#include "contiki.h" + +PROCESS_NAME(ctk_gtksim_service_process); + +#endif /* __CTK_GTKSIM_SERVICE_H__ */ diff --git a/platform/gtk/ctk/ctk-gtksim.c b/platform/gtk/ctk/ctk-gtksim.c new file mode 100644 index 000000000..899d30753 --- /dev/null +++ b/platform/gtk/ctk/ctk-gtksim.c @@ -0,0 +1,371 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-gtksim.c,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + * + */ + +/* This file provides a very simple implementation of CTK using the + GTK (Gimp toolkit) under FreeBSD/Linux. */ + + +#include "lib/libconio.h" + +#include "ctk/ctk.h" +#include "ctk/ctk-draw.h" +#include "ctk/ctk-mouse.h" + +#include +#include +#include + +#define FONT_HEIGHT 14 +#define FONT_WIDTH 8 +#define FONT_HEIGHT_BASELINE 11 + +GdkPixmap *ctk_gtksim_pixmap = NULL; +GtkWidget *ctk_gtksim_drawing_area; +static GdkFont *font; + +static int mouse_x, mouse_y, mouse_button; + +static int redrawflag; + +void +ctk_gtksim_redraw(void) +{ + if(redrawflag) { + gdk_draw_pixmap(ctk_gtksim_drawing_area->window, + ctk_gtksim_drawing_area->style->fg_gc[GTK_WIDGET_STATE (ctk_gtksim_drawing_area)], + ctk_gtksim_pixmap, + 0,0,0,0, + CTK_GTKSIM_SCREEN_WIDTH, CTK_GTKSIM_SCREEN_HEIGHT); + redrawflag = 0; + } + +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_gtksim_set_redrawflag(void) +{ + redrawflag = 1; +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_arch_draw_char(char c, + unsigned char x, unsigned char y, + unsigned char reversed, + unsigned char color) +{ + char str[2]; + + str[0] = c; + str[1] = 0; + + if(reversed) { + gdk_draw_rectangle(ctk_gtksim_pixmap, + ctk_gtksim_drawing_area->style->black_gc, + TRUE, + x * FONT_WIDTH, + y * FONT_HEIGHT, + FONT_WIDTH, FONT_HEIGHT); + + gdk_draw_string(ctk_gtksim_pixmap, + font, + ctk_gtksim_drawing_area->style->white_gc, + x * FONT_WIDTH, FONT_HEIGHT_BASELINE + y * FONT_HEIGHT, + str); + } else { + gdk_draw_rectangle(ctk_gtksim_pixmap, + ctk_gtksim_drawing_area->style->white_gc, + TRUE, + x * FONT_WIDTH, + y * FONT_HEIGHT, + FONT_WIDTH, FONT_HEIGHT); + + gdk_draw_string(ctk_gtksim_pixmap, + font, + ctk_gtksim_drawing_area->style->black_gc, + x * FONT_WIDTH, FONT_HEIGHT_BASELINE + y * FONT_HEIGHT, + str); + } + + gdk_draw_pixmap(ctk_gtksim_drawing_area->window, + ctk_gtksim_drawing_area->style->fg_gc[GTK_WIDGET_STATE (ctk_gtksim_drawing_area)], + ctk_gtksim_pixmap, + x * FONT_WIDTH, + y * FONT_HEIGHT, + x * FONT_WIDTH, + y * FONT_HEIGHT, + FONT_WIDTH, FONT_HEIGHT); + +} +/*-----------------------------------------------------------------------------------*/ +#define NUMKEYS 100 +static ctk_arch_key_t keys[NUMKEYS]; +static int firstkey, lastkey; + +unsigned char +ctk_arch_keyavail(void) +{ + return firstkey != lastkey; +} +/*-----------------------------------------------------------------------------------*/ +ctk_arch_key_t +ctk_arch_getkey(void) +{ + ctk_arch_key_t key; + key = keys[firstkey]; + + if(firstkey != lastkey) { + ++firstkey; + if(firstkey >= NUMKEYS) { + firstkey = 0; + } + } + + return key; +} +/*-----------------------------------------------------------------------------------*/ +static gint +configure_event(GtkWidget *widget, GdkEventConfigure *event) +{ + if(ctk_gtksim_pixmap != NULL) { + gdk_pixmap_unref(ctk_gtksim_pixmap); + } + + ctk_gtksim_pixmap = gdk_pixmap_new(widget->window, + widget->allocation.width, + widget->allocation.height, + -1); + + if(ctk_gtksim_pixmap == NULL) { + printf("gdk_pixmap_new == NULL\n"); + exit(1); + } + gdk_draw_rectangle(ctk_gtksim_pixmap, + widget->style->white_gc, + TRUE, + 0, 0, + widget->allocation.width, + widget->allocation.height); + + return TRUE; +} + +/* Redraw the screen from the backing pixmap */ +static gint +expose_event (GtkWidget * widget, GdkEventExpose * event) +{ + /* draw_screen();*/ + gdk_draw_pixmap(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE (widget)], + ctk_gtksim_pixmap, + event->area.x, event->area.y, + event->area.x, event->area.y, + event->area.width, event->area.height); + return FALSE; +} + +static gint +key_press_event (GtkWidget * widget, GdkEventKey * event) +{ + if(event->keyval == GDK_Shift_L || + event->keyval == GDK_Shift_R) { + return TRUE; + } + keys[lastkey] = event->keyval; + ++lastkey; + if(lastkey >= NUMKEYS) { + lastkey = 0; + } + + return TRUE; +} + +static gint +key_release_event (GtkWidget * widget, GdkEventKey * event) +{ + return TRUE; +} + +static gint +motion_notify_event (GtkWidget * widget, GdkEventMotion * event) +{ + int x, y; + GdkModifierType state; + + if (event->is_hint) { + gdk_window_get_pointer (event->window, &x, &y, &state); + } else { + x = event->x; + y = event->y; + } + + mouse_x = x; + mouse_y = y; + return TRUE; +} + +static gint +button_press_event (GtkWidget * widget, GdkEventButton * event) +{ + mouse_button = event->button; + return TRUE; +} + +static gint +button_release_event (GtkWidget * widget, GdkEventButton * event) +{ + mouse_button = 0; + return TRUE; +} + +static void +quit(void) +{ + gtk_exit(0); +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_gtksim_init(void) +{ + GtkWidget *window; +#if 0 + GtkWidget *vbox; +#endif + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(window, "Contiki GTKsim"); + +#if 0 + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER (window), vbox); + gtk_widget_show(vbox); +#endif + gtk_signal_connect(GTK_OBJECT (window), "destroy", + GTK_SIGNAL_FUNC (quit), NULL); + + /* Create the drawing area */ + + ctk_gtksim_drawing_area = gtk_drawing_area_new(); + gtk_drawing_area_size(GTK_DRAWING_AREA (ctk_gtksim_drawing_area), + CTK_GTKSIM_SCREEN_WIDTH, + CTK_GTKSIM_SCREEN_HEIGHT); +#if 0 + gtk_box_pack_start(GTK_BOX(vbox), ctk_gtksim_drawing_area, TRUE, TRUE, 0); +#else + gtk_container_add(GTK_CONTAINER(window), ctk_gtksim_drawing_area); +#endif + + gtk_widget_show(ctk_gtksim_drawing_area); + + /* Load a fixed width font. */ + /* font = gdk_font_load("-*-gamow-medium-r-*-*-*-90-*-*-*-*-*-*");*/ + /* font = gdk_font_load("-*-courier-*-r-normal-*-14-*-*-*-m-*-iso8859-1");*/ + font = gdk_font_load("-*-courier-medium-r-*-*-12-*-*-*-*-*-iso8859-1"); + if(font != NULL) { + printf("Font loaded OK\n"); + } else { + printf("Font loading failed\n"); + exit(1); + } + + + /* Signals used to handle backing pixmap */ + + gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "expose_event", + (GtkSignalFunc) expose_event, NULL); + gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "configure_event", + (GtkSignalFunc) configure_event, NULL); + + /* Event signals */ + + gtk_signal_connect(GTK_OBJECT (window), "key_press_event", + (GtkSignalFunc) key_press_event, NULL); + gtk_signal_connect(GTK_OBJECT (window), "key_release_event", + (GtkSignalFunc) key_release_event, NULL); + + gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "motion_notify_event", + (GtkSignalFunc) motion_notify_event, NULL); + + gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "button_press_event", + (GtkSignalFunc) button_press_event, NULL); + + gtk_signal_connect(GTK_OBJECT (ctk_gtksim_drawing_area), "button_release_event", + (GtkSignalFunc) button_release_event, NULL); + + gtk_widget_set_events(ctk_gtksim_drawing_area, gtk_widget_get_events (ctk_gtksim_drawing_area) + | GDK_KEY_PRESS_MASK + | GDK_KEY_RELEASE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_POINTER_MOTION_HINT_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK); + + gtk_widget_show(window); + +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_init(void) +{ + +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_x(void) +{ + return mouse_x; +} +/*-----------------------------------------------------------------------------------*/ +unsigned short +ctk_mouse_y(void) +{ + return mouse_y; +} +/*-----------------------------------------------------------------------------------*/ +unsigned char +ctk_mouse_button(void) +{ + return mouse_button; +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_hide(void) +{ +} +/*-----------------------------------------------------------------------------------*/ +void +ctk_mouse_show(void) +{ +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/gtk/ctk/ctk-gtksim.h b/platform/gtk/ctk/ctk-gtksim.h new file mode 100644 index 000000000..00033d008 --- /dev/null +++ b/platform/gtk/ctk/ctk-gtksim.h @@ -0,0 +1,73 @@ +/* + * 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 "ctk" console GUI toolkit for cc65 + * + * $Id: ctk-gtksim.h,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + * + */ + +#ifndef __CTK_GTKSIM_H__ +#define __CTK_GTKSIM_H__ + +#include +#include +#include +#include + +#define CTK_ARCH_KEY_T guint + +unsigned char ctk_arch_keyavail(void); +guint ctk_arch_getkey(void); + +#define CH_CURS_RIGHT GDK_Right +#define CH_CURS_DOWN GDK_Down +#define CH_CURS_LEFT GDK_Left +#define CH_CURS_UP GDK_Up +#define CH_ENTER GDK_Return +#define CH_TAB GDK_Tab +#define CH_F1 GDK_F1 +#define CH_F2 GDK_F2 +#define CH_F3 GDK_F3 +#define CH_F4 GDK_F4 +#define CH_F5 GDK_F5 +#define CH_DEL GDK_BackSpace +#define CH_ESC GDK_Escape + +void ctk_gtksim_init(void); + +void ctk_gtksim_redraw(void); + +extern GdkPixmap *ctk_gtksim_pixmap; +extern GtkWidget *ctk_gtksim_drawing_area; + +#define CTK_GTKSIM_SCREEN_WIDTH 1024 +#define CTK_GTKSIM_SCREEN_HEIGHT 768 + +#endif /* __CTK_GTKSIM_H__ */ diff --git a/platform/gtk/menubar.png b/platform/gtk/menubar.png new file mode 100644 index 000000000..dfc02e389 Binary files /dev/null and b/platform/gtk/menubar.png differ diff --git a/platform/gtk/net/tapdev-service.c b/platform/gtk/net/tapdev-service.c new file mode 100644 index 000000000..17a8b9b96 --- /dev/null +++ b/platform/gtk/net/tapdev-service.c @@ -0,0 +1,63 @@ + +#include "net/packet-service.h" +#include "tapdev.h" + +#include "net/uip_arp.h" + +static struct uip_eth_addr addr = + {{0x08, 0x12, 0x23, 0x89, 0xa3, 0x94}}; + +SERVICE(tapdev_service, packet_service, { tapdev_send }); + +PROCESS(tapdev_process, "TAP driver"); + +/*---------------------------------------------------------------------------*/ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) +static void +pollhandler(void) +{ + /* tapdev_service_request_poll();*/ + process_poll(&tapdev_process); + uip_len = tapdev_poll(); + + if(uip_len > 0) { + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + /* uip_input();*/ + tcpip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + tapdev_do_send(); + } + } + } +} +/*---------------------------------------------------------------------------*/ + +PROCESS_THREAD(tapdev_process, ev, data) +{ + PROCESS_BEGIN(); + + tapdev_init(); + + SERVICE_REGISTER(tapdev_service); + + process_poll(&tapdev_process); + + while(1) { + PROCESS_YIELD(); + if(ev == PROCESS_EVENT_POLL) { + pollhandler(); + } + } + + PROCESS_END(); +} diff --git a/platform/gtk/net/tapdev-service.h b/platform/gtk/net/tapdev-service.h new file mode 100644 index 000000000..b3562e346 --- /dev/null +++ b/platform/gtk/net/tapdev-service.h @@ -0,0 +1,8 @@ +#ifndef __TAPDEV_SERVICE_H__ +#define __TAPDEV_SERVICE_H__ + +#include "contiki.h" + +PROCESS_NAME(tapdev_process); + +#endif /* __TAPDEV_SERVICE_H__ */ diff --git a/platform/gtk/net/tapdev.c b/platform/gtk/net/tapdev.c new file mode 100644 index 000000000..ab6474744 --- /dev/null +++ b/platform/gtk/net/tapdev.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Adam Dunkels + * + * $Id: tapdev.c,v 1.1 2006/06/17 22:41:29 adamdunkels Exp $ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef linux +#include +#include +#include +#define DEVTAP "/dev/net/tun" +#else /* linux */ +#define DEVTAP "/dev/tap0" +#endif /* linux */ + +#include "contiki-net.h" + +#define DROP 0 + +static int drop = 0; +static int fd; + +static unsigned long lasttime; +static struct timezone tz; + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +static void do_send(void); +u8_t tapdev_send(void); + + +u16_t +tapdev_poll(void) +{ + fd_set fdset; + struct timeval tv; + int ret; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&fdset); + if(fd > 0) { + FD_SET(fd, &fdset); + } + + ret = select(fd + 1, &fdset, NULL, NULL, &tv); + if(ret == 0) { + return 0; + } + ret = read(fd, uip_buf, UIP_BUFSIZE); + if(ret == -1) { + perror("tapdev_poll: read"); + } + return ret; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_init(void) +{ + char buf[1024]; + + fd = open(DEVTAP, O_RDWR); + if(fd == -1) { + perror("tapdev: tapdev_init: open"); + return; + } + +#ifdef linux + { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { + perror(buf); + exit(1); + } + } +#endif /* Linux */ + + snprintf(buf, sizeof(buf), "ifconfig tap0 inet 192.168.2.1"); + system(buf); + printf("%s\n", buf); + + lasttime = 0; + + /* gdk_input_add(fd, GDK_INPUT_READ, + read_callback, NULL);*/ + +} +/*---------------------------------------------------------------------------*/ +static void +do_send(void) +{ + int ret; + + if(fd <= 0) { + return; + } + + + /* printf("tapdev_send: sending %d bytes\n", size);*/ + /* check_checksum(uip_buf, size);*/ +#if DROP + drop++; + if(drop % 8 == 7) { + printf("Dropped an output packet!\n"); + return; + } +#endif /* DROP */ + + ret = write(fd, uip_buf, uip_len); + + if(ret == -1) { + perror("tap_dev: tapdev_send: writev"); + exit(1); + } +} +/*---------------------------------------------------------------------------*/ +u8_t +tapdev_send(void) +{ + uip_arp_out(); + + do_send(); + return 0; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_do_send(void) +{ + do_send(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/gtk/net/tapdev.h b/platform/gtk/net/tapdev.h new file mode 100644 index 000000000..0c5f57dea --- /dev/null +++ b/platform/gtk/net/tapdev.h @@ -0,0 +1,43 @@ +/* + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. 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: tapdev.h,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + * + */ +#ifndef __TAPDEV_H__ +#define __TAPDEV_H__ + +void tapdev_init(void); + +u8_t tapdev_send(void); +#endif /* __TAPDEV_H__ */ diff --git a/platform/gtk/windowborder.png b/platform/gtk/windowborder.png new file mode 100644 index 000000000..9618b9aba Binary files /dev/null and b/platform/gtk/windowborder.png differ diff --git a/platform/minimal-net/Makefile.minimal-net b/platform/minimal-net/Makefile.minimal-net new file mode 100644 index 000000000..42f5e4388 --- /dev/null +++ b/platform/minimal-net/Makefile.minimal-net @@ -0,0 +1,57 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +#contiki: contiki-$(TARGET).a + +CONTIKI_TARGET_DIRS = . net +CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} + +CONTIKI_TARGET_SOURCEFILES = tapdev-service.c tapdev.c contiki-main.c dlloader.c clock.c leds.c leds-arch.c + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +.SUFFIXES: + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/x86 + +### Compiler definitions +CC = gcc +LD = ld +AS = as +OBJCOPY = objcopy +STRIP = strip +CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) \ + -I$(CONTIKI)/platform/$(TARGET) \ + ${addprefix -I,$(APPDIRS)} $(APP_INCLUDES) \ + -DWITH_UIP -DWITH_ASCII \ + -Wall -g -I. -I/usr/local/include +CFLAGS += $(CFLAGSNO) +LDFLAGS = -Wl,-Map=contiki.map,-export-dynamic + +### Setup directory search path for source files + +CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \ + $(CONTIKI_TARGET_DIRS)} +vpath %.c $(PROJECTDIRS) \ + $(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ + $(CONTIKI_CPU) $(APP_DIRS) + +### Compilation rules + +# $(OBJECTDIR)/%.o: %.c +# $(CC) $(CFLAGS) -c $< -o $@ + +%.so: $(OBJECTDIR)/%.o + $(LD) -shared -o $@ $^ + +# %.ce: %.co +# $(LD) -shared -o $@ $^ + +# %.co: %.c +# $(CC) $(CFLAGS) -DPROCESS_LOADABLE -c $< -o $@ +# $(STRIP) --strip-unneeded -g -x $@ + +# %: %.co $(CONTIKI_TARGET_MAIN) $(PROJECT_OBJECTFILES) contiki-$(TARGET).a +# $(CC) $(CFLAGS) -o $@.$(TARGET) $^ $(LDFLAGS) diff --git a/platform/minimal-net/clock.c b/platform/minimal-net/clock.c new file mode 100644 index 000000000..8bc7aed04 --- /dev/null +++ b/platform/minimal-net/clock.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: clock.c,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ + +/** + * \file + * Clock implementation for Unix. + * \author + * Adam Dunkels + */ + +#include "sys/clock.h" +#include + +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} +/*---------------------------------------------------------------------------*/ +void +clock_delay(unsigned int d) +{ + /* Does not do anything. */ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/minimal-net/contiki-conf.h b/platform/minimal-net/contiki-conf.h new file mode 100644 index 000000000..72c1cded7 --- /dev/null +++ b/platform/minimal-net/contiki-conf.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-conf.h,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ + +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#include + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL +#define CC_CONF_VA_ARGS 1 + +typedef uint8_t u8_t; +typedef uint16_t u16_t; +typedef uint32_t u32_t; +typedef unsigned short uip_stats_t; + +#define UIP_CONF_MAX_CONNECTIONS 40 +#define UIP_CONF_MAX_LISTENPORTS 40 +#define UIP_CONF_BUFFER_SIZE 600 +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_LOGGING 1 +#define UIP_CONF_UDP_CHECKSUMS 1 + +typedef unsigned long clock_time_t; +#define CLOCK_CONF_SECOND 1000 + +#define LOG_CONF_ENABLED 1 + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/minimal-net/contiki-main.c b/platform/minimal-net/contiki-main.c new file mode 100644 index 000000000..44b20ce8a --- /dev/null +++ b/platform/minimal-net/contiki-main.c @@ -0,0 +1,94 @@ +/* + * 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 OS + * + * $Id: contiki-main.c,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + * + */ + +#include "contiki.h" + +#include "net/uip.h" +#include "net/tapdev-service.h" + +PROCINIT(&etimer_process, &tcpip_process, + &tapdev_process); + +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + u16_t addr[2]; + + process_init(); + + procinit_init(); + + autostart_start(autostart_processes); + + uip_ipaddr(addr, 192,168,2,2); + uip_sethostaddr(addr); + + uip_ipaddr(addr, 192,168,2,1); + uip_setdraddr(addr); + + uip_ipaddr(addr, 255,255,255,0); + uip_setnetmask(addr); + + while(1) { + int n; + n = process_run(); + /* if(n > 0) { + printf("%d processes in queue\n"); + }*/ + usleep(1); + etimer_request_poll(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +void log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} + +void +uip_log(char *m) +{ + printf("uIP: '%s'\n", m); +} + +unsigned short +sensors_light1(void) +{ + static unsigned short count; + return count++; +} diff --git a/platform/minimal-net/net/tapdev-service.c b/platform/minimal-net/net/tapdev-service.c new file mode 100644 index 000000000..d148be4b5 --- /dev/null +++ b/platform/minimal-net/net/tapdev-service.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: tapdev-service.c,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ + +#include "contiki-net.h" +#include "tapdev.h" +#include "net/uip-neighbor.h" + +/*static struct uip_eth_addr addr = + {{0x08, 0x12, 0x23, 0x89, 0xa3, 0x94}};*/ + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) +#define IPBUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +SERVICE(tapdev_service, packet_service, { tapdev_send }); + +PROCESS(tapdev_process, "TAP driver"); + +/*---------------------------------------------------------------------------*/ +static void +pollhandler(void) +{ + /* tapdev_service_request_poll();*/ + process_poll(&tapdev_process); + uip_len = tapdev_poll(); + + if(uip_len > 0) { +#if UIP_CONF_IPV6 + if(BUF->type == htons(UIP_ETHTYPE_IPV6)) { + uip_neighbor_add(IPBUF->srcipaddr, &BUF->src); + tcpip_input(); + } else +#endif /* UIP_CONF_IPV6 */ + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + /* uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr);*/ + /* uip_input();*/ + tcpip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + tapdev_do_send(); + } + } + } +} +/*---------------------------------------------------------------------------*/ + +PROCESS_THREAD(tapdev_process, ev, data) +{ + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + + tapdev_init(); + + SERVICE_REGISTER(tapdev_service); + + process_poll(&tapdev_process); + + while(1) { + PROCESS_YIELD(); + if(ev == PROCESS_EVENT_POLL) { + pollhandler(); + } + } + + PROCESS_END(); +} diff --git a/platform/minimal-net/net/tapdev-service.h b/platform/minimal-net/net/tapdev-service.h new file mode 100644 index 000000000..24f9d2427 --- /dev/null +++ b/platform/minimal-net/net/tapdev-service.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: tapdev-service.h,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ +#ifndef __TAPDEV_SERVICE_H__ +#define __TAPDEV_SERVICE_H__ + +#include "contiki.h" + +PROCESS_NAME(tapdev_process); + +#endif /* __TAPDEV_SERVICE_H__ */ diff --git a/platform/minimal-net/net/tapdev.c b/platform/minimal-net/net/tapdev.c new file mode 100644 index 000000000..dd1da894c --- /dev/null +++ b/platform/minimal-net/net/tapdev.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Adam Dunkels + * + * $Id: tapdev.c,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef linux +#include +#include +#include +#define DEVTAP "/dev/net/tun" +#else /* linux */ +#define DEVTAP "/dev/tap0" +#endif /* linux */ + +#include "tapdev.h" + +#include "contiki-net.h" + +#define DROP 0 + +#if DROP +static int drop = 0; +#endif + +static int fd; + +static unsigned long lasttime; + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +static void do_send(void); +u8_t tapdev_send(void); + + +u16_t +tapdev_poll(void) +{ + fd_set fdset; + struct timeval tv; + int ret; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&fdset); + if(fd > 0) { + FD_SET(fd, &fdset); + } + + ret = select(fd + 1, &fdset, NULL, NULL, &tv); + + if(ret == 0) { + return 0; + } + ret = read(fd, uip_buf, UIP_BUFSIZE); + + if(ret == -1) { + perror("tapdev_poll: read"); + } + return ret; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_init(void) +{ + char buf[1024]; + + fd = open(DEVTAP, O_RDWR); + if(fd == -1) { + perror("tapdev: tapdev_init: open"); + return; + } + +#ifdef linux + { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { + perror(buf); + exit(1); + } + } +#endif /* Linux */ + + snprintf(buf, sizeof(buf), "ifconfig tap0 inet 192.168.2.1"); + system(buf); + printf("%s\n", buf); + + lasttime = 0; + + /* gdk_input_add(fd, GDK_INPUT_READ, + read_callback, NULL);*/ + +} +/*---------------------------------------------------------------------------*/ +static void +do_send(void) +{ + int ret; + + if(fd <= 0) { + return; + } + + + /* printf("tapdev_send: sending %d bytes\n", size);*/ + /* check_checksum(uip_buf, size);*/ +#if DROP + drop++; + if(drop % 8 == 7) { + printf("Dropped an output packet!\n"); + return; + } +#endif /* DROP */ + + ret = write(fd, uip_buf, uip_len); + + if(ret == -1) { + perror("tap_dev: tapdev_send: writev"); + exit(1); + } +} +/*---------------------------------------------------------------------------*/ +u8_t +tapdev_send(void) +{ + uip_arp_out(); + + do_send(); + return 0; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_do_send(void) +{ + do_send(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/minimal-net/net/tapdev.h b/platform/minimal-net/net/tapdev.h new file mode 100644 index 000000000..a7f491dc2 --- /dev/null +++ b/platform/minimal-net/net/tapdev.h @@ -0,0 +1,46 @@ +/* + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. 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: tapdev.h,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + * + */ +#ifndef __TAPDEV_H__ +#define __TAPDEV_H__ + +#include "contiki-net.h" + +void tapdev_init(void); +u8_t tapdev_send(void); +u16_t tapdev_poll(void); +void tapdev_do_send(void); +#endif /* __TAPDEV_H__ */ diff --git a/platform/minimal-ppp/Makefile b/platform/minimal-ppp/Makefile new file mode 100644 index 000000000..ce48e0397 --- /dev/null +++ b/platform/minimal-ppp/Makefile @@ -0,0 +1,118 @@ +# Copyright (c) 2002-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: Makefile,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ +# + +all: contiki + +CONTIKI=../.. +SDIRS = . net +APPDIRS = ${wildcard ${addprefix $(CONTIKI)/,apps apps/*}} +CSDIRS = ${addprefix $(CONTIKI)/core/,. dev lib net sys cfs lib/ctk ctk loader net/ppp } + +CC=gcc +STRIP=strip +CFLAGS=-Wall -Wstrict-prototypes -Wmissing-prototypes -g \ + -I$(CONTIKI) \ + ${addprefix -I,$(CONTIKI)/core} \ + ${addprefix -I,$(SDIRS)} \ + ${addprefix -I,$(APPDIRS)} +LDFLAGS=-Wl,-Map=contiki-main.map,-export-dynamic,-lutil + + +vpath %.c ${SDIRS} $(CSDIRS) $(APPDIRS) + +-include $(CONTIKI)/arch/Makefile.common + +SYSTEM=process.o procinit.o service.o arg.o +UIP=uip.o uiplib.o tcpip.o \ + uip-fw.o uip-fw-service.o tcpdump.o \ + psock.o uipbuf.o uip_arp.o resolv.o \ + ppp/ahdlc.o ppp/ipcp.o ppp/lcp.o ppp/pap.o ppp/ppp.o ppp/ppp_process.o +LIBS=memb.o timer.o list.o etimer.o + +CFS=cfs.o + +WWW=www.o webclient.o http-strings.o htmlparser.o html-strings.o www-dsc.o http-user-agent-string.o +EMAIL=email.o smtp-socket.o smtp-strings.o ctk-textedit.o +WEBSERVER=webserver.o webserver-dsc.o httpd.o httpd-fs.o http-strings.o httpd-cgi.o webserver-nogui.o +TELNET=simpletelnet.o telnet.o +VNCVIEWER=vnc.o vnc-viewer.o vnc-draw.o vnc-dsc.o + +CTK=ctk.o +CTKGTK=ctk-gtksim.o ctk-draw.o ctk-gtksim-service.o libconio.o ctk-gtksim-draw.o +CTKVNC=ctk-vncserver.o libconio.o vnc-server.o vnc-out.o ctk-vncfont.o +CTKTERM=libconio.o ctk-term.o ctk-term-in.o ctk-term-out.o ctk-termtelnet.o + +POP=pop.o popc.o popc-strings.o + +TELNETD=telnetd.o shell.o + +APPS=$(WWW) $(EMAIL) $(WEBSERVER) $(TELNET) $(TELNETD) program-handler.o + +contiki.a: $(SYSTEM) $(UIP) uip-split.o $(LIBS) $(CFS) \ + ppp-arch.o $(APPS) \ + $(CTK) $(CTKVNC) \ + dlloader.o process.o clock.o + $(AR) rcf $@ $^ + +webserver.co: webserver-nogui.co httpd.o httpd-fs.o http-strings.o httpd-cgi.o psock.o uipbuf.o + $(LD) -i -o $@ $^ + +%.co: %.o + $(LD) -i -o $@ $^ + +%.ce: %.co + $(LD) -shared -o $@ $^ + +%.co: %.c + $(CC) $(CFLAGS) -DPROCESS_LOADABLE -c $< -o $@ + $(STRIP) --strip-unneeded -g -x $@ + + +contiki: contiki-main.o contiki.a + gcc $(LDFLAGS) -o $@ $^ + +test: test-main.o contiki.a + gcc $(LDFLAGS) -o $@ $^ + +clean: + rm -f *.o *~ *core contiki *.s *.ce *.co *.a *.map Makefile.depend ppp/*.o + +Makefile.depend depend: + gcc -MM \ + ${addprefix -I,$(CSDIRS)} \ + ${addprefix -I,$(SDIRS)} \ + ${addsuffix /*.c,$(CSDIRS)} \ + ${addsuffix /*.c,$(SDIRS)} \ + > Makefile.depend 2> /dev/null || true + +include Makefile.depend + diff --git a/platform/minimal-ppp/Makefile.minimal-ppp b/platform/minimal-ppp/Makefile.minimal-ppp new file mode 100644 index 000000000..515156e9a --- /dev/null +++ b/platform/minimal-ppp/Makefile.minimal-ppp @@ -0,0 +1,58 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +#contiki: contiki-$(TARGET).a + +CONTIKI_TARGET_DIRS = . net +CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} + +UIPDRIVERS = ppp/ahdlc.c ppp/ipcp.c ppp/lcp.c ppp/pap.c ppp/ppp.c ppp/ppp_process.c +CONTIKI_TARGET_SOURCEFILES = ppp-arch.c contiki-main.c dlloader.c clock.c leds.c leds-arch.c $(UIPDRIVERS) + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +.SUFFIXES: + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/x86 + +### Compiler definitions +CC = gcc +LD = ld +AS = as +OBJCOPY = objcopy +STRIP = strip +CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) \ + -I$(CONTIKI)/platform/$(TARGET) \ + ${addprefix -I,$(APPDIRS)} $(APP_INCLUDES) \ + -DWITH_UIP -DWITH_ASCII \ + -Wall -g -I. -I/usr/local/include +CFLAGS += $(CFLAGSNO) +LDFLAGS = -Wl,-Map=contiki.map,-export-dynamic + +### Setup directory search path for source files + +CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \ + $(CONTIKI_TARGET_DIRS)} +vpath %.c $(PROJECTDIRS) \ + $(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ + $(CONTIKI_CPU) $(APP_DIRS) + +### Compilation rules + +# $(OBJECTDIR)/%.o: %.c +# $(CC) $(CFLAGS) -c $< -o $@ + +%.so: $(OBJECTDIR)/%.o + $(LD) -shared -o $@ $^ + +# %.ce: %.co +# $(LD) -shared -o $@ $^ + +# %.co: %.c +# $(CC) $(CFLAGS) -DPROCESS_LOADABLE -c $< -o $@ +# $(STRIP) --strip-unneeded -g -x $@ + +# %: %.co $(CONTIKI_TARGET_MAIN) $(PROJECT_OBJECTFILES) contiki-$(TARGET).a +# $(CC) $(CFLAGS) -o $@.$(TARGET) $^ $(LDFLAGS) diff --git a/platform/minimal-ppp/README b/platform/minimal-ppp/README new file mode 100644 index 000000000..4d31474d8 --- /dev/null +++ b/platform/minimal-ppp/README @@ -0,0 +1,5 @@ +When ./contiki is started, it will open a pty and connect its internal pppd +daemon to it. +The host side of the pppd process will assign an IP number to the contiki +interface, that means that it is not necessary to "ping" the contiki interface +to give it a number. diff --git a/platform/minimal-ppp/clock.c b/platform/minimal-ppp/clock.c new file mode 100644 index 000000000..8bc7aed04 --- /dev/null +++ b/platform/minimal-ppp/clock.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: clock.c,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ + +/** + * \file + * Clock implementation for Unix. + * \author + * Adam Dunkels + */ + +#include "sys/clock.h" +#include + +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} +/*---------------------------------------------------------------------------*/ +void +clock_delay(unsigned int d) +{ + /* Does not do anything. */ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/minimal-ppp/contiki-conf.h b/platform/minimal-ppp/contiki-conf.h new file mode 100644 index 000000000..76f60d286 --- /dev/null +++ b/platform/minimal-ppp/contiki-conf.h @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-conf.h,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ + +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#include + +#include "ctk/ctk-vncarch.h" +#define TELNETD_CONF_LINELEN 80 +#define TELNETD_CONF_NUMLINES 16 + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL +#define CC_CONF_VA_ARGS 1 + +typedef uint8_t u8_t; +typedef uint16_t u16_t; +typedef uint32_t u32_t; +typedef unsigned short uip_stats_t; + +#define UIP_CONF_MAX_CONNECTIONS 40 +#define UIP_CONF_MAX_LISTENPORTS 40 +#define UIP_CONF_BUFFER_SIZE 420 +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_LOGGING 1 +#define UIP_CONF_UDP_CHECKSUMS 1 + +typedef unsigned long clock_time_t; +#define CLOCK_CONF_SECOND 1000 + +#define LOG_CONF_ENABLED 1 + +#define CTK_CONF_MAXMENUITEMS 10 + +/* The size of the HTML viewing area. */ +#define WWW_CONF_WEBPAGE_WIDTH 76 +#define WWW_CONF_WEBPAGE_HEIGHT 30 + +/* The size of the "Back" history. */ +#define WWW_CONF_HISTORY_SIZE 40 + +/* Defines the maximum length of an URL */ +#define WWW_CONF_MAX_URLLEN 200 + +/* The maxiumum number of widgets (i.e., hyperlinks, form elements) on + a page. */ +#define WWW_CONF_MAX_NUMPAGEWIDGETS 80 + +/* Turns
        support on or off; must be on for forms to work. */ +#define WWW_CONF_RENDERSTATE 1 + +/* Toggles support for HTML forms. */ +#define WWW_CONF_FORMS 1 + +/* Maximum lengths for various HTML form parameters. */ +#define WWW_CONF_MAX_FORMACTIONLEN 200 +#define WWW_CONF_MAX_FORMNAMELEN 200 +#define WWW_CONF_MAX_INPUTNAMELEN 200 +#define WWW_CONF_MAX_INPUTVALUELEN 240 + +#define WWW_CONF_PAGEVIEW 1 + + +/*------------------------------------------------------------------------------*/ + +#define LIBCONIO_CONF_SCREEN_WIDTH 80 +#define LIBCONIO_CONF_SCREEN_HEIGHT 45 +/*------------------------------------------------------------------------------*/ + +#include "ctk-arch.h" + +/* + * This file is used for setting various compile time settings for the + * CTK GUI toolkit. +*/ + +/* Toggles mouse support (must have support functions in the +architecture specific files to work). */ +#define CTK_CONF_MOUSE_SUPPORT 1 + +/* Defines which key that is to be used for activating the menus */ +#define CTK_CONF_MENU_KEY CH_F1 + +/* Defines which key that is to be used for switching the frontmost + window. */ +#define CTK_CONF_WINDOWSWITCH_KEY CH_F3 + +/* Defines which key that is to be used for switching to the next + widget. */ +#define CTK_CONF_WIDGETDOWN_KEY CH_TAB + +/* Defines which key that is to be used for switching to the prevoius + widget. */ +#define CTK_CONF_WIDGETUP_KEY CH_F5 + +/* Toggles support for icons. */ +#define CTK_CONF_ICONS 1 /* 107 bytes */ + +/* Toggles support for icon bitmaps. */ +#define CTK_CONF_ICON_BITMAPS 1 + +/* Toggles support for icon textmaps. */ +#define CTK_CONF_ICON_TEXTMAPS 1 + +/* Toggles support for movable windows. */ +#define CTK_CONF_WINDOWMOVE 1 /* 333 bytes */ + +/* Toggles support for closable windows. */ +#define CTK_CONF_WINDOWCLOSE 1 /* 14 bytes */ + +/* Toggles support for menus. */ +#define CTK_CONF_MENUS 1 /* 1384 bytes */ + +/* Defines the default width of a menu. */ +#define CTK_CONF_MENUWIDTH 16 +/* The maximum number of menu items in each menu. */ +#define CTK_CONF_MAXMENUITEMS 10 + +#define CTK_CONF_WIDGET_FLAGS 1 + + +/*------------------------------------------------------------------------------*/ + +#define COLOR_BLACK 0 +#define COLOR_WHITE 1 + +#define BORDERCOLOR COLOR_BLACK +#define SCREENCOLOR COLOR_BLACK + +#define WINDOWCOLOR_FOCUS COLOR_WHITE +#define WINDOWCOLOR COLOR_WHITE + +#define DIALOGCOLOR COLOR_WHITE + +#define WIDGETCOLOR_HLINK COLOR_WHITE +#define WIDGETCOLOR_FWIN COLOR_WHITE +#define WIDGETCOLOR COLOR_WHITE +#define WIDGETCOLOR_DIALOG COLOR_WHITE +#define WIDGETCOLOR_FOCUS COLOR_WHITE + +#define MENUCOLOR COLOR_WHITE +#define OPENMENUCOLOR COLOR_WHITE +#define ACTIVEMENUITEMCOLOR COLOR_WHITE + + +/*------------------------------------------------------------------------------*/ + +/* Maximum number of clients to the telnet server */ +#define CTK_TERM_CONF_MAX_TELNET_CLIENTS 3 + +/* Telnet server port */ +#define CTK_TERM_CONF_TELNET_PORT 23 + +/* Serial server output buffer size */ +#define CTK_TERM_CONF_SERIAL_BUFFER_SIZE 300 + +/* Maximum number of clients to the terminal module. + Should be set to CTK_TERM_CONF_MAX_TELNET_CLIENTS or + CTK_TERM_CONF_MAX_TELNET_CLIENTS+1 if the serial server is used too +*/ +#define CTK_TERM_CONF_MAX_CLIENTS (CTK_TERM_CONF_MAX_TELNET_CLIENTS+1) + + +/*------------------------------------------------------------------------------*/ + +#define CTK_VNCSERVER_CONF_NUMCONNS 10 + +#define CTK_VNCSERVER_CONF_MAX_ICONS 16 +/** + * Some PPP definitions + */ + +#define clock_seconds() time(NULL) + +#define UIP_CONF_LLH_LEN 0 + +#define IPCP_RETRY_COUNT 5 +#define IPCP_TIMEOUT 5 +#define xxdebug_printf printf +#define debug_printf +#define LCP_RETRY_COUNT 10 +#define PAP_USERNAME_SIZE 16 +#define PAP_PASSWORD_SIZE 16 +#define PPP_RX_BUFFER_SIZE 1024 + + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/minimal-ppp/contiki-main.c b/platform/minimal-ppp/contiki-main.c new file mode 100644 index 000000000..abe29fbad --- /dev/null +++ b/platform/minimal-ppp/contiki-main.c @@ -0,0 +1,99 @@ +/* + * 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 OS + * + * $Id: contiki-main.c,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + * + */ + +#include "contiki.h" + +#include "net/uip.h" +#include "net/ppp/ppp.h" +#include "webserver.h" +#include "telnetd.h" + + +PROCINIT(&etimer_process, &tcpip_process, + &webserver_process, + &telnetd_process, + &ppp_process); + +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + u16_t addr[2]; + + process_init(); + + procinit_init(); + + //autostart_start(autostart_processes); + + //uip_ipaddr(addr, 192,168,2,2); + //uip_sethostaddr(addr); + + //uip_ipaddr(addr, 192,168,2,1); + //uip_setdraddr(addr); + + //uip_ipaddr(addr, 255,255,255,0); + //uip_setnetmask(addr); + + while(1) { + int n; + n = process_run(); + /* if(n > 0) { + printf("%d processes in queue\n"); + }*/ + usleep(1); + etimer_request_poll(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +void log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} + +void +uip_log(char *m) +{ + printf("%s\n", m); +} + +unsigned short +sensors_light1(void) +{ + static unsigned short count; + return count++; +} diff --git a/platform/minimal-ppp/ctk-arch.h b/platform/minimal-ppp/ctk-arch.h new file mode 100644 index 000000000..f20d58c69 --- /dev/null +++ b/platform/minimal-ppp/ctk-arch.h @@ -0,0 +1,41 @@ +/* + * 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. + * + * $Id: ctk-arch.h,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + * + */ + +#ifndef __CTK_ARCH_H__ +#define __CTK_ARCH_H__ + +#include "ctk/ctk-vncarch.h" + +#define ctk_arch_isprint(x) isprint(x) + +#endif /* __CTK_ARCH_H__ */ diff --git a/platform/minimal-ppp/leds-arch.c b/platform/minimal-ppp/leds-arch.c new file mode 100644 index 000000000..cea7333f4 --- /dev/null +++ b/platform/minimal-ppp/leds-arch.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: leds-arch.c,v 1.1 2006/06/17 22:41:30 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "dev/leds.h" +static unsigned char leds; +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + leds = 0; +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char l) +{ + leds = l; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/minimal-ppp/ppp-arch.c b/platform/minimal-ppp/ppp-arch.c new file mode 100644 index 000000000..479c53f63 --- /dev/null +++ b/platform/minimal-ppp/ppp-arch.c @@ -0,0 +1,62 @@ +#include "contiki.h" +#include +#include +#include + +static int ppp_master_fd = -1; +static int ppp_slave_fd = -1; +static char ppp_slave_name[80]; + +void init_pty() { + char cmd[256]; + + if (ppp_master_fd == -1) { + if (openpty( &ppp_master_fd, &ppp_slave_fd, ppp_slave_name, NULL, NULL)==0) + { + sprintf( cmd, "stty raw -echo -echoe < %s", ppp_slave_name); + system(cmd); + printf("pty opened, slave name = %s\n", ppp_slave_name); + printf("Now start pppd, for example with:\n"); + printf("/usr/sbin/pppd %s 115200 local noauth nocrtscts nodetach persist asyncmap 0xffffffff 192.168.1.1:192.168.1.2\n", + ppp_slave_name); + close(ppp_slave_fd); + } else { + printf("pty open failed\n"); + exit(1); + } + } +} + +void ppp_arch_putchar(u8_t c) { + init_pty(); + if (write( ppp_master_fd, &c, 1 ) > 0) { + //printf("wr=0x%02x '%c'\n", c, c>=' '?c<0x7f?c:' ':' '); + } else { + //printf("wr=0x%02x '%c' FAILED\n", c, c>=' '?c<0x7f?c:' ':' '); + } +} + +int ppp_arch_getchar(u8_t *p) { + fd_set read_fds; + struct timeval timeout; + + init_pty(); + FD_ZERO( &read_fds ); + FD_SET( ppp_master_fd, &read_fds ); + timeout.tv_sec = 0; + timeout.tv_usec = 10000; + if (select( ppp_master_fd+1, &read_fds, NULL, NULL, &timeout) != 0) { + if (FD_ISSET( ppp_master_fd, &read_fds )) { + if ( read( ppp_master_fd, p, 1) > 0 ) { + //printf("rd=0x%02x\n", *p); + return 1; + } + return 0; + } + printf("closing pty: %s\n", ppp_slave_name); + close( ppp_master_fd ); + ppp_master_fd == -1; + } else { + return 0; + } +} diff --git a/platform/minimal-ppp/ppp_arch.h b/platform/minimal-ppp/ppp_arch.h new file mode 100644 index 000000000..e69de29bb diff --git a/platform/native/Makefile.native b/platform/native/Makefile.native new file mode 100644 index 000000000..b8aef31fc --- /dev/null +++ b/platform/native/Makefile.native @@ -0,0 +1,28 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +#contiki: contiki-$(TARGET).a + +CONTIKI_TARGET_DIRS = . dev +CONTIKI_TARGET_MAIN = ${addprefix $(OBJECTDIR)/,contiki-main.o} + +CONTIKI_TARGET_SOURCEFILES = contiki-main.c clock.c leds.c leds-arch.c \ + button-sensor.c pir-sensor.c vib-sensor.c \ + sensors.c irq.c random.c + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +.SUFFIXES: + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/x86 +include $(CONTIKI)/cpu/x86/Makefile.x86 + +### Setup directory search path for source files + +CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \ + $(CONTIKI_TARGET_DIRS)} +vpath %.c $(PROJECTDIRS) \ + $(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ + $(CONTIKI_CPU) $(APP_DIRS) diff --git a/platform/native/clock.c b/platform/native/clock.c new file mode 100644 index 000000000..4c4550eb3 --- /dev/null +++ b/platform/native/clock.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: clock.c,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + */ + +/** + * \file + * Clock implementation for Unix. + * \author + * Adam Dunkels + */ + +#include "sys/clock.h" +#include + +/*---------------------------------------------------------------------------*/ +clock_time_t +clock_time(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} +/*---------------------------------------------------------------------------*/ +void +clock_delay(unsigned int d) +{ + /* Does not do anything. */ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/native/contiki-conf.h b/platform/native/contiki-conf.h new file mode 100644 index 000000000..5cc540c31 --- /dev/null +++ b/platform/native/contiki-conf.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: contiki-conf.h,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + */ + +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +#include + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL +#define CC_CONF_VA_ARGS 1 +#define CC_CONF_INLINE inline + +typedef uint8_t u8_t; +typedef uint16_t u16_t; +typedef uint32_t u32_t; +typedef unsigned short uip_stats_t; + +#define UIP_CONF_MAX_CONNECTIONS 40 +#define UIP_CONF_MAX_LISTENPORTS 40 +#define UIP_CONF_BUFFER_SIZE 420 +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN +#define UIP_CONF_TCP_SPLIT 1 +#define UIP_CONF_LOGGING 0 +#define UIP_CONF_UDP_CHECKSUMS 1 + +typedef unsigned long clock_time_t; +#define CLOCK_CONF_SECOND 1000 + +#define LOG_CONF_ENABLED 1 + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/native/contiki-main.c b/platform/native/contiki-main.c new file mode 100644 index 000000000..ba4c152c2 --- /dev/null +++ b/platform/native/contiki-main.c @@ -0,0 +1,98 @@ +/* + * 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 OS + * + * $Id: contiki-main.c,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + * + */ + +#include "contiki.h" + +#include "net/uip.h" + +#include "dev/button-sensor.h" +#include "dev/pir-sensor.h" +#include "dev/vib-sensor.h" + +PROCINIT(&etimer_process, &tcpip_process); + +SENSORS(&pir_sensor, &vib_sensor, &button_sensor); + +/*---------------------------------------------------------------------------*/ +int +main(void) +{ + uip_ipaddr_t addr; + + process_init(); + + procinit_init(); + + autostart_start(autostart_processes); + + uip_ipaddr(addr, 192,168,2,2); + uip_sethostaddr(addr); + + uip_ipaddr(addr, 192,168,2,1); + uip_setdraddr(addr); + + uip_ipaddr(addr, 255,255,255,0); + uip_setnetmask(addr); + + printf("Contiki initiated, now starting process scheduling\n"); + + while(1) { + int n; + n = process_run(); + usleep(1); + etimer_request_poll(); + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +void log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} + +void +uip_log(char *m) +{ + printf("%s\n", m); +} + +/*unsigned short +sensors_light1(void) +{ + static unsigned short count; + return count++; +} +*/ diff --git a/platform/native/dev/beep.c b/platform/native/dev/beep.c new file mode 100644 index 000000000..680001f29 --- /dev/null +++ b/platform/native/dev/beep.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: beep.c,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + */ +#include +#include "dev/beep.h" + +void +beep_down(int n) +{ + printf("beep_down(%d)\n", n); +} + +void +beep_beep(int n) +{ + printf("beep_beep(%d)\n", n); +} + +void +beep_alarm(int alarmmode, int len) +{ + printf("beep_alarm(%d,%d)\n", alarmmode, len); +} + +void +beep_spinup(void) +{ + +} + +void beep(void) +{ + printf("%cbeep\n", 7); /*fflush(NULL);*/ +} + + +void +beep_off(void) +{ + +} +void +beep_on(void) +{ + +} + +void +beep_long(clock_time_t len) +{ +} + +void +beep_quick(int n) +{ + +} diff --git a/platform/native/dev/beep.h b/platform/native/dev/beep.h new file mode 100644 index 000000000..e75ceafd6 --- /dev/null +++ b/platform/native/dev/beep.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: beep.h,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + */ +/** + * \addtogroup esb + * @{ + */ + +/** + * \defgroup beeper Beeper interface + * @{ + */ + +/** + * \file + * Interface to the beeper. + * \author Adam Dunkels + * + */ + +#ifndef __BEEP_H__ +#define __BEEP_H__ + +#define BEEP_ON 1 +#define BEEP_OFF 0 + +#define BEEP_ALARM1 1 +#define BEEP_ALARM2 2 + +#include "sys/clock.h" + +/** + * Beep for a specified time. + * + * This function causes the beeper to beep for the specified time. The + * time is measured in the same units as for the clock_delay() + * function. + * + * \note This function will hang the CPU during the beep. + * + * \note This function will stop any beep that was on previously when this + * function ends. + * + * \note If the beeper is turned off with beep_off() this call will still + * take the same time, though it will be silent. + * + * \param len The length of the beep. + * + */ +void beep_beep(int len); + +/** + * Beep an alarm for a specified time. + * + * This function causes the beeper to beep for the specified time. The + * time is measured in the same units as for the clock_delay() + * function. + * + * \note This function will hang the CPU during the beep. + * + * \note This function will stop any beep that was on previously when this + * function ends. + * + * \note If the beeper is turned off with beep_off() this call will still + * take the same time, though it will be silent. + * + * \param alarmmode The alarm mode (BEEP_ALARM1,BEEP_ALARM2) + * \param len The length of the beep. + * + */ +void beep_alarm(int alarmmode, int len); + +/** + * Produces a quick click-like beep. + * + * This function produces a short beep that sounds like a click. + * + */ +void beep(void); + +/** + * A beep with a pitch-bend down. + * + * This function produces a pitch-bend sound with deecreasing + * frequency. + * + * \param len The length of the pitch-bend. + * + */ +void beep_down(int len); + +/** + * Turn the beeper on. + * + * This function turns on the beeper. The beeper is turned off with + * the beep_off() function. + */ +void beep_on(void); + +/** + * Turn the beeper off. + * + * This function turns the beeper off after it has been turned on with + * beep_on(). + */ +void beep_off(void); + +/** + * Produce a sound similar to a hard-drive spinup. + * + * This function produces a sound that is intended to be similar to + * the sound a hard-drive makes when it starts. + * + */ +void beep_spinup(void); + +/** + * Beep for a long time (seconds) + * + * This function produces a beep with the specified length and will + * not return until the beep is complete. The length of the beep is + * specified using CLOCK_SECOND: a two second beep is CLOCK_SECOND * + * 2, and a quarter second beep is CLOCK_SECOND / 4. + * + * \note If the beeper is turned off with beep_off() this call will still + * take the same time, though it will be silent. + * + * \param len The length of the beep, measured in units of CLOCK_SECOND + */ +void beep_long(clock_time_t len); + +void beep_quick(int num); + +/** @} */ +/** @} */ + +#endif /* __BEEP_H__ */ diff --git a/platform/native/dev/button-sensor.c b/platform/native/dev/button-sensor.c new file mode 100644 index 000000000..c8f724503 --- /dev/null +++ b/platform/native/dev/button-sensor.c @@ -0,0 +1,60 @@ + +#include "dev/button-sensor.h" + +const struct sensors_sensor button_sensor; + +/*---------------------------------------------------------------------------*/ +void +button_press(void) +{ + sensors_changed(&button_sensor); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/native/dev/button-sensor.h b/platform/native/dev/button-sensor.h new file mode 100644 index 000000000..2a3f28459 --- /dev/null +++ b/platform/native/dev/button-sensor.h @@ -0,0 +1,12 @@ +#ifndef __BUTTON_SENSOR_H__ +#define __BUTTON_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor button_sensor; + +#define BUTTON_SENSOR "Button" + +void button_press(void); + +#endif /* __BUTTON_SENSOR_H__ */ diff --git a/platform/native/dev/dummy-sensors.c b/platform/native/dev/dummy-sensors.c new file mode 100644 index 000000000..66a4a4d4c --- /dev/null +++ b/platform/native/dev/dummy-sensors.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: dummy-sensors.c,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:31 $ + * $Revision: 1.1 $ + */ + +#include "dev/temperature-sensor.h" + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/native/dev/eeprom.c b/platform/native/dev/eeprom.c new file mode 100644 index 000000000..94b86baa5 --- /dev/null +++ b/platform/native/dev/eeprom.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: eeprom.c,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + */ +#include "dev/eeprom.h" +#include "node.h" +#include + +#include +#include +#include +#include + +static unsigned char eeprom[65536]; + +void +eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size) +{ + int f; + char name[400]; + + snprintf(name, sizeof(name), "eeprom.%d.%d", node_x(), node_y()); + f = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644); + lseek(f, addr, SEEK_SET); + write(f, buf, size); + close(f); + + printf("eeprom_write(addr 0x%02x, buf %p, size %d);\n", addr, buf, size); + + memcpy(&eeprom[addr], buf, size); +} +void +eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size) +{ + /* printf("eeprom_read(addr 0x%02x, buf %p, size %d);\n", addr, buf, size);*/ + memcpy(buf, &eeprom[addr], size); +} diff --git a/platform/native/dev/irq.c b/platform/native/dev/irq.c new file mode 100644 index 000000000..160e0c1b7 --- /dev/null +++ b/platform/native/dev/irq.c @@ -0,0 +1,5 @@ +void +irq_init(void) +{ +} + diff --git a/platform/native/dev/leds-arch.c b/platform/native/dev/leds-arch.c new file mode 100644 index 000000000..cd7a8ccab --- /dev/null +++ b/platform/native/dev/leds-arch.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: leds-arch.c,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "dev/leds.h" +static unsigned char leds; +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + leds = 0; +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + return leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char l) +{ + leds = l; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/native/dev/pir-sensor.c b/platform/native/dev/pir-sensor.c new file mode 100644 index 000000000..065cd1f6b --- /dev/null +++ b/platform/native/dev/pir-sensor.c @@ -0,0 +1,63 @@ + +#include "dev/pir-sensor.h" + +const struct sensors_sensor pir_sensor; + +static int pir_value; + +/*---------------------------------------------------------------------------*/ +void +pir_sensor_changed(int strength) +{ + pir_value += strength; + sensors_changed(&pir_sensor); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return pir_value; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(pir_sensor, PIR_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/native/dev/pir-sensor.h b/platform/native/dev/pir-sensor.h new file mode 100644 index 000000000..84659c760 --- /dev/null +++ b/platform/native/dev/pir-sensor.h @@ -0,0 +1,12 @@ +#ifndef __PIR_SENSOR_H__ +#define __PIR_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor pir_sensor; + +#define PIR_SENSOR "PIR" + +void pir_sensor_changed(int strength); + +#endif /* __PIR_SENSOR_H__ */ diff --git a/platform/native/dev/temperature-sensor.h b/platform/native/dev/temperature-sensor.h new file mode 100644 index 000000000..8636d9f94 --- /dev/null +++ b/platform/native/dev/temperature-sensor.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: temperature-sensor.h,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:31 $ + * $Revision: 1.1 $ + */ + +#ifndef __TEMPERATURE_SENSOR_H__ +#define __TEMPERATURE_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* __TEMPERATURE_SENSOR_H__ */ diff --git a/platform/native/dev/vib-sensor.c b/platform/native/dev/vib-sensor.c new file mode 100644 index 000000000..323601f06 --- /dev/null +++ b/platform/native/dev/vib-sensor.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: vib-sensor.c,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:31 $ + * $Revision: 1.1 $ + */ + +#include "dev/vib-sensor.h" + +const struct sensors_sensor vib_sensor; +static unsigned int vib; + +/*---------------------------------------------------------------------------*/ +void +vib_sensor_changed(void) +{ + sensors_changed(&vib_sensor); +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + vib = 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + vib = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + vib = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return vib; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(vib_sensor, VIB_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/native/dev/vib-sensor.h b/platform/native/dev/vib-sensor.h new file mode 100644 index 000000000..30523c104 --- /dev/null +++ b/platform/native/dev/vib-sensor.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: vib-sensor.h,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:31 $ + * $Revision: 1.1 $ + */ + +#ifndef __VIB_SENSOR_H__ +#define __VIB_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor vib_sensor; + +#define VIB_SENSOR "Vibration" + +void vib_sensor_changed(void); + +#endif /* __VIB_SENSOR_H__ */ diff --git a/platform/netsim/Makefile.netsim b/platform/netsim/Makefile.netsim new file mode 100644 index 000000000..f038282c7 --- /dev/null +++ b/platform/netsim/Makefile.netsim @@ -0,0 +1,52 @@ +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +#contiki: contiki-$(TARGET).a + +CONTIKI_TARGET_DIRS = . dev apps net + +SENSORS = sensors.c beep.c button-sensor.c pir-sensor.c vib-sensor.c \ + irq.c eeprom.c \ + dummy-sensors.c leds.c leds-arch.c esb-sensors.c +NETSIM = ether.c ethernode.c ethernode-drv.c tr1001.c tr1001-drv.c lpm.c \ + tapdev-drv.c tapdev-service.c tapdev.c rs232.c flash.c \ + node.c nodes.c sensor.c display.c random.c radio.c \ + dlloader.c main.c init.c contiki-main.c + +CONTIKI_TARGET_SOURCEFILES = $(NETSIM) $(SENSORS) + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +.SUFFIXES: + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/x86 + +### Compiler definitions +CC = gcc +LD = ld +AS = as +OBJCOPY = objcopy +STRIP = strip +CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) \ + -I$(CONTIKI)/platform/$(TARGET) \ + ${addprefix -I,$(APPDIRS)} \ + -DWITH_UIP -DWITH_ASCII \ + -Wall -g -I. -I/usr/local/include \ + `gtk-config --cflags` +CFLAGS += $(CFLAGSNO) +LDFLAGS = -Wl,-Map=contiki-$(TARGET).map,-export-dynamic `gtk-config --libs` + +### Setup directory search path for source files + +CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \ + $(CONTIKI_TARGET_DIRS)} +vpath %.c $(PROJECTDIRS) \ + $(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \ + $(CONTIKI_CPU) + +### Compilation rules + +%.so: $(OBJECTDIR)/%.o + $(LD) -shared -o $@ $^ diff --git a/platform/netsim/contiki-conf.h b/platform/netsim/contiki-conf.h new file mode 100644 index 000000000..cc02ee0fa --- /dev/null +++ b/platform/netsim/contiki-conf.h @@ -0,0 +1,296 @@ +#ifndef __CONTIKI_CONF_H__ +#define __CONTIKI_CONF_H__ + +/* + * 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: contiki-conf.h,v 1.1 2006/06/17 22:41:31 adamdunkels Exp $ + * + */ + +#define CC_CONF_REGISTER_ARGS 1 +#define CC_CONF_FUNCTION_POINTER_ARGS 1 +#define CC_CONF_FASTCALL + +#define CC_CONF_VA_ARGS 1 + +/*------------------------------------------------------------------------------*/ +/** + * \defgroup uipopttypedef uIP type definitions + * @{ + */ + +#include + +/** + * The 8-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * char" works for most compilers. + */ +typedef uint8_t u8_t; + +/** + * The 16-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * short" works for most compilers. + */ +typedef uint16_t u16_t; + +/** + * The 32-bit unsigned data type. + * + * This may have to be tweaked for your particular compiler. "unsigned + * short" works for most compilers. + */ +typedef uint32_t u32_t; + +/** + * The statistics data type. + * + * This datatype determines how high the statistics counters are able + * to count. + */ +typedef unsigned short uip_stats_t; + +/** @} */ + + +/*------------------------------------------------------------------------------*/ + +typedef unsigned long clock_time_t; +#define CLOCK_CONF_SECOND 1000 + + +/*------------------------------------------------------------------------------*/ + +#include "ctk/ctk-vncarch.h" + +/* + * This file is used for setting various compile time settings for the + * CTK GUI toolkit. +*/ + +/* Toggles mouse support (must have support functions in the +architecture specific files to work). */ +#define CTK_CONF_MOUSE_SUPPORT 1 + +/* Defines which key that is to be used for activating the menus */ +#define CTK_CONF_MENU_KEY CH_F1 + +/* Defines which key that is to be used for switching the frontmost + window. */ +#define CTK_CONF_WINDOWSWITCH_KEY CH_F3 + +/* Defines which key that is to be used for switching to the next + widget. */ +#define CTK_CONF_WIDGETDOWN_KEY CH_TAB + +/* Defines which key that is to be used for switching to the prevoius + widget. */ +#define CTK_CONF_WIDGETUP_KEY CH_F5 + +/* Toggles support for icons. */ +#define CTK_CONF_ICONS 1 /* 107 bytes */ + +/* Toggles support for icon bitmaps. */ +#define CTK_CONF_ICON_BITMAPS 1 + +/* Toggles support for icon textmaps. */ +#define CTK_CONF_ICON_TEXTMAPS 1 + +/* Toggles support for movable windows. */ +#define CTK_CONF_WINDOWMOVE 1 /* 333 bytes */ + +/* Toggles support for closable windows. */ +#define CTK_CONF_WINDOWCLOSE 1 /* 14 bytes */ + +/* Toggles support for menus. */ +#define CTK_CONF_MENUS 1 /* 1384 bytes */ + +/* Defines the default width of a menu. */ +#define CTK_CONF_MENUWIDTH 16 +/* The maximum number of menu items in each menu. */ +#define CTK_CONF_MAXMENUITEMS 10 + +#define CTK_CONF_WIDGET_FLAGS 1 + + +/*------------------------------------------------------------------------------*/ + +#define COLOR_BLACK 0 +#define COLOR_WHITE 1 + +#define BORDERCOLOR COLOR_BLACK +#define SCREENCOLOR COLOR_BLACK + +#define WINDOWCOLOR_FOCUS COLOR_WHITE +#define WINDOWCOLOR COLOR_WHITE + +#define DIALOGCOLOR COLOR_WHITE + +#define WIDGETCOLOR_HLINK COLOR_WHITE +#define WIDGETCOLOR_FWIN COLOR_WHITE +#define WIDGETCOLOR COLOR_WHITE +#define WIDGETCOLOR_DIALOG COLOR_WHITE +#define WIDGETCOLOR_FOCUS COLOR_WHITE + +#define MENUCOLOR COLOR_WHITE +#define OPENMENUCOLOR COLOR_WHITE +#define ACTIVEMENUITEMCOLOR COLOR_WHITE + + +/*------------------------------------------------------------------------------*/ + +/* Maximum number of clients to the telnet server */ +#define CTK_TERM_CONF_MAX_TELNET_CLIENTS 3 + +/* Telnet server port */ +#define CTK_TERM_CONF_TELNET_PORT 23 + +/* Serial server output buffer size */ +#define CTK_TERM_CONF_SERIAL_BUFFER_SIZE 300 + +/* Maximum number of clients to the terminal module. + Should be set to CTK_TERM_CONF_MAX_TELNET_CLIENTS or + CTK_TERM_CONF_MAX_TELNET_CLIENTS+1 if the serial server is used too +*/ +#define CTK_TERM_CONF_MAX_CLIENTS (CTK_TERM_CONF_MAX_TELNET_CLIENTS+1) + + +/*------------------------------------------------------------------------------*/ + +#define CTK_VNCSERVER_CONF_NUMCONNS 10 + +#define CTK_VNCSERVER_CONF_MAX_ICONS 16 + + +/*------------------------------------------------------------------------------*/ + +#define EMAIL_CONF_WIDTH 36 +#define EMAIL_CONF_HEIGHT 16 + + +/*------------------------------------------------------------------------------*/ + +#define IRC_CONF_WIDTH 78 +#define IRC_CONF_HEIGHT 21 + +#define IRC_CONF_SYSTEM_STRING "GTK simulation" + + +/*------------------------------------------------------------------------------*/ + +#define LIBCONIO_CONF_SCREEN_WIDTH 80 +#define LIBCONIO_CONF_SCREEN_HEIGHT 45 + + +/*------------------------------------------------------------------------------*/ + +#define LOG_CONF_ENABLED 1 + + +/*------------------------------------------------------------------------------*/ + +#define PROGRAM_HANDLER_CONF_MAX_NUMDSCS 10 + + +/*------------------------------------------------------------------------------*/ + +#define SHELL_GUI_CONF_XSIZE 46 +#define SHELL_GUI_CONF_YSIZE 22 + + +/*------------------------------------------------------------------------------*/ + +#define TELNETD_CONF_LINELEN 80 +#define TELNETD_CONF_NUMLINES 16 + + +/*------------------------------------------------------------------------------*/ + +#define UIP_CONF_MAX_CONNECTIONS 40 +#define UIP_CONF_MAX_LISTENPORTS 40 +#define UIP_CONF_BUFFER_SIZE 420 + +#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN + +#define UIP_CONF_BROADCAST 1 + +#define UIP_CONF_TCP_SPLIT 1 + +#define UIP_CONF_LOGGING 0 + +#define UIP_CONF_UDP_CHECKSUMS 0 + + +/*------------------------------------------------------------------------------*/ + +#define VNC_CONF_VIEWPORT_WIDTH (32*8) +#define VNC_CONF_VIEWPORT_HEIGHT (16*8) + +#define VNC_CONF_REFRESH_ROWS 8 + + +/*------------------------------------------------------------------------------*/ + +/* The size of the HTML viewing area. */ +#define WWW_CONF_WEBPAGE_WIDTH 76 +#define WWW_CONF_WEBPAGE_HEIGHT 30 + +/* The size of the "Back" history. */ +#define WWW_CONF_HISTORY_SIZE 40 + +/* Defines the maximum length of an URL */ +#define WWW_CONF_MAX_URLLEN 200 + +/* The maxiumum number of widgets (i.e., hyperlinks, form elements) on + a page. */ +#define WWW_CONF_MAX_NUMPAGEWIDGETS 80 + +/* Turns
        support on or off; must be on for forms to work. */ +#define WWW_CONF_RENDERSTATE 1 + +/* Toggles support for HTML forms. */ +#define WWW_CONF_FORMS 1 + +/* Maximum lengths for various HTML form parameters. */ +#define WWW_CONF_MAX_FORMACTIONLEN 200 +#define WWW_CONF_MAX_FORMNAMELEN 200 +#define WWW_CONF_MAX_INPUTNAMELEN 200 +#define WWW_CONF_MAX_INPUTVALUELEN 240 + +#define WWW_CONF_PAGEVIEW 1 + +#define LOADER_CONF_ARCH "loader/dlloader.h" + +#endif /* __CONTIKI_CONF_H__ */ diff --git a/platform/netsim/contiki-esb.h b/platform/netsim/contiki-esb.h new file mode 100644 index 000000000..49d74ec57 --- /dev/null +++ b/platform/netsim/contiki-esb.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: contiki-esb.h,v 1.1 2006/06/17 22:41:33 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __CONTIKI_ESB_H__ +#define __CONTIKI_ESB_H__ + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" +#include "dev/leds.h" + +#include "dev/vib-sensor.h" +#include "dev/radio-sensor.h" +#include "dev/pir-sensor.h" +#include "dev/temperature-sensor.h" +#include "dev/button-sensor.h" + +#include "dev/lpm.h" +#include "dev/radio.h" + +#include "dev/tr1001.h" +#include "dev/tr1001-drv.h" + +#include "dev/beep.h" + +#endif /* __CONTIKI_ESB_H__ */ diff --git a/platform/netsim/contiki-main.c b/platform/netsim/contiki-main.c new file mode 100644 index 000000000..35cfe5263 --- /dev/null +++ b/platform/netsim/contiki-main.c @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: contiki-main.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ + +#include "contiki.h" +#include "contiki-net.h" +#include "contiki-lib.h" + +#include "net/tapdev.h" +#include "net/tapdev-drv.h" +#include "net/tapdev-service.h" +#include "net/ethernode-drv.h" +#include "net/ethernode.h" +#include "ether.h" + +/*#include +#include +#include */ + +#include "dev/button-sensor.h" +#include "dev/pir-sensor.h" +#include "dev/vib-sensor.h" +#include "dev/leds.h" + +static struct uip_fw_netif tapif = + {UIP_FW_NETIF(0,0,0,0, 0,0,0,0, tapdev_send)}; +static struct uip_fw_netif ethernodeif = + {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, ethernode_drv_send)}; + +static const struct uip_eth_addr ethaddr = {{0x00,0x06,0x98,0x01,0x02,0x12}}; + +/*PROCESS(test_send_process, "Test send stuff"); + PROCESS(test_tcp_process, "Test TCP");*/ + +SENSORS(&button_sensor, &pir_sensor, &vib_sensor); + +PROCINIT(&sensors_process, &etimer_process, &tcpip_process, + ðernode_drv_process, + &uip_fw_process); + +#if 0 +static +PT_THREAD(send_packet(struct pt *pt, + struct uip_udp_conn *c, process_event_t ev, + process_data_t data)) +{ + PT_BEGIN(pt); + + tcpip_poll_udp(c); + + PT_YIELD_UNTIL(pt, ev == tcpip_event); + + uip_send("hej", 3); + + PT_END(pt); +} + +PROCESS_THREAD(test_send_process, ev, data) +{ + static struct uip_udp_conn *conn; + static struct etimer etimer; + static struct pt send_pt; + + PROCESS_BEGIN(); + + conn = udp_broadcast_new(HTONS(3737), NULL); + + etimer_set(&etimer, CLOCK_SECOND * 2); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&etimer) || uip_newdata()); + + if(uip_newdata()) { + /* printf("Got a packet!\n");*/ + } + + if(etimer_expired(&etimer)) { + PROCESS_SPAWN(&send_pt, send_packet(&send_pt, conn, ev, data)); + etimer_set(&etimer, CLOCK_SECOND * 2); + } + + } + + PROCESS_END(); +} + +PROCESS_THREAD(test_tcp_process, ev, data) +{ + uip_ipaddr_t server; + + PROCESS_BEGIN(); + + uip_ipaddr(server, 255,255,255,255); + tcp_connect(server, HTONS(1000), NULL); + + while(1) { + PROCESS_WAIT_EVENT(); + printf("test_tcp_process: event %d\n", ev); + } + + PROCESS_END(); +} + +#endif /* 0 */ +/*---------------------------------------------------------------------------*/ +/*static void +idle(void) +{ + ether_server_poll(); + display_tick(); + display_redraw(); + ether_tick(); + ek_run(); +}*/ +/*---------------------------------------------------------------------------*/ +void +contiki_main(int flag) +{ + random_init(0); + + leds_init(); + + process_init(); + + procinit_init(); + + if(flag == 1) { + process_start(&tapdev_drv_process, NULL); + uip_fw_register(ðernodeif); + uip_fw_default(&tapif); + printf("uip_hostaddr %02x%02x\n", uip_hostaddr[0], uip_hostaddr[1]); + } else { + uip_fw_default(ðernodeif); + } + leds_green(LEDS_ON); + + autostart_start(autostart_processes); + + while(1) { + int n; + n = process_run(); + /* if(n > 0) { + printf("%d processes in queue\n"); + }*/ + usleep(1); + etimer_request_poll(); + } + +} +/*---------------------------------------------------------------------------*/ +process_event_t codeprop_event_quit; diff --git a/platform/netsim/contiki-main.h b/platform/netsim/contiki-main.h new file mode 100644 index 000000000..98257b3b8 --- /dev/null +++ b/platform/netsim/contiki-main.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: contiki-main.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#ifndef __CONTIKI_MAIN_H__ +#define __CONTIKI_MAIN_H__ + +void contiki_main(int b); + +#endif /* __CONTIKI_MAIN_H__ */ diff --git a/platform/netsim/dev/beep.c b/platform/netsim/dev/beep.c new file mode 100644 index 000000000..6c589d973 --- /dev/null +++ b/platform/netsim/dev/beep.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: beep.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#include +#include "dev/beep.h" + +void +beep_down(int n) +{ + printf("beep_down(%d)\n", n); +} + +void +beep_beep(int n) +{ + printf("beep_beep(%d)\n", n); +} + +void +beep_alarm(int alarmmode, int len) +{ + printf("beep_alarm(%d,%d)\n", alarmmode, len); +} + +void +beep_spinup(void) +{ + +} + +void beep(void) +{ + printf("%cbeep\n", 7); /*fflush(NULL);*/ +} + + +void +beep_off(void) +{ + +} +void +beep_on(void) +{ + +} + +void +beep_long(clock_time_t len) +{ +} + +void +beep_quick(int n) +{ + +} diff --git a/platform/netsim/dev/beep.h b/platform/netsim/dev/beep.h new file mode 100644 index 000000000..8803f135b --- /dev/null +++ b/platform/netsim/dev/beep.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: beep.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +/** + * \addtogroup esb + * @{ + */ + +/** + * \defgroup beeper Beeper interface + * @{ + */ + +/** + * \file + * Interface to the beeper. + * \author Adam Dunkels + * + */ + +#ifndef __BEEP_H__ +#define __BEEP_H__ + +#define BEEP_ON 1 +#define BEEP_OFF 0 + +#define BEEP_ALARM1 1 +#define BEEP_ALARM2 2 + +#include "sys/clock.h" + +/** + * Beep for a specified time. + * + * This function causes the beeper to beep for the specified time. The + * time is measured in the same units as for the clock_delay() + * function. + * + * \note This function will hang the CPU during the beep. + * + * \note This function will stop any beep that was on previously when this + * function ends. + * + * \note If the beeper is turned off with beep_off() this call will still + * take the same time, though it will be silent. + * + * \param len The length of the beep. + * + */ +void beep_beep(int len); + +/** + * Beep an alarm for a specified time. + * + * This function causes the beeper to beep for the specified time. The + * time is measured in the same units as for the clock_delay() + * function. + * + * \note This function will hang the CPU during the beep. + * + * \note This function will stop any beep that was on previously when this + * function ends. + * + * \note If the beeper is turned off with beep_off() this call will still + * take the same time, though it will be silent. + * + * \param alarmmode The alarm mode (BEEP_ALARM1,BEEP_ALARM2) + * \param len The length of the beep. + * + */ +void beep_alarm(int alarmmode, int len); + +/** + * Produces a quick click-like beep. + * + * This function produces a short beep that sounds like a click. + * + */ +void beep(void); + +/** + * A beep with a pitch-bend down. + * + * This function produces a pitch-bend sound with deecreasing + * frequency. + * + * \param len The length of the pitch-bend. + * + */ +void beep_down(int len); + +/** + * Turn the beeper on. + * + * This function turns on the beeper. The beeper is turned off with + * the beep_off() function. + */ +void beep_on(void); + +/** + * Turn the beeper off. + * + * This function turns the beeper off after it has been turned on with + * beep_on(). + */ +void beep_off(void); + +/** + * Produce a sound similar to a hard-drive spinup. + * + * This function produces a sound that is intended to be similar to + * the sound a hard-drive makes when it starts. + * + */ +void beep_spinup(void); + +/** + * Beep for a long time (seconds) + * + * This function produces a beep with the specified length and will + * not return until the beep is complete. The length of the beep is + * specified using CLOCK_SECOND: a two second beep is CLOCK_SECOND * + * 2, and a quarter second beep is CLOCK_SECOND / 4. + * + * \note If the beeper is turned off with beep_off() this call will still + * take the same time, though it will be silent. + * + * \param len The length of the beep, measured in units of CLOCK_SECOND + */ +void beep_long(clock_time_t len); + +void beep_quick(int num); + +/** @} */ +/** @} */ + +#endif /* __BEEP_H__ */ diff --git a/platform/netsim/dev/button-sensor.c b/platform/netsim/dev/button-sensor.c new file mode 100644 index 000000000..c8f724503 --- /dev/null +++ b/platform/netsim/dev/button-sensor.c @@ -0,0 +1,60 @@ + +#include "dev/button-sensor.h" + +const struct sensors_sensor button_sensor; + +/*---------------------------------------------------------------------------*/ +void +button_press(void) +{ + sensors_changed(&button_sensor); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/netsim/dev/button-sensor.h b/platform/netsim/dev/button-sensor.h new file mode 100644 index 000000000..2a3f28459 --- /dev/null +++ b/platform/netsim/dev/button-sensor.h @@ -0,0 +1,12 @@ +#ifndef __BUTTON_SENSOR_H__ +#define __BUTTON_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor button_sensor; + +#define BUTTON_SENSOR "Button" + +void button_press(void); + +#endif /* __BUTTON_SENSOR_H__ */ diff --git a/platform/netsim/dev/dummy-sensors.c b/platform/netsim/dev/dummy-sensors.c new file mode 100644 index 000000000..a0ee65c9b --- /dev/null +++ b/platform/netsim/dev/dummy-sensors.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: dummy-sensors.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:36 $ + * $Revision: 1.1 $ + */ + +#include "dev/temperature-sensor.h" +#include "dev/radio-sensor.h" + +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(temperature_sensor, TEMPERATURE_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); +SENSORS_SENSOR(radio_sensor, RADIO_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/netsim/dev/eeprom.c b/platform/netsim/dev/eeprom.c new file mode 100644 index 000000000..225508a31 --- /dev/null +++ b/platform/netsim/dev/eeprom.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: eeprom.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ +#include "dev/eeprom.h" +#include "node.h" +#include + +#include +#include +#include +#include + +static unsigned char eeprom[65536]; + +void +eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size) +{ + int f; + char name[400]; + + snprintf(name, sizeof(name), "eeprom.%d.%d", node_x(), node_y()); + f = open(name, O_WRONLY | O_APPEND | O_CREAT, 0644); + lseek(f, addr, SEEK_SET); + write(f, buf, size); + close(f); + + printf("eeprom_write(addr 0x%02x, buf %p, size %d);\n", addr, buf, size); + + memcpy(&eeprom[addr], buf, size); +} +void +eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size) +{ + /* printf("eeprom_read(addr 0x%02x, buf %p, size %d);\n", addr, buf, size);*/ + memcpy(buf, &eeprom[addr], size); +} diff --git a/platform/netsim/dev/esb-sensors.c b/platform/netsim/dev/esb-sensors.c new file mode 100644 index 000000000..037aa0d9e --- /dev/null +++ b/platform/netsim/dev/esb-sensors.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: esb-sensors.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "esb-sensors.h" +#include +/*---------------------------------------------------------------------------*/ +void +esb_sensors_on(void) +{ + printf("esb_sensors_on()\n"); +} +/*---------------------------------------------------------------------------*/ +void +esb_sensors_off(void) +{ + printf("esb_sensors_off()\n"); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/esb-sensors.h b/platform/netsim/dev/esb-sensors.h new file mode 100644 index 000000000..4a1d50242 --- /dev/null +++ b/platform/netsim/dev/esb-sensors.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: esb-sensors.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __ESB_SENSORS_H__ +#define __ESB_SENSORS_H__ + +void esb_sensors_on(void); +void esb_sensors_off(void); + +#endif /* __ESB_SENSORS_H__ */ diff --git a/platform/netsim/dev/flash.c b/platform/netsim/dev/flash.c new file mode 100644 index 000000000..bd56a9b68 --- /dev/null +++ b/platform/netsim/dev/flash.c @@ -0,0 +1,61 @@ +/** + * \file + * Functions for reading and writing flash ROM. + * \author Adam Dunkels + */ + +/* Copyright (c) 2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * $Id: flash.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + * Author: Adam Dunkels + * + */ + + +/*---------------------------------------------------------------------------*/ +void +flash_setup(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +flash_done(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +flash_clear(unsigned short *ptr) +{ +} +/*---------------------------------------------------------------------------*/ +void +flash_write(unsigned short *ptr, unsigned short word) +{ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/flash.h b/platform/netsim/dev/flash.h new file mode 100644 index 000000000..b2b5d2720 --- /dev/null +++ b/platform/netsim/dev/flash.h @@ -0,0 +1,78 @@ +/** + * \file + * Functions for reading and writing MSP430 flash ROM. + * \author Adam Dunkels + */ + +/* Copyright (c) 2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * $Id: flash.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + * Author: Adam Dunkels + * + */ + +#ifndef __FLASH_H__ +#define __FLASH_H__ + +/** + * Setup function to be called before any of the flash programming functions. + * + */ +void flash_setup(void); + +/** + * Function that is to be called after flashing is done. + */ +void flash_done(void); + +/** + * Write a 16-bit word to flash ROM. + * + * This function writes a 16-bit word to flash ROM. The function + * flash_setup() must have been called first. + * + * \param addr A pointer to the address in flash ROM which is to be + * written. + * + * \param word The 16-bit word that is to be written. + */ +void flash_write(unsigned short *addr, unsigned short word); + +/** + * Clear a 16-bit word in flash ROM. + * + * This function clears a 16-bit word in flash ROM. The function + * flash_setup() must have been called first. + * + * \param addr A pointer to the address in flash ROM which is to be + * cleared. + */ +void flash_clear(unsigned short *addr); + +#endif /* __FLASH_H__ */ diff --git a/platform/netsim/dev/irq.c b/platform/netsim/dev/irq.c new file mode 100644 index 000000000..160e0c1b7 --- /dev/null +++ b/platform/netsim/dev/irq.c @@ -0,0 +1,5 @@ +void +irq_init(void) +{ +} + diff --git a/platform/netsim/dev/leds-arch.c b/platform/netsim/dev/leds-arch.c new file mode 100644 index 000000000..67a82808a --- /dev/null +++ b/platform/netsim/dev/leds-arch.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: leds-arch.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-03 + * Updated : $Date: 2006/06/17 22:41:36 $ + * $Revision: 1.1 $ + */ + +#include "dev/leds.h" +#include "ether.h" + +static int cleds; + +void leds_arch_init() { + cleds = 0; +} + +unsigned char leds_arch_get() { + return cleds; +} + +void leds_arch_set(unsigned char leds) { + if(leds != cleds) { + cleds = leds; + ether_set_leds(cleds); + } +} diff --git a/platform/netsim/dev/lpm.c b/platform/netsim/dev/lpm.c new file mode 100644 index 000000000..4de5f759f --- /dev/null +++ b/platform/netsim/dev/lpm.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: lpm.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "lpm.h" +#include +/*---------------------------------------------------------------------------*/ +void +lpm_on(void) +{ + printf("lpm_on()\n"); +} +/*---------------------------------------------------------------------------*/ +void +lpm_off(void) +{ + printf("lpm_off()\n"); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/lpm.h b/platform/netsim/dev/lpm.h new file mode 100644 index 000000000..892655306 --- /dev/null +++ b/platform/netsim/dev/lpm.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: lpm.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ +#ifndef __LPM_H__ +#define __LPM_H__ + +void lpm_on(void); +void lpm_off(void); + + +#endif /* __LPM_H__ */ diff --git a/platform/netsim/dev/pir-sensor.c b/platform/netsim/dev/pir-sensor.c new file mode 100644 index 000000000..065cd1f6b --- /dev/null +++ b/platform/netsim/dev/pir-sensor.c @@ -0,0 +1,63 @@ + +#include "dev/pir-sensor.h" + +const struct sensors_sensor pir_sensor; + +static int pir_value; + +/*---------------------------------------------------------------------------*/ +void +pir_sensor_changed(int strength) +{ + pir_value += strength; + sensors_changed(&pir_sensor); +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return pir_value; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(pir_sensor, PIR_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/netsim/dev/pir-sensor.h b/platform/netsim/dev/pir-sensor.h new file mode 100644 index 000000000..84659c760 --- /dev/null +++ b/platform/netsim/dev/pir-sensor.h @@ -0,0 +1,12 @@ +#ifndef __PIR_SENSOR_H__ +#define __PIR_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor pir_sensor; + +#define PIR_SENSOR "PIR" + +void pir_sensor_changed(int strength); + +#endif /* __PIR_SENSOR_H__ */ diff --git a/platform/netsim/dev/radio-sensor.h b/platform/netsim/dev/radio-sensor.h new file mode 100644 index 000000000..35d97d33d --- /dev/null +++ b/platform/netsim/dev/radio-sensor.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: radio-sensor.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ +#ifndef __RADIO_SENSOR_H__ +#define __RADIO_SENSOR_H__ + +#include "contiki-esb.h" + +extern const struct sensors_sensor radio_sensor; + +#define RADIO_SENSOR "Radio" + +extern unsigned int radio_sensor_signal; + +#endif /* __RADIO_SENSOR_H__ */ diff --git a/platform/netsim/dev/radio.c b/platform/netsim/dev/radio.c new file mode 100644 index 000000000..38f242815 --- /dev/null +++ b/platform/netsim/dev/radio.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: radio.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "radio.h" +/*---------------------------------------------------------------------------*/ +void +radio_on(void) +{ +} +/*---------------------------------------------------------------------------*/ +void +radio_off(void) +{ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/radio.h b/platform/netsim/dev/radio.h new file mode 100644 index 000000000..1ec33274d --- /dev/null +++ b/platform/netsim/dev/radio.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: radio.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __RADIO_H__ +#define __RADIO_H__ + +void radio_on(void); +void radio_off(void); + +#endif /* __RADIO_H__ */ diff --git a/platform/netsim/dev/rs232.c b/platform/netsim/dev/rs232.c new file mode 100644 index 000000000..01126ff50 --- /dev/null +++ b/platform/netsim/dev/rs232.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: rs232.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include "rs232.h" +#include +/*---------------------------------------------------------------------------*/ +void +rs232_set_input(int (* f)(unsigned char)) +{ + printf("rs232_set_input(%p)\n", f); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/rs232.h b/platform/netsim/dev/rs232.h new file mode 100644 index 000000000..02f5e1a20 --- /dev/null +++ b/platform/netsim/dev/rs232.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: rs232.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __RS232_H__ +#define __RS232_H__ + +void rs232_set_input(int (* f)(unsigned char)); + +#endif /* __RS232_H__ */ diff --git a/platform/netsim/dev/temperature-sensor.h b/platform/netsim/dev/temperature-sensor.h new file mode 100644 index 000000000..8718790b3 --- /dev/null +++ b/platform/netsim/dev/temperature-sensor.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: temperature-sensor.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:36 $ + * $Revision: 1.1 $ + */ + +#ifndef __TEMPERATURE_SENSOR_H__ +#define __TEMPERATURE_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor temperature_sensor; + +#define TEMPERATURE_SENSOR "Temperature" + +#endif /* __TEMPERATURE_SENSOR_H__ */ diff --git a/platform/netsim/dev/tr1001-drv.c b/platform/netsim/dev/tr1001-drv.c new file mode 100644 index 000000000..90f1810e0 --- /dev/null +++ b/platform/netsim/dev/tr1001-drv.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: tr1001-drv.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +#include "contiki-esb.h" +#include "net/hc.h" + +#include +#include + +PROCESS(tr1001_drv_process, "TR1001 driver"); + +static unsigned char slip_dump; + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(tr1001_drv_process, ev, data) +{ + PROCESS_BEGIN(); + + tr1001_init(); + + while(1) { + + PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_POLL); + + uip_len = tr1001_poll(); + + if(uip_len > 0) { + uip_len = hc_inflate(); + tcpip_input(); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +tr1001_drv_request_poll(void) +{ + process_poll(&tr1001_drv_process); +} +/*---------------------------------------------------------------------------*/ +u8_t +tr1001_drv_send(void) +{ + int len; + + len = hc_compress(); + return tr1001_send(&uip_buf[UIP_LLH_LEN], len); +} +/*---------------------------------------------------------------------------*/ +void +tr1001_drv_set_slip_dump(int dump) +{ + slip_dump = dump; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/tr1001-drv.h b/platform/netsim/dev/tr1001-drv.h new file mode 100644 index 000000000..e7319d97a --- /dev/null +++ b/platform/netsim/dev/tr1001-drv.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: tr1001-drv.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ +#ifndef __TR1001_DRV_H__ +#define __TR1001_DRV_H__ + +PROCESS_NAME(tr1001_drv_process); + +void tr1001_drv_set_slip_dump(int dump); + +u8_t tr1001_drv_send(void); + +void tr1001_drv_request_poll(void); + +#endif /* __TR1001_DRV_H__ */ diff --git a/platform/netsim/dev/tr1001.c b/platform/netsim/dev/tr1001.c new file mode 100644 index 000000000..e52a1f64d --- /dev/null +++ b/platform/netsim/dev/tr1001.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: tr1001.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#include +#include "tr1001.h" +/*---------------------------------------------------------------------------*/ +void +tr1001_init(void) +{ + printf("tr1001_init()\n"); +} +/*---------------------------------------------------------------------------*/ +unsigned short +tr1001_poll(void) +{ + printf("tr1001_poll()\n"); + return 0; +} +/*---------------------------------------------------------------------------*/ +u8_t +tr1001_send(u8_t *packet, u16_t len) +{ + printf("tr1001_send(%p, %d)\n", packet, len); + return 0; +} +/*---------------------------------------------------------------------------*/ +void +tr1001_set_txpower(unsigned char p) +{ + printf("tr1001_set_txpower(%d)\n", p); +} +/*---------------------------------------------------------------------------*/ +unsigned short +tr1001_sstrength(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static unsigned short packets_ok, packets_err; +unsigned short +tr1001_packets_ok(void) +{ + return packets_ok; +} +/*---------------------------------------------------------------------------*/ +unsigned short +tr1001_packets_dropped(void) +{ + return packets_err; +} +/*---------------------------------------------------------------------------*/ +void +tr1001_clear_packets(void) +{ + packets_ok = packets_err = 0; +} +/*---------------------------------------------------------------------------*/ +unsigned short +tr1001_sstrength_value(unsigned int type) +{ + printf("tr1001_sstrength_value(%d)\n", type); + return 0; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/dev/tr1001.h b/platform/netsim/dev/tr1001.h new file mode 100644 index 000000000..2b9325bb1 --- /dev/null +++ b/platform/netsim/dev/tr1001.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2006, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: tr1001.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +/** + * \file + * A brief description of what this file is. + * \author + * Adam Dunkels + */ + +#ifndef __TR1001_H__ +#define __TR1001_H__ + +#include "contiki-net.h" + + +void tr1001_init(void); +u8_t tr1001_send(u8_t *packet, u16_t len); +unsigned short tr1001_poll(void); + +void tr1001_set_txpower(unsigned char p); +#define TR1001_TXPOWER_HIGHEST 100 +#define TR1001_TXPOWER_LOWEST 1 + +unsigned short tr1001_sstrength(void); + +#define TR1001_SSTRENGTH_DROPPED 1 +#define TR1001_SSTRENGTH_MAX 2 +#define TR1001_SSTRENGTH_MIN 3 +unsigned short tr1001_packets_ok(void); +unsigned short tr1001_packets_dropped(void); +void tr1001_clear_packets(void); +unsigned short tr1001_sstrength_value(unsigned int type); + +#endif /* __TR1001_H__ */ diff --git a/platform/netsim/dev/vib-sensor.c b/platform/netsim/dev/vib-sensor.c new file mode 100644 index 000000000..9932693ce --- /dev/null +++ b/platform/netsim/dev/vib-sensor.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: vib-sensor.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:36 $ + * $Revision: 1.1 $ + */ + +#include "dev/vib-sensor.h" + +const struct sensors_sensor vib_sensor; +static unsigned int vib; + +/*---------------------------------------------------------------------------*/ +void +vib_sensor_changed(void) +{ + sensors_changed(&vib_sensor); +} +/*---------------------------------------------------------------------------*/ +static int +irq(void) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void +init(void) +{ + vib = 0; +} +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + vib = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + vib = 0; +} +/*---------------------------------------------------------------------------*/ +static int +active(void) +{ + return vib; +} +/*---------------------------------------------------------------------------*/ +static unsigned int +value(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, void *c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static void * +status(int type) +{ + return NULL; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(vib_sensor, VIB_SENSOR, + init, irq, activate, deactivate, active, + value, configure, status); diff --git a/platform/netsim/dev/vib-sensor.h b/platform/netsim/dev/vib-sensor.h new file mode 100644 index 000000000..0e54ff747 --- /dev/null +++ b/platform/netsim/dev/vib-sensor.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Configurable Sensor Network Application + * Architecture for sensor nodes running the Contiki operating system. + * + * $Id: vib-sensor.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2006/06/17 22:41:36 $ + * $Revision: 1.1 $ + */ + +#ifndef __VIB_SENSOR_H__ +#define __VIB_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor vib_sensor; + +#define VIB_SENSOR "Vibration" + +void vib_sensor_changed(void); + +#endif /* __VIB_SENSOR_H__ */ diff --git a/platform/netsim/display.c b/platform/netsim/display.c new file mode 100644 index 000000000..d3f7efa5d --- /dev/null +++ b/platform/netsim/display.c @@ -0,0 +1,619 @@ +/* + * Copyright (c) 2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * $Id: display.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + * + * Author: Adam Dunkels + * + */ + +#include "dev/leds.h" +#include "display.h" +#include "nodes.h" +#include "node.h" +#include "ether.h" +#include "lib/list.h" +#include "lib/memb.h" +#include "sensor.h" + +#include + +#include + +static GdkPixmap *pixmap = NULL; +static GtkWidget *drawing_area; + + +#define DISPLAY_WIDTH 400 +#define DISPLAY_HEIGHT 300 + +#define BASESTATION_SIZE 4 + +#define MAPSCALE 20 +#define SCALE 2 + +#define MARK_SIZE 8 + +#define DOT_SIZE ether_strength() +#define DOT_INTENSITY 3 + +struct dot { + struct dot *next; + int x, y; + int size; + int intensity; +}; + +MEMB(dotsmem, struct dot, 20000); +LIST(dots); +LIST(tempdots); + +static int window_is_open; + +static GdkGC *intensity_gcs[DOT_INTENSITY]; + +static GdkGC *intensity_clusterhead; +static GdkGC *intensity_clusterhead_lightgray; +static GdkGC *intensity_clusterhead_red; + +static GdkGC *green, *red, *yellow, *black, *white; + +static struct nodes_node *marked_node; + +/*-----------------------------------------------------------------------------------*/ +void +display_redraw(void) +{ + int i, j; + struct nodes_node *n, *m; + char string[20]; + int x, y; + struct dot *d; + GdkGC *color; + + if(!window_is_open) { + return; + } + + gdk_draw_rectangle(pixmap, + white, + TRUE, + 0, 0, + drawing_area->allocation.width, + drawing_area->allocation.height); + + + for(i = 0; i < nodes_num(); ++i) { + n = nodes_node(i); + x = n->x; + y = n->y; + + if(n->type == NODE_TYPE_CLUSTERHEAD) { + gdk_draw_arc(pixmap, + intensity_clusterhead_lightgray, + TRUE, + x * SCALE - DOT_SIZE * SCALE, + y * SCALE - DOT_SIZE * SCALE, + DOT_SIZE * 2 * SCALE, DOT_SIZE * 2 * SCALE, + 0, 360 * 64); + } + + if(n == marked_node) { + gdk_draw_arc(pixmap, + red, + FALSE, + x * SCALE - MARK_SIZE * SCALE, + y * SCALE - MARK_SIZE * SCALE, + MARK_SIZE * 2 * SCALE, MARK_SIZE * 2 * SCALE, + 0, 360 * 64); + } + + } + + for(i = 0; i < nodes_num(); ++i) { + n = nodes_node(i); + x = n->x; + y = n->y; + + if(n->type == NODE_TYPE_CLUSTERHEAD) { + gdk_draw_rectangle(pixmap, + intensity_clusterhead_red, + TRUE, + x * SCALE, + y * SCALE, + 3, 3); + for(j = 0; j < nodes_num(); ++j) { + m = nodes_node(j); + if(m->type == NODE_TYPE_CLUSTERHEAD && + ((x - m->x) * (x - m->x) + + (y - m->y) * (y - m->y) < ether_strength() * ether_strength())) { + gdk_draw_line(pixmap, + intensity_clusterhead, + x * SCALE, + y * SCALE, + m->x * SCALE, + m->y * SCALE); + + + } + } + } else { + + gdk_draw_rectangle(pixmap, + black, + TRUE, + x * SCALE, + y * SCALE, + 2, 2); + /* gdk_draw_rectangle(pixmap, + drawing_area->style->white_gc, + TRUE, + x * SCALE, + y * SCALE, + 2, 2);*/ + if(n->leds & LEDS_GREEN) { + gdk_draw_rectangle(pixmap, + green, + TRUE, + x * SCALE + 2, + y * SCALE, + 4, 4); + } + if(n->leds & LEDS_YELLOW) { + gdk_draw_rectangle(pixmap, + yellow, + TRUE, + x * SCALE, + y * SCALE + 2, + 4, 4); + } + if(n->leds & LEDS_RED) { + gdk_draw_rectangle(pixmap, + red, + TRUE, + x * SCALE + 2, + y * SCALE + 2, + 4, 4); + } + } + + } + + for(d = list_head(dots); d != NULL; d = d->next) { + gdk_draw_arc(pixmap, + intensity_gcs[d->intensity - 1], + FALSE, + d->x * SCALE - d->size * SCALE, + d->y * SCALE - d->size * SCALE, + d->size * 2 * SCALE, d->size * 2 * SCALE, + 0, 360 * 64); + } + + + gtk_widget_draw(drawing_area, NULL); + +} +/*-----------------------------------------------------------------------------------*/ +void +display_tick(void) +{ + struct dot *d, *e; + struct ether_packet *p; + + if(!window_is_open) { + return; + } + + /* Fade out active dots. The intensity value of each dot is counted + downwards, and those dots that still have an intensity are placed + in a temporary list. The temporary list is then copied into the + list of all dots. */ + + list_init(tempdots); + + for(d = list_head(dots); + d != NULL; + d = e) { + if(d != NULL) { + e = d->next; + } else { + e = NULL; + } + d->size -= 4; + /* --(d->intensity);*/ + if(d->size > 0) { + list_push(tempdots, d); + } else { + memb_free(&dotsmem, (void *)d); + } + } + list_copy(dots, tempdots); + + /* Check if there are any new dots that should be placed in the list. */ + for(p = ether_packets(); p != NULL; p = p->next) { + d = (struct dot *)memb_alloc(&dotsmem); + + if(d != NULL) { + d->x = p->x; + d->y = p->y; + d->size = DOT_SIZE; + d->intensity = DOT_INTENSITY; + list_push(dots, d); + } + } +} +/*-----------------------------------------------------------------------------------*/ +static gint +configure_event(GtkWidget *widget, GdkEventConfigure *event) +{ + if(pixmap != NULL) { + gdk_pixmap_unref(pixmap); + } + + pixmap = gdk_pixmap_new(widget->window, + widget->allocation.width, + widget->allocation.height, + -1); + + if(pixmap == NULL) { + printf("gdk_pixmap_new == NULL\n"); + exit(1); + } + gdk_draw_rectangle(pixmap, + widget->style->black_gc, + TRUE, + 0, 0, + widget->allocation.width, + widget->allocation.height); + /* draw_screen();*/ + return TRUE; +} + +/* Redraw the screen from the backing pixmap */ +static gint +expose_event (GtkWidget * widget, GdkEventExpose * event) +{ + /* draw_screen();*/ + gdk_draw_pixmap(widget->window, + widget->style->fg_gc[GTK_WIDGET_STATE (widget)], + pixmap, + event->area.x, event->area.y, + event->area.x, event->area.y, + event->area.width, event->area.height); + return FALSE; +} + +static gint +key_press_event (GtkWidget * widget, GdkEventKey * event) +{ + /* if(event->keyval == GDK_Shift_L || + event->keyval == GDK_Shift_R) { + return TRUE; + } + keys[lastkey] = event->keyval; + ++lastkey; + if(lastkey >= NUMKEYS) { + lastkey = 0; + }*/ + + if(event->keyval == 'q') { + exit(0); + } + return TRUE; +} + +static gint +key_release_event (GtkWidget * widget, GdkEventKey * event) +{ + return TRUE; +} + +static gint +button_press_event (GtkWidget * widget, GdkEventKey * event) +{ + struct dot *d; + struct sensor_data s; + GdkModifierType state; + int x, y; + + gdk_window_get_pointer (event->window, &x, &y, &state); + + x = ((GdkEventButton*)event)->x / SCALE; + y = ((GdkEventButton*)event)->y / SCALE; + + if(state & GDK_BUTTON1_MASK) { + d = (struct dot *)memb_alloc(&dotsmem); + + if(d != NULL) { + d->x = x; + d->y = y; + d->size = sensor_strength(); + d->intensity = DOT_INTENSITY - 2; + list_push(dots, d); + } + sensor_data_init(&s); + s.pir = 1; + s.button = 0; + s.vib = 0; + ether_send_sensor_data(&s, x, y, sensor_strength()); + } else if(state & GDK_BUTTON2_MASK) { + sensor_data_init(&s); + s.pir = 0; + s.button = 1; + s.vib = 0; + if(marked_node != NULL) { + ether_send_sensor_data(&s, marked_node->x, marked_node->y, 1); + } + } else if(state & GDK_BUTTON3_MASK) { + sensor_data_init(&s); + s.pir = 0; + s.button = 0; + s.vib = 1; + if(marked_node != NULL) { + ether_send_sensor_data(&s, marked_node->x, marked_node->y, 1); + } + } + + return TRUE; +} + +static gint +pointer_motion_event (GtkWidget * widget, GdkEventMotion * event) +{ + struct dot *d; + struct sensor_data s; + GdkModifierType state; + + int x, y; + struct nodes_node *node, *closest; + int nodex, nodey; + unsigned long dist; + int i; + + if(event->is_hint) { + return TRUE; + } + + gdk_window_get_pointer (event->window, &x, &y, &state); + x /= SCALE; + y /= SCALE; + + + if(state & GDK_BUTTON1_MASK) { + d = (struct dot *)memb_alloc(&dotsmem); + + if(d != NULL) { + d->x = x; + d->y = y; + d->size = sensor_strength(); + d->intensity = DOT_INTENSITY - 2; + list_push(dots, d); + } + sensor_data_init(&s); + s.pir = 1; + ether_send_sensor_data(&s, x, y, sensor_strength()); + } else { + + + /* Find the closest node and mark it. */ + closest = NULL; + dist = 0; + for(i = 0; i < nodes_num(); ++i) { + node = nodes_node(i); + nodex = node->x; + nodey = node->y; + + if(closest == NULL || + (x - nodex) * (x - nodex) + (y - nodey) * (y - nodey) < dist) { + dist = (x - nodex) * (x - nodex) + (y - nodey) * (y - nodey); + closest = node; + } + } + marked_node = closest; + } + return TRUE; +} + +static void +quit(void) +{ + gtk_exit(0); +} +/*-----------------------------------------------------------------------------------*/ +static void (* idle)(void); +static gint +idle_callback(gpointer data) +{ + idle(); + return TRUE; +} +/*-----------------------------------------------------------------------------------*/ +static GdkGC * +get_color(unsigned short r, unsigned short g, unsigned short b) +{ + GdkGCValues values; + GdkColor color; + + color.pixel = 0; + color.red = r; + color.green = g; + color.blue = b; + + if(gdk_colormap_alloc_color(gdk_colormap_get_system(), + &color, FALSE, TRUE)) { + } + + values.foreground = color; + + return gdk_gc_new_with_values(drawing_area->window, + &values, + GDK_GC_FOREGROUND); +} +/*-----------------------------------------------------------------------------------*/ +void +display_init(void (* idlefunc)(void), int time, int with_gui) +{ + int i; + GtkWidget *window; + GtkWidget *vbox; + GdkGCValues values; + GdkColor color; + + memb_init(&dotsmem); + list_init(dots); + list_init(tempdots); + + gtk_init(NULL, NULL); + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_title(window, "Contiki simulation display"); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER (window), vbox); + gtk_widget_show(vbox); + + gtk_signal_connect(GTK_OBJECT (window), "destroy", + GTK_SIGNAL_FUNC (quit), NULL); + + /* Create the drawing area */ + + drawing_area = gtk_drawing_area_new(); + gtk_drawing_area_size(GTK_DRAWING_AREA (drawing_area), + DISPLAY_WIDTH, + DISPLAY_HEIGHT); + gtk_box_pack_start(GTK_BOX(vbox), drawing_area, TRUE, TRUE, 0); + + gtk_widget_show(drawing_area); + + /* Signals used to handle backing pixmap */ + + gtk_signal_connect(GTK_OBJECT (drawing_area), "expose_event", + (GtkSignalFunc) expose_event, NULL); + gtk_signal_connect(GTK_OBJECT (drawing_area), "configure_event", + (GtkSignalFunc) configure_event, NULL); + + /* Event signals */ + + gtk_signal_connect(GTK_OBJECT (window), "key_press_event", + (GtkSignalFunc) key_press_event, NULL); + gtk_signal_connect(GTK_OBJECT (window), "key_release_event", + (GtkSignalFunc) key_release_event, NULL); + + gtk_signal_connect(GTK_OBJECT (window), "button_press_event", + (GtkSignalFunc) button_press_event, NULL); + + gtk_signal_connect(GTK_OBJECT (window), "motion_notify_event", + (GtkSignalFunc) pointer_motion_event, NULL); + + gtk_widget_set_events(drawing_area,GDK_KEY_PRESS_MASK + | GDK_KEY_RELEASE_MASK | GDK_BUTTON_PRESS_MASK + | GDK_POINTER_MOTION_MASK); + + /* gtk_window_iconify(window);*/ + if(with_gui) { + gtk_widget_show(window); + window_is_open = with_gui; + } + + + idle = idlefunc; + gtk_timeout_add(time, idle_callback, NULL); + + if(with_gui) { + + for(i = 0; i < DOT_INTENSITY; ++i) { + color.pixel = 0; + color.red = 0; + color.green = ((DOT_INTENSITY + 1) * 0xffff) / (i + 1); + color.blue = ((DOT_INTENSITY + 1) * 0xffff) / (i + 1); + + if(gdk_colormap_alloc_color(gdk_colormap_get_system(), + &color, FALSE, TRUE)) { + } + + values.foreground = color; + + intensity_gcs[i] = gdk_gc_new_with_values(drawing_area->window, &values, + GDK_GC_FOREGROUND); + } + + color.pixel = 0; + color.red = 0xbfff; + color.green = 0xbfff; + color.blue = 0xbfff; + + if(gdk_colormap_alloc_color(gdk_colormap_get_system(), + &color, FALSE, TRUE)) { + } + + values.foreground = color; + + intensity_clusterhead = gdk_gc_new_with_values(drawing_area->window, &values, + GDK_GC_FOREGROUND); + + color.pixel = 0; + color.red = 0xefff; + color.green = 0xefff; + color.blue = 0xefff; + + if(gdk_colormap_alloc_color(gdk_colormap_get_system(), + &color, FALSE, TRUE)) { + } + + values.foreground = color; + + intensity_clusterhead_lightgray = gdk_gc_new_with_values(drawing_area->window, &values, + GDK_GC_FOREGROUND); + + color.pixel = 0; + color.red = 0xffff; + color.green = 0; + color.blue = 0; + + if(gdk_colormap_alloc_color(gdk_colormap_get_system(), + &color, FALSE, TRUE)) { + } + + values.foreground = color; + + intensity_clusterhead_red = gdk_gc_new_with_values(drawing_area->window, &values, + GDK_GC_FOREGROUND); + + + red = get_color(0xffff, 0, 0); + green = get_color(0, 0xffff, 0); + yellow = get_color(0xffff, 0xffff, 0); + black = get_color(0, 0, 0); + white = get_color(0xffff, 0xffff, 0xffff); + } +} +/*-----------------------------------------------------------------------------------*/ +void +display_run(void) +{ + gtk_main(); +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/netsim/display.h b/platform/netsim/display.h new file mode 100644 index 000000000..1e57a1edd --- /dev/null +++ b/platform/netsim/display.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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. + * + * $Id: display.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + * + * Author: Adam Dunkels + * + */ +#ifndef __DISPLAY_H__ +#define __DISPLAY_H__ + + +void display_redraw(void); +void display_init(void (* idle)(void), int time, int with_gui); +void display_run(void); + +void display_tick(void); + +#endif /* __DISPLAY_H__ */ + + + + + diff --git a/platform/netsim/ether.c b/platform/netsim/ether.c new file mode 100644 index 000000000..94d66837a --- /dev/null +++ b/platform/netsim/ether.c @@ -0,0 +1,476 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ether.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +/** + * \file + * This module implements a simple "ether", into which datapackets can + * be injected. The packets are delivered to all nodes that are in + * transmission range. + * + * \author Adam Dunkels + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ether.h" +#include "lib/memb.h" +#include "lib/list.h" +#include "nodes.h" + +#include "sensor.h" + +#include "node.h" +#include "net/uip.h" +#include "net/uip-fw.h" + +#ifndef NULL +#define NULL 0 +#endif /* NULL */ + +MEMB(packets, struct ether_packet, 20000); +LIST(active_packets); + +static u8_t rxbuffer[2000]; +static clock_time_t timer; + +#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN]) + +#define PRINTF(x) printf x + +static int s, sc; + +#define PTYPE_CLOCK 1 +#define PTYPE_DATA 2 +#define PTYPE_SENSOR 3 +#define PTYPE_LEDS 4 + +struct ether_hdr { + int type; + struct sensor_data sensor_data; + clock_time_t clock; + int srcx, srcy; + int srcpid; + int srcid; + int srcnodetype; + int leds; +}; +static int strength; + +static int collisions = 1; + +/*-----------------------------------------------------------------------------------*/ +void +ether_set_collisions(int c) +{ + collisions = c; +} +/*-----------------------------------------------------------------------------------*/ +void +ether_set_strength(int s) +{ + strength = s; +} +/*-----------------------------------------------------------------------------------*/ +int +ether_strength(void) +{ + return strength; +} +/*-----------------------------------------------------------------------------------*/ +void +ether_server_init(void) +{ + struct sockaddr_in sa; + + memb_init(&packets); + list_init(active_packets); + + timer = 0; + + s = socket(AF_INET,SOCK_DGRAM,0); + + if(s < 0) { + perror("ether_server_init: socket"); + } + + bzero((char *)&sa, sizeof(sa)); + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr("127.0.0.1");/*htonl(INADDR_ANY);*/ + + sa.sin_port = htons(ETHER_PORT); + + /* printf("Binding to port %d\n", ETHER_PORT);*/ + + if(bind(s, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + printf("Bind to port %d\n", ETHER_PORT); + perror("bind"); + exit(1); + } + +} +/*-----------------------------------------------------------------------------------*/ +void +ether_client_init(int port) +{ + struct sockaddr_in sa; + + sc = socket(AF_INET,SOCK_DGRAM,0); + + if(sc < 0) { + perror("socket"); + } + + bzero((char *)&sa, sizeof(sa)); + + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr("127.0.0.1");/*htonl(INADDR_ANY);*/ + + sa.sin_port = htons(port); + + /* printf("ether_client_init: binding id %d to port %d\n", id, PORTBASE + id);*/ + if(bind(sc, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + printf("Bind to port %d\n", port); + perror("bind"); + exit(1); + } +} +/*-----------------------------------------------------------------------------------*/ +u16_t +ether_client_poll(void) +{ + int ret, len; + fd_set fdset; + struct timeval tv; + struct ether_hdr *hdr = (struct ether_hdr *)rxbuffer; + + FD_ZERO(&fdset); + FD_SET(sc, &fdset); + + tv.tv_sec = 0; + tv.tv_usec = 1000; + + + ret = select(sc + 1, &fdset, NULL, NULL, &tv); + if(ret == 0) { + return 0; + } + if(FD_ISSET(sc, &fdset)) { + ret = recv(sc, &rxbuffer[0], UIP_BUFSIZE, 0); + if(ret == -1) { + perror("ether_client_poll: read"); + return 0; + } + len = ret; + + memcpy(uip_buf, &rxbuffer[sizeof(struct ether_hdr)], len); + + if(hdr->type == PTYPE_DATA) { + return len - sizeof(struct ether_hdr); + } else if(hdr->type == PTYPE_CLOCK) { + node_set_time(hdr->clock); + } else if(hdr->type == PTYPE_SENSOR) { + int strength = sensor_strength() - + ((hdr->srcx - node_x()) * (hdr->srcx - node_x()) + + (hdr->srcy - node_y()) * (hdr->srcy - node_y())) / sensor_strength(); + /* printf("Dist %d \n", strength);*/ + if(strength > 0) { + sensor_input(&hdr->sensor_data, strength); + } + } + } + return 0; +} +/*-----------------------------------------------------------------------------------*/ +void +ether_server_poll(void) +{ + int ret; + fd_set fdset; + struct timeval tv; + struct ether_hdr *hdr = (struct ether_hdr *)rxbuffer; + /* struct timeval rtime1, rtime2; + struct timespec ts; + struct timezone tz;*/ + + + tv.tv_sec = 0; + tv.tv_usec = 4000; + + + do { + FD_ZERO(&fdset); + FD_SET(s, &fdset); + + ret = select(s + 1, &fdset, NULL, NULL, &tv); + if(ret == 0) { + return; + } + if(FD_ISSET(s, &fdset)) { + ret = recv(s, &rxbuffer[0], UIP_BUFSIZE, 0); + /* printf("ether_poll: read %d bytes from (%d, %d)\n", ret, hdr->srcx, hdr->srcy);*/ + if(ret == -1) { + perror("ether_poll: read"); + return; + } + switch(hdr->type) { + case PTYPE_DATA: + ether_put(rxbuffer, ret, hdr->srcx, hdr->srcy); + break; + case PTYPE_LEDS: + nodes_set_leds(hdr->srcx, hdr->srcy, hdr->leds); + break; + } + } + /* tv.tv_sec = 0; + tv.tv_usec = 1;*/ + + } while(1/*ret > 0*/); +} +/*-----------------------------------------------------------------------------------*/ +void +ether_put(char *data, int len, int x, int y) +{ + struct ether_packet *p; + + /* printf("ether_put: packet len %d at (%d, %d)\n", len, x, y);*/ + + p = (struct ether_packet *)memb_alloc(&packets); + + if(p != NULL) { + if(len > 1500) { + len = 1500; + } + memcpy(p->data, data, len); + p->len = len; + p->x = x; + p->y = y; + list_push(active_packets, p); + + + } +} +/*-----------------------------------------------------------------------------------*/ +static void +send_packet(char *data, int len, int port) +{ + struct sockaddr_in sa; + + bzero((char *)&sa , sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr("127.0.0.1"); + sa.sin_port = htons(port); + + if(sendto(s, data, len, 0, (struct sockaddr *)&sa, sizeof(sa)) == -1) { + perror("ether: send_packet: sendto"); + } +} +/*-----------------------------------------------------------------------------------*/ +void +ether_tick(void) +{ + struct ether_packet *p, *q; + struct ether_hdr *hdr; + int port; + int x, y; + int i; + int interference; + + /* Go through every node and see if there are any packets destined + to them. If two or more packets are sent in the vicinity of the + node, they interfere with each otehr and none reaches the + node. */ + for(i = 0; i < nodes_num(); ++i) { + + x = nodes_node(i)->x; + y = nodes_node(i)->y; + port = nodes_node(i)->port; + + /* Go through all active packets to see if anyone is sent within + range of this node. */ + for(p = list_head(active_packets); p != NULL; p = p->next) { + + /* Update the node type. */ + hdr = (struct ether_hdr *)p->data; + nodes_node(hdr->srcid)->type = hdr->srcnodetype; + + if(!(p->x == x && p->y == y) && /* Don't send packets back to + the sender. */ + (p->x - x) * (p->x - x) + + (p->y - y) * (p->y - y) <= + ether_strength() * ether_strength()) { + + /* This packet was sent in the reception range of this node, + so we check against all other packets to see if there is + more than one packet sent towards this node. If so, we have + interference and the node will not be able to receive any + data. */ + interference = 0; + if(collisions) { + for(q = list_head(active_packets); q != NULL; q = q->next) { + + /* Compute the distance^2 and check against signal strength. */ + if(p != q && + ((q->x - x) * (q->x - x) + + (q->y - y) * (q->y - y) <= + ether_strength() * ether_strength())) { + interference = 1; + break; + } + } + } + + if(!interference) { + send_packet(p->data, p->len, port); + } + } + + + } + } + + /* Remove all packets from the active packets list. */ + for(p = list_head(active_packets); p != NULL; p = list_pop(active_packets)) { + memb_free(&packets, (void *)p); + } + + ++timer; +} +/*-----------------------------------------------------------------------------------*/ +struct ether_packet * +ether_packets(void) +{ + return list_head(active_packets); +} +/*-----------------------------------------------------------------------------------*/ +clock_time_t +ether_time(void) +{ + return timer; +} +/*-----------------------------------------------------------------------------------*/ +static void +node_send_packet(char *data, int len) +{ + struct sockaddr_in sa; + + bzero((char *)&sa , sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr("127.0.0.1"); + sa.sin_port = htons(ETHER_PORT); + + if(sendto(sc, data, len, 0, + (struct sockaddr *)&sa, sizeof(sa)) == -1) { + perror("ether.c node_send_packet: sendto"); + } +} +/*-----------------------------------------------------------------------------------*/ +u8_t +ether_send(char *data, int len) +{ + char tmpbuf[UIP_BUFSIZE + UIP_LLH_LEN + sizeof(struct ether_hdr)]; + struct ether_hdr *hdr = (struct ether_hdr *)tmpbuf; + + + memcpy(&tmpbuf[sizeof(struct ether_hdr)], data, len); + + hdr->srcx = node.x; + hdr->srcy = node.y; + hdr->type = PTYPE_DATA; + hdr->srcnodetype = node.type; + hdr->srcid = node.id; + + + node_send_packet(tmpbuf, len + sizeof(struct ether_hdr)); + + return UIP_FW_OK; +} +/*-----------------------------------------------------------------------------------*/ +void +ether_set_leds(int leds) +{ + struct ether_hdr hdr; + + hdr.srcx = node.x; + hdr.srcy = node.y; + hdr.type = PTYPE_LEDS; + hdr.leds = leds; + hdr.srcnodetype = node.type; + hdr.srcid = node.id; + + node_send_packet((char *)&hdr, sizeof(struct ether_hdr)); + +} +/*-----------------------------------------------------------------------------------*/ +void +ether_send_sensor_data(struct sensor_data *d, int srcx, int srcy, int strength) +{ + int port; + int x, y; + int i; + struct ether_hdr hdr; + + printf("Sensor data at (%d, %d)\n", srcx, srcy); + + for(i = 0; i < nodes_num(); ++i) { + + x = nodes_node(i)->x; + y = nodes_node(i)->y; + port = nodes_node(i)->port; + + if((srcx - x) * (srcx - x) + + (srcy - y) * (srcy - y) <= + strength * strength) { + + hdr.srcx = srcx; + hdr.srcy = srcy; + hdr.type = PTYPE_SENSOR; + hdr.sensor_data = *d; + send_packet((char *)&hdr, sizeof(hdr), port); + } + } + +} +/*-----------------------------------------------------------------------------------*/ diff --git a/platform/netsim/ether.h b/platform/netsim/ether.h new file mode 100644 index 000000000..c93e92e47 --- /dev/null +++ b/platform/netsim/ether.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ether.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#ifndef __ETHER_H__ +#define __ETHER_H__ + +#include "contiki.h" +#include "sensor.h" + +struct ether_packet { + struct ether_packet *next; + char data[1500]; + int len; + int x, y; +}; + + +u8_t ether_send(char *data, int len); +void ether_set_leds(int leds); + + +void ether_poll(void); +void ether_server_init(void); +void ether_client_init(int port); +void ether_tick(void); + + +u16_t ether_client_poll(void); +void ether_server_poll(void); + +void ether_put(char *packet, int len, int src_x, int src_y); + +void ether_send_sensor_data(struct sensor_data *d, int srcx, int srcy, int strength); + + +struct ether_packet * ether_packets(void); + +clock_time_t ether_time(void); + +#define ETHER_PORT 4999 +/*#define ETHER_STRENGTH 24*/ +int ether_strength(void); +void ether_set_strength(int s); + + +void ether_set_collisions(int c); + +#endif /* __ETHER_H__ */ diff --git a/platform/netsim/init.c b/platform/netsim/init.c new file mode 100644 index 000000000..a1039e547 --- /dev/null +++ b/platform/netsim/init.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: init.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#include "init.h" +#include "random.h" + +void +init(void) +{ + int x, y; + + ether_set_strength(21); + + main_add_node(1, 1); + main_add_node(1, 20); + main_add_node(20, 1); + + /*for(x = 1; x < 201; x += 20) { + for(y = 1; y < 201; y += 20) { + main_add_node(x, y); + } + }*/ + + + /* main_add_node(10, 10); + main_add_node(11, 11); + main_add_node(12, 12); + main_add_node(13, 13); + main_add_node(14, 14); + main_add_node(15, 15); + main_add_node(16, 16); */ + + /* for(x = 10; x < 370; x += 20) { + for(y = 10; y < 370; y += 20) { + main_add_node(x + (random_rand() % 20) - 10, + y + (random_rand() % 20) - 10); + } + }*/ + + /* main_add_base(1, 1);*/ +} diff --git a/platform/netsim/init.h b/platform/netsim/init.h new file mode 100644 index 000000000..3eb5161d8 --- /dev/null +++ b/platform/netsim/init.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: init.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#ifndef __INIT_H__ +#define __INIT_H__ + +void init(void); + +void main_add_node(int x, int y); +void main_add_base(int x, int y); + +#endif /* __INIT_H__ */ diff --git a/platform/netsim/loader-arch.h b/platform/netsim/loader-arch.h new file mode 100644 index 000000000..12e662cc7 --- /dev/null +++ b/platform/netsim/loader-arch.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * $Id: loader-arch.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ + +/** + * \file + * Loader definitions for the netsim target + * \author + * Adam Dunkels + */ + +#ifndef __LOADER_ARCH_H__ +#define __LOADER_ARCH_H__ + +#include "loader/dlloader.h" + +#define LOADER_LOAD(name, arg) dlloader_load(name, arg); + +#endif /* __LOADER_ARCH_H__ */ diff --git a/platform/netsim/main.c b/platform/netsim/main.c new file mode 100644 index 000000000..368586d76 --- /dev/null +++ b/platform/netsim/main.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: main.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ + +/** + * \file + * This file implements the main function of the Contiki distributed + * sensor network simulation environment. + * \author Adam Dunkels + * + * When starting, each sensor node is created as its own process. The + * sensor node processes communicates with the starting process using + * named pipes. These pipes carry messages such as data packets and + * configuration and statistics information requests. + */ +#include "contiki-net.h" +#include "display.h" +#include "contiki-main.h" +#include "nodes.h" +#include "ether.h" +#include "node.h" + +#include "net/ethernode.h" + +#include +#include +#include +#include +#include +#include + +static int main_process = 0; + +/*---------------------------------------------------------------------------*/ +static void +sigchld_handler(int sig) +{ + int status; + pid_t pid; + struct nodes_node *node; + if(!main_process) { + return; + } + + pid = waitpid(-1, &status, WNOHANG); + + if(WIFSIGNALED(status) && + WTERMSIG(status) == SIGSEGV) { + node = nodes_find_pid(pid); + if(node == NULL) { + printf("A Contiki node crashed, but it wasn't even started by the system. Something weird is going on!\n"); + } else { + printf("Contiki node at (%d, %d) crashed - Segmentation fault\n", + node->x, node->y); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +idle(void) +{ + int events; + + do { + ether_server_poll(); + display_tick(); + display_redraw(); + ether_tick(); + events = process_run(); + if(events > 0) { + printf("events %d\n", events); + } + } while(events > 0); + +} +/*---------------------------------------------------------------------------*/ +static void +start_node(int x, int y, int b) +{ + pid_t pid; + static unsigned short port = NODES_PORTBASE; + + + pid = fork(); + + if(pid == 0) { + + /* This is the sensor process. */ + main_process = 0; + + srandom(getpid()); + + usleep(1000 * ((random() & 0x0f) << 6) ); + + node_init(port - NODES_PORTBASE, x, y, b); + ethernode_init(port); + + + + contiki_main(b); + + /* NOTREACHED */ + } + /* printf("Adding sensor %d at (%d,%d)\n", pid, x, y);*/ + main_process = 1; + nodes_add(pid, x, y, port); + + + ++port; +} +/*---------------------------------------------------------------------------*/ +void +main_add_node(int x, int y) +{ + start_node(x, y, 0); +} +/*---------------------------------------------------------------------------*/ +void +main_add_base(int x, int y) +{ + start_node(x, y, 1); +} +/*---------------------------------------------------------------------------*/ +int +main(int argc, char **argv) +{ + /* system("ifconfig tap0 inet 192.168.250.1");*/ + /* system("route delete 172.16.0.0/16"); + system("route add 172.16.0.0/16 192.168.250.2");*/ + + nodes_init(); + + atexit(nodes_kill); + + init(); + + ether_server_init(); + +#if 0 + while(1) { + ether_server_poll(); + ether_tick(); + process_run(); + usleep(100); + } +#endif /* 0 */ + if(argc > 1 && strcmp(argv[1], "-q") == 0) { + display_init(idle, 50, 0); + } else { + display_init(idle, 50, 1); + } + display_redraw(); + + signal(SIGCHLD, sigchld_handler); + + + display_run(); + + return 0; + + argv = argv; + argc = argc; + +} +/*-----------------------------------------------------------------------------------*/ +char *arg_alloc(char size) {return NULL;} +void arg_init(void) {} +void arg_free(char *arg) {} +/*-----------------------------------------------------------------------------------*/ + +char *shell_prompt_text = "sensor-router> "; + +/*-----------------------------------------------------------------------------------*/ +#include + +static signed long drift = 0; + +void +clock_delay(unsigned int num) +{ + usleep(num * 100); +} + +void +clock_set_time(clock_time_t time, clock_time_t ftime) +{ + drift = time - node_time(); +} + +clock_time_t +clock_time(void) +{ + return drift + node_time(); +} +/*-----------------------------------------------------------------------------------*/ +unsigned long +clock_seconds(void) +{ + return node_seconds(); +} +/*-----------------------------------------------------------------------------------*/ +void +uip_log(char *m) +{ + u16_t addr[2]; + uip_gethostaddr(addr); + + printf("uIP log at %d.%d.%d.%d: %s\n", + uip_ipaddr1(addr), + uip_ipaddr2(addr), + uip_ipaddr3(addr), + uip_ipaddr4(addr), + m); + fflush(NULL); +} +void +configurator_send_config(u16_t *addr, unsigned long seconds) +{ + printf("Configurator: address %d.%d.%d.%d, seconds %lu\n", + uip_ipaddr1(addr), + uip_ipaddr2(addr), + uip_ipaddr3(addr), + uip_ipaddr4(addr), + seconds); +} + + +void +system_log(char *m) +{ + printf("%s", m); +} +/*void tr1001_drv_set_slip_dump(int c) +{ + +}*/ diff --git a/platform/netsim/net/ethernode-drv.c b/platform/netsim/net/ethernode-drv.c new file mode 100644 index 000000000..50280d701 --- /dev/null +++ b/platform/netsim/net/ethernode-drv.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ethernode-drv.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + +#include "contiki.h" + +#include "ethernode.h" + +#include "net/uip-fw.h" +#include "net/hc.h" +#include "net/tapdev.h" + +PROCESS(ethernode_drv_process, "Ethernode driver"); + +enum { NULLEVENT }; +/*---------------------------------------------------------------------------*/ +u8_t +ethernode_drv_send(void) +{ + uip_len = hc_compress(); + /* uip_len = hc_inflate();*/ + + return ethernode_send(); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ethernode_drv_process, ev, data) +{ +/* static int drop = 0; */ + PROCESS_BEGIN(); + + while(1) { + process_poll(ðernode_drv_process); + PROCESS_WAIT_EVENT(); + + /* Poll Ethernet device to see if there is a frame avaliable. */ + uip_len = ethernode_poll(); + + if(uip_len > 0) { + + /* if(drop++ >= (random_rand() % 10)) { + printf("Bropp\n"); + drop = 0; + } else*/ { + + uip_len = hc_inflate(); + + tapdev_send_raw(); + /* if(uip_fw_forward() == UIP_FW_LOCAL)*/ { + /* A frame was avaliable (and is now read into the uip_buf), so + we process it. */ + tcpip_input(); + } + } + } + } + PROCESS_END(); + +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/net/ethernode-drv.h b/platform/netsim/net/ethernode-drv.h new file mode 100644 index 000000000..2669627bf --- /dev/null +++ b/platform/netsim/net/ethernode-drv.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ethernode-drv.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ +#ifndef __ETHERNODE_DRV_H__ +#define __ETHERNODE_DRV_H__ + +#include "contiki.h" + +PROCESS_NAME(ethernode_drv_process); + +u8_t ethernode_drv_send(void); + +u8_t ethernode_drv_send(void); + +#endif /* __ETHERNODE_DRV_H__ */ diff --git a/platform/netsim/net/ethernode.c b/platform/netsim/net/ethernode.c new file mode 100644 index 000000000..18769df18 --- /dev/null +++ b/platform/netsim/net/ethernode.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ethernode.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ +/** + * \file + * uIP virtual network interface using UDP tunnels. + * \author Adam Dunkels + * + */ + +#include "net/ethernode.h" +#include "net/uip_arch.h" +#include "net/uip-fw.h" +#include "ether.h" + +#include "node.h" + +#include "lib/random.h" + +#include +#include + +#define BUF ((uip_tcpip_hdr *)&uip_buf[HDR_LEN]) + +/*#define PRINTF(x)*/ +#define PRINTF(x) printf x; fflush(NULL) + +struct { + u8_t id; + int timer; + u8_t seqno; +} state; + +#define TYPE_DATA 1 +#define TYPE_ACK 2 + +struct hdr { + u8_t type; + u8_t src; + u8_t dest; + u8_t seqno; +}; + + +#define HDR_LEN UIP_LLH_LEN + +#define ID_BROADCAST 0x80 +/*-------------------------------------------------------------------------------*/ +static u8_t +do_send(u8_t type, u8_t dest, struct hdr *hdr, int len) +{ + + hdr->type = type; + hdr->src = state.id; + + hdr->dest = dest; + + hdr->seqno = state.seqno; + + ++state.seqno; + + return ether_send((char *)hdr, len); + +} +/*-------------------------------------------------------------------------------*/ +/** + * Initialize the virtual UDP tunnel network interface. + * + * \param sid The ID number of this node. + * + */ +/*-------------------------------------------------------------------------------*/ +void +ethernode_init(int port) +{ + ether_client_init(port); + + do { + state.id = random_rand() & 0x7f; + } while(state.id == ID_BROADCAST); + + state.seqno = 0; +} +/*-------------------------------------------------------------------------------*/ +/** + * Poll the network device to see if a packet has arrived. + * + * \return The length of the incoming packet, or zero if no packet was + * found. + */ +/*-------------------------------------------------------------------------------*/ +int +ethernode_poll(void) +{ + int len; + struct hdr *hdr = (struct hdr *)uip_buf; + + len = ether_client_poll(); + if(len == 0) { + return 0; + } + + /* printf("ethernode_poll: received data packet with len %d\n", len);*/ + + switch(hdr->type) { + case TYPE_DATA: + if(hdr->dest == state.id || + hdr->dest == ID_BROADCAST) { + return len - HDR_LEN; + } + break; + case TYPE_ACK: + printf("<%d>: Received ack packet from %d\n", state.id, hdr->src); + break; + default: + printf("<%d>: Received unknown packet type %d from %d\n", state.id, hdr->type, hdr->src); + break; + } + + return 0; + +} +/*-------------------------------------------------------------------------------*/ +/** + * Send a packet from the uip_buf buffer over the UDP tunnel. + * + * + * \retval UIP_FW_TOOLARGE A transmission of packet that was too large was attempted. + * + * \retval UIP_FW_DROPPED The packet is known to be dropped. + * + * \retval UIP_FW_OK The packet was transmitted. + */ +/*-------------------------------------------------------------------------------*/ +u8_t +ethernode_send(void) +{ + int len; + static char tmpbuf[UIP_BUFSIZE + HDR_LEN]; + struct hdr *hdr = (struct hdr *)tmpbuf; + u8_t dest; + + if(uip_len > UIP_BUFSIZE) { + PRINTF(("Ethernode_send: too large uip_len %d\n", uip_len)); + return UIP_FW_TOOLARGE; + } + + memcpy(&tmpbuf[HDR_LEN], &uip_buf[HDR_LEN], uip_len); + len = uip_len + HDR_LEN; + + dest = ID_BROADCAST; + + usleep(800 * (random_rand() % 1000)); + + do_send(TYPE_DATA, dest, hdr, len); + + return UIP_FW_OK; +} +/*-------------------------------------------------------------------------------*/ diff --git a/platform/netsim/net/ethernode.h b/platform/netsim/net/ethernode.h new file mode 100644 index 000000000..c5fc201fd --- /dev/null +++ b/platform/netsim/net/ethernode.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: ethernode.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ +#ifndef __ETHERNODE_H__ +#define __ETHERNODE_H__ + +#include "contiki.h" + +void ethernode_init(int port); +int ethernode_poll(void); +u8_t ethernode_send(void); + +void ethernode_periodic(void); + +#endif /* __ETHERNODE_H__ */ diff --git a/platform/netsim/net/tapdev-drv.c b/platform/netsim/net/tapdev-drv.c new file mode 100644 index 000000000..a83a51be0 --- /dev/null +++ b/platform/netsim/net/tapdev-drv.c @@ -0,0 +1,58 @@ + +#include "net/tapdev.h" +#include "net/uip_arp.h" + +static struct uip_eth_addr addr = + {{0x08, 0x12, 0x23, 0x89, 0xa3, 0x94}}; +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +PROCESS(tapdev_drv_process, "TAP driver"); + +void tapdev_drv_request_poll(void); + +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(tapdev_drv_process, ev, data) + +{ + PROCESS_BEGIN(); + + tapdev_init(); + uip_setethaddr(addr); + tapdev_drv_request_poll(); + + while(1) { + PROCESS_WAIT_EVENT(); + tapdev_drv_request_poll(); + + tapdev_drv_request_poll(); + uip_len = tapdev_poll(); + + if(uip_len > 0) { + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + /* uip_input();*/ + tcpip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + tapdev_send_raw(); + } + } + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +void +tapdev_drv_request_poll(void) +{ + process_poll(&tapdev_drv_process); +} diff --git a/platform/netsim/net/tapdev-drv.h b/platform/netsim/net/tapdev-drv.h new file mode 100644 index 000000000..d70387a53 --- /dev/null +++ b/platform/netsim/net/tapdev-drv.h @@ -0,0 +1,8 @@ +#ifndef __TAPDEV_DRV_H__ +#define __TAPDEV_DRV_H__ + +#include "contiki.h" + +PROCESS_NAME(tapdev_drv_process); + +#endif /* __TAPDEV_DRV_H__ */ diff --git a/platform/netsim/net/tapdev-service.c b/platform/netsim/net/tapdev-service.c new file mode 100644 index 000000000..b1c8b6710 --- /dev/null +++ b/platform/netsim/net/tapdev-service.c @@ -0,0 +1,63 @@ + +#include "net/packet-service.h" +#include "net/tapdev.h" + +#include "net/uip_arp.h" + +/* static struct uip_eth_addr addr = */ +/* {0x08, 0x12, 0x23, 0x89, 0xa3, 0x94}; */ + +SERVICE(tapdev_service, packet_service, { tapdev_send }); + +PROCESS(tapdev_service_process, "TAP driver"); + +/*---------------------------------------------------------------------------*/ +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) +static void +pollhandler(void) +{ + /* tapdev_service_request_poll();*/ + process_poll(&tapdev_service_process); + uip_len = tapdev_poll(); + + if(uip_len > 0) { + if(BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_len -= sizeof(struct uip_eth_hdr); + /* uip_input();*/ + tcpip_input(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + } else if(BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + /* If the above function invocation resulted in data that + should be sent out on the network, the global variable + uip_len is set to a value > 0. */ + if(uip_len > 0) { + tapdev_send_raw(); + } + } + } +} +/*---------------------------------------------------------------------------*/ + +PROCESS_THREAD(tapdev_service_process, ev, data) +{ + PROCESS_BEGIN(); + + tapdev_init(); + + SERVICE_REGISTER(tapdev_service); + + process_poll(&tapdev_service_process); + + while(1) { + PROCESS_YIELD(); + if(ev == PROCESS_EVENT_POLL) { + pollhandler(); + } + } + + PROCESS_END(); +} diff --git a/platform/netsim/net/tapdev-service.h b/platform/netsim/net/tapdev-service.h new file mode 100644 index 000000000..9089097a8 --- /dev/null +++ b/platform/netsim/net/tapdev-service.h @@ -0,0 +1,8 @@ +#ifndef __TAPDEV_SERVICE_H__ +#define __TAPDEV_SERVICE_H__ + +#include "contiki.h" + +PROCESS_NAME(tapdev_service_process); + +#endif /* __TAPDEV_SERVICE_H__ */ diff --git a/platform/netsim/net/tapdev.c b/platform/netsim/net/tapdev.c new file mode 100644 index 000000000..c0ddd9a08 --- /dev/null +++ b/platform/netsim/net/tapdev.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Adam Dunkels + * + * $Id: tapdev.c,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef linux +#include +#include +#include +#define DEVTAP "/dev/net/tun" +#else /* linux */ +#define DEVTAP "/dev/tap0" +#endif /* linux */ + +#include "net/uip.h" +#include "net/uip_arp.h" +#include "net/uip-fw.h" +#include "net/tapdev.h" + +#include "net/tcpip.h" + +#define DROP 0 + +static int drop = 0; +static int fd; + +static unsigned long lasttime; +static struct timezone tz; + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +static void do_send(void); + +u16_t +tapdev_poll(void) +{ + fd_set fdset; + struct timeval tv; + int ret; + + tv.tv_sec = 0; + tv.tv_usec = 0; + + FD_ZERO(&fdset); + if(fd > 0) { + FD_SET(fd, &fdset); + } + + ret = select(fd + 1, &fdset, NULL, NULL, &tv); + if(ret == 0) { + return 0; + } + ret = read(fd, uip_buf, UIP_BUFSIZE); + if(ret == -1) { + perror("tapdev_poll: read"); + } + return ret; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_init(void) +{ + char buf[1024]; + + fd = open(DEVTAP, O_RDWR); + if(fd == -1) { + perror("tapdev: tapdev_init: open"); + return; + } + +#ifdef linux + { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP|IFF_NO_PI; + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { + perror(buf); + exit(1); + } + } +#endif /* Linux */ + + snprintf(buf, sizeof(buf), "ifconfig tap0 inet 192.168.2.1"); + system(buf); + printf("%s\n", buf); + + lasttime = 0; + + /* gdk_input_add(fd, GDK_INPUT_READ, + read_callback, NULL);*/ + +} +/*---------------------------------------------------------------------------*/ +static void +do_send(void) +{ + int ret; + char tmpbuf[UIP_BUFSIZE]; + int i; + + if(fd <= 0) { + return; + } + + /* printf("tapdev_send: sending %d bytes\n", size);*/ + /* check_checksum(uip_buf, size);*/ +#if DROP + drop++; + if(drop % 8 == 7) { + printf("Dropped an output packet!\n"); + return; + } +#endif /* DROP */ + + for(i = 0; i < 40 + UIP_LLH_LEN; i++) { + tmpbuf[i] = uip_buf[i]; + } + + + for(; i < uip_len; i++) { + tmpbuf[i] = ((char *)uip_appdata)[i - 40 - UIP_LLH_LEN]; + } + + ret = write(fd, tmpbuf, uip_len); + + if(ret == -1) { + perror("tap_dev: tapdev_send: writev"); + exit(1); + } +} +/*---------------------------------------------------------------------------*/ +u8_t +tapdev_send(void) +{ + uip_arp_out(); + + do_send(); + uip_len -= UIP_LLH_LEN; + return UIP_FW_OK; +} +/*---------------------------------------------------------------------------*/ +void +tapdev_send_raw(void) +{ + do_send(); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/net/tapdev.h b/platform/netsim/net/tapdev.h new file mode 100644 index 000000000..afc2f2fd3 --- /dev/null +++ b/platform/netsim/net/tapdev.h @@ -0,0 +1,47 @@ +/* + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Adam Dunkels. + * 4. 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: tapdev.h,v 1.1 2006/06/17 22:41:36 adamdunkels Exp $ + * + */ +#ifndef __TAPDEV_H__ +#define __TAPDEV_H__ + +#include "contiki.h" + +void tapdev_init(void); +u16_t tapdev_poll(void); +u8_t tapdev_send(void); +void tapdev_send_raw(void); + +#endif /* __TAPDEV_H__ */ diff --git a/platform/netsim/node-id.h b/platform/netsim/node-id.h new file mode 100644 index 000000000..bd0bdb2df --- /dev/null +++ b/platform/netsim/node-id.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: node-id.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ + +#ifndef __NODE_ID_H__ +#define __NODE_ID_H__ + +#include "node.h" + +#define node_id (node.id) + +#endif /* __NODE_ID_H__ */ diff --git a/platform/netsim/node.c b/platform/netsim/node.c new file mode 100644 index 000000000..7870ec062 --- /dev/null +++ b/platform/netsim/node.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: node.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#include "node.h" +#include "contiki.h" +#include "net/uip.h" +#include +#include + +static clock_time_t drift, timer; + +struct node node; + +static int fd; + +static void init_node_log(void); + +/*------------------------------------------------------------------------------*/ +void +node_init(int id, int posx, int posy, int b) +{ + u16_t addr[2]; + + node.id = id; + node.x = posx; + node.y = posy; + node.type = NODE_TYPE_NORMAL; + + if(b) { + uip_ipaddr(addr, 192,168,250,2); + } else { + uip_ipaddr(addr, 10,10,posx,posy); + } + uip_sethostaddr(addr); + + drift = random() % 9572627217; + + init_node_log(); +} +/*------------------------------------------------------------------------------*/ +#include + +clock_time_t +node_time(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec * 1000 + tv.tv_usec / 1000 + drift; +} +/*------------------------------------------------------------------------------*/ +unsigned long +node_seconds(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return tv.tv_sec; +} +/*------------------------------------------------------------------------------*/ +void +node_set_time(clock_time_t time) +{ + timer = time; +} +/*------------------------------------------------------------------------------*/ +int +node_x(void) +{ + return node.x; +} +/*------------------------------------------------------------------------------*/ +int +node_y(void) +{ + return node.y; +} +/*------------------------------------------------------------------------------*/ +#include +#include +#include +#include + +static void +init_node_log(void) +{ + fd = open("log", O_CREAT | O_WRONLY | O_APPEND, 0666); +} + +void +node_log(const char *fmt, ...) +{ + va_list ap; + char buf[4096]; + int len; + + len = snprintf(buf, sizeof(buf), "Node %d (%d, %d): ", node.id, node.x, node.y); + va_start(ap, fmt); + vsnprintf(&buf[len], sizeof(buf) - len, fmt, ap); + write(fd, buf, strlen(buf)); + va_end(ap); +} +/*------------------------------------------------------------------------------*/ diff --git a/platform/netsim/node.h b/platform/netsim/node.h new file mode 100644 index 000000000..1f58f5f85 --- /dev/null +++ b/platform/netsim/node.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: node.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#ifndef __NODE_H__ +#define __NODE_H__ + +#include "sys/clock.h" + +struct node { + int x, y; + +#define NODE_TYPE_NORMAL 1 +#define NODE_TYPE_CLUSTERHEAD 2 + int type; + + /* The node ID is used only during simulation. */ + int id; +}; + +extern struct node node; + +void node_init(int id, int x, int y, int b); +void node_set_time(clock_time_t time); +clock_time_t node_time(void); +unsigned long node_seconds(void); + +int node_x(void); +int node_y(void); + +void node_log(const char *fmt, ...); + +#endif /* __NODE_H__ */ diff --git a/platform/netsim/nodes.c b/platform/netsim/nodes.c new file mode 100644 index 000000000..8fe40f0d8 --- /dev/null +++ b/platform/netsim/nodes.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: nodes.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#include +#include +#include + +#include "nodes.h" + + +static int numnodes; + +static struct nodes_node nodes[2000]; + +/*---------------------------------------------------------------------------*/ +void +nodes_init(void) +{ + numnodes = 0; +} +/*---------------------------------------------------------------------------*/ +void +nodes_add(int pid, int x, int y, int port) +{ + nodes[numnodes].pid = pid; + nodes[numnodes].x = x; + nodes[numnodes].y = y; + nodes[numnodes].port = port; + nodes[numnodes].leds = 0; + ++numnodes; +} +/*---------------------------------------------------------------------------*/ +void +nodes_kill(void) +{ + int i; + for(i = 0; i < numnodes; ++i) { + kill(nodes[i].pid, SIGTERM); + } +} +/*---------------------------------------------------------------------------*/ +int +nodes_num(void) +{ + return numnodes; +} +/*---------------------------------------------------------------------------*/ +struct nodes_node * +nodes_node(int num) +{ + if(num > numnodes) { + fprintf(stderr, "nodes_node: request for %d > %d\n", num, numnodes); + abort(); + } + return &nodes[num]; +} +/*---------------------------------------------------------------------------*/ +void +nodes_set_leds(int x, int y, int leds) +{ + int i; + + for(i = numnodes; i >= 0; --i) { + if(nodes[i].x == x && nodes[i].y == y) { + nodes[i].leds = leds; + return; + } + } +} +/*---------------------------------------------------------------------------*/ +struct nodes_node * +nodes_find_pid(pid_t pid) +{ + int i; + printf("Nofodes %d\n", numnodes); + for(i = 0; i < numnodes; ++i) { + printf("%d == %d\n", pid, nodes[i].pid); fflush(NULL); + if(nodes[i].pid == pid) { + return &nodes[i]; + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/nodes.h b/platform/netsim/nodes.h new file mode 100644 index 000000000..227df5d20 --- /dev/null +++ b/platform/netsim/nodes.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: nodes.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#ifndef __NODES_H__ +#define __NODES_H__ + +#include + + +void nodes_init(void); +void nodes_add(int pid, int x, int y, int port); +void nodes_kill(void); +void nodes_set_leds(int x, int y, int leds); + +int nodes_num(void); +struct nodes_node *nodes_node(int num); +struct nodes_node *nodes_find_pid(pid_t pid); + +struct nodes_node { + int pid; + int x, y; + int port; + int type; + int leds; +}; + +#define NODES_PORTBASE 5000 + +#endif /* __NODES_H__ */ diff --git a/platform/netsim/random.c b/platform/netsim/random.c new file mode 100644 index 000000000..22a50f925 --- /dev/null +++ b/platform/netsim/random.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: random.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +/*----------------------------------------------------------------------------*/ +/* + * \file + * Stubs for pseudo-random generator. + * \author Adam Dunkels + * + * + */ +/*----------------------------------------------------------------------------*/ + +#include + +/*----------------------------------------------------------------------------*/ +void +random_init(void) +{ + srandom(getpid()); +} +/*----------------------------------------------------------------------------*/ +unsigned short +random_rand(void) +{ + return (random() >> 4) & 0xffff; +} +/*----------------------------------------------------------------------------*/ diff --git a/platform/netsim/random.h b/platform/netsim/random.h new file mode 100644 index 000000000..c4bb9bf9f --- /dev/null +++ b/platform/netsim/random.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: random.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#ifndef __RANDOM_H__ +#define __RANDOM_H__ + +/* + * Initialize the pseudo-random generator. + * + */ +void random_init(void); + +/* + * Calculate a pseudo random number between 0 and 65535. + * + * \return A pseudo-random number between 0 and 65535. + */ +unsigned short random_rand(void); + + + +#endif /* __RANDOM_H__ */ diff --git a/platform/netsim/sensor.c b/platform/netsim/sensor.c new file mode 100644 index 000000000..1318ad092 --- /dev/null +++ b/platform/netsim/sensor.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: sensor.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#include "sensor.h" +#include "dev/pir-sensor.h" +#include "dev/button-sensor.h" +#include "dev/vib-sensor.h" + +static int strength = 20; + +static int pir, button, vib; + +/*---------------------------------------------------------------------------*/ +void +sensor_init(void) +{ + +} +/*---------------------------------------------------------------------------*/ +int +sensor_strength(void) +{ + return strength; +} +/*---------------------------------------------------------------------------*/ +void +sensor_set_strength(int s) +{ + strength = s; +} +/*---------------------------------------------------------------------------*/ +void +sensor_input(struct sensor_data *d, int strength) +{ + pir += d->pir; + if(d->pir) { + pir_sensor_changed(strength); + } + if(d->button) { + button_press(); + } + button += d->button; + /* if(button) { + printf("Button %d %d\n", button, d->button); + }*/ + if(d->vib) { + vib_sensor_changed(); + } + vib += d->vib; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/netsim/sensor.h b/platform/netsim/sensor.h new file mode 100644 index 000000000..f506fb868 --- /dev/null +++ b/platform/netsim/sensor.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2004, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author: Adam Dunkels + * + * $Id: sensor.h,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#ifndef __SENSOR_H__ +#define __SENSOR_H__ + +#include + +struct sensor_data { + int pir; + int button; + int vib; +}; + +void sensor_input(struct sensor_data *d, int strength); +void sensor_init(void); +int sensor_poll(void); + +int sensor_strength(void); +void sensor_set_strength(int s); + +#define sensor_data_init(s) memset(s, 0, sizeof(struct sensor_data)) + +#endif /* __SENSOR_H__ */ diff --git a/platform/netsim/symbols.c b/platform/netsim/symbols.c new file mode 100644 index 000000000..c4a2baf0d --- /dev/null +++ b/platform/netsim/symbols.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2005, Swedish Institute of Computer Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * @(#)$Id: symbols.c,v 1.1 2006/06/17 22:41:35 adamdunkels Exp $ + */ +#include "loader/symbols.h" +const struct symbols symbols[] = { +{(void *)0, 0} }; diff --git a/tools/avr-make-symbols b/tools/avr-make-symbols new file mode 100755 index 000000000..d51e41307 --- /dev/null +++ b/tools/avr-make-symbols @@ -0,0 +1,8 @@ +#!/bin/sh +echo \#include '"symbols.h"' +echo \#include '' +avr-nm $* | perl -ne 'print ".global $2\n$2 = 0x$1\n" if(/([0-9a-f]+) [ABDRST] (.+)$/);' | grep -v ^_ | grep -v _reset_vector | grep = | perl -ne 'print "static const prog_char s_$1 [] = \"$1\";\n" if(/(\w+) = (\w+)/)' | sort + +echo "PROGMEM const struct symbols symbols[] = {" +avr-nm $* | perl -ne 'print ".global $2\n$2 = 0x$1\n" if(/([0-9a-f]+) [ABDRST] (.+)$/);' | grep -v ^_ | grep -v _reset_vector | grep = | perl -ne 'print "{s_$1, $2},\n" if(/(\w+) = (\w+)/)' | sort +echo "{(void *)0, 0} };" \ No newline at end of file diff --git a/tools/cc65-make-labels b/tools/cc65-make-labels new file mode 100755 index 000000000..6dd73e680 --- /dev/null +++ b/tools/cc65-make-labels @@ -0,0 +1,6 @@ +#!/bin/sh + + +egrep -v 'ZP|BSS' contiki-labels | perl -n -e 'if(/^al 0000(.+) \.([^@]+)\n/){if($l{$2} eq ""){$l{$2}=$1;print ".exportzp $2\n$2=\$$1\n";}} elsif(/^al 00(.+) \.([^@]+)\n/){if($l{$2} eq ""){$l{$2}=$1;print ".export $2\n$2=\$$1\n";}}' > contiki-labels.s + +echo '.segment "EXTZP": zeropage' >> contiki-labels.s \ No newline at end of file diff --git a/tools/makefsdata b/tools/makefsdata new file mode 100755 index 000000000..b2109abdb --- /dev/null +++ b/tools/makefsdata @@ -0,0 +1,78 @@ +#!/usr/bin/perl + +open(OUTPUT, "> httpd-fsdata.c"); + +chdir("httpd-fs"); + +opendir(DIR, "."); +@files = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); +closedir(DIR); + +foreach $file (@files) { + + if(-d $file && $file !~ /^\./) { + print "Processing directory $file\n"; + opendir(DIR, $file); + @newfiles = grep { !/^\./ && !/(CVS|~)/ } readdir(DIR); + closedir(DIR); + printf "Adding files @newfiles\n"; + @files = (@files, map { $_ = "$file/$_" } @newfiles); + next; + } +} + +foreach $file (@files) { + if(-f $file) { + + print "Adding file $file\n"; + + open(FILE, $file) || die "Could not open file $file\n"; + + $file =~ s-^-/-; + $fvar = $file; + $fvar =~ s-/-_-g; + $fvar =~ s-\.-_-g; + # for AVR, add PROGMEM here + print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); + print(OUTPUT "\t/* $file */\n\t"); + for($j = 0; $j < length($file); $j++) { + printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); + } + printf(OUTPUT "0,\n"); + + + $i = 0; + while(read(FILE, $data, 1)) { + if($i == 0) { + print(OUTPUT "\t"); + } + printf(OUTPUT "%#02x, ", unpack("C", $data)); + $i++; + if($i == 10) { + print(OUTPUT "\n"); + $i = 0; + } + } + print(OUTPUT "0};\n\n"); + close(FILE); + push(@fvars, $fvar); + push(@pfiles, $file); + } +} + +for($i = 0; $i < @fvars; $i++) { + $file = $pfiles[$i]; + $fvar = $fvars[$i]; + + if($i == 0) { + $prevfile = "NULL"; + } else { + $prevfile = "file" . $fvars[$i - 1]; + } + print(OUTPUT "const struct httpd_fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); + print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); + print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); +} + +print(OUTPUT "#define HTTPD_FS_ROOT file$fvars[$i - 1]\n\n"); +print(OUTPUT "#define HTTPD_FS_NUMFILES $i\n"); diff --git a/tools/msp430-make-symbols b/tools/msp430-make-symbols new file mode 100755 index 000000000..1c39c6cca --- /dev/null +++ b/tools/msp430-make-symbols @@ -0,0 +1,13 @@ +#!/bin/sh +echo \#include '"loader/symbols.h"' +echo "const struct symbols symbols[] = {" + +if [ -f $* ] ; then + msp430-nm $* | perl -ne 'print ".global $2\n$2 = 0x$1\n" if(/([0-9a-f]+) [ABDRST] (.+)$/);' | grep -v _reset_vector | grep = | perl -ne 'print "{\"$1\", (char *)$2},\n" if(/(\w+) = (\w+)/)' | sort +# msp430-nm $* | perl -ne 'print ".global $2\n$2 = 0x$1\n" if(/([0-9a-f]+) [ABDRST] (.+)$/);' | grep -v ^_ | grep -v _reset_vector | grep = | perl -ne 'print "{\"$1\", (char *)$2},\n" if(/(\w+) = (\w+)/)' | sort + status=$? +fi + +echo "{(void *)0, 0} };" + +exit $status