Stefan Schuermans commited on 2012-05-21 12:27:06
Showing 67 changed files, with 0 additions and 7288 deletions.
... | ... |
@@ -1,10 +0,0 @@ |
1 |
-flaneth - flash and ethernet - dartboard mod |
|
2 |
-Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
3 |
-Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
4 |
-a BlinkenArea project - http://www.blinkenarea.org/ |
|
5 |
- |
|
6 |
-0.1 2008-11-09 |
|
7 |
--------------- |
|
8 |
-first version |
|
9 |
-based on flaneth 0.2 |
|
10 |
- |
... | ... |
@@ -1,447 +0,0 @@ |
1 |
-# flaneth - flash and ethernet - dartboard mod |
|
2 |
-# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
3 |
-# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
4 |
-# a BlinkenArea project - http://www.blinkenarea.org/ |
|
5 |
- |
|
6 |
-include Makefile.conf |
|
7 |
- |
|
8 |
-# WinAVR Sample makefile written by Eric B. Weddington, J�rg Wunsch, et al. |
|
9 |
-# Released to the Public Domain |
|
10 |
-# Please read the make user manual! |
|
11 |
-# |
|
12 |
-# Additional material for this makefile was submitted by: |
|
13 |
-# Tim Henigan |
|
14 |
-# Peter Fleury |
|
15 |
-# Reiner Patommel |
|
16 |
-# Sander Pool |
|
17 |
-# Frederik Rouleau |
|
18 |
-# Markus Pfaff |
|
19 |
-# Stefan Schuermans |
|
20 |
-# |
|
21 |
-# On command line: |
|
22 |
-# |
|
23 |
-# make all = Make software. |
|
24 |
-# |
|
25 |
-# make clean = Clean out built project files. |
|
26 |
-# |
|
27 |
-# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). |
|
28 |
-# |
|
29 |
-# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio |
|
30 |
-# 4.07 or greater). |
|
31 |
-# |
|
32 |
-# make program_fuses = Set the fuse bits of the device, using avrdude. Please |
|
33 |
-# customize the avrdude settings below first! |
|
34 |
-# |
|
35 |
-# make program = Download the hex file to the device, using avrdude. Please |
|
36 |
-# customize the avrdude settings below first! |
|
37 |
-# |
|
38 |
-# make filename.s = Just compile filename.c into the assembler code only |
|
39 |
-# |
|
40 |
-# To rebuild project do "make clean" then "make all". |
|
41 |
-# |
|
42 |
- |
|
43 |
- |
|
44 |
-# MCU name |
|
45 |
-MCU = atmega128 |
|
46 |
- |
|
47 |
-# Output format. (can be srec, ihex, binary) |
|
48 |
-FORMAT = ihex |
|
49 |
- |
|
50 |
-# Target file name (without extension). |
|
51 |
-TARGET = main |
|
52 |
- |
|
53 |
-# Optimization level, can be [0, 1, 2, 3, s]. 0 turns off optimization. |
|
54 |
-# (Note: 3 is not always the best optimization level. See avr-libc FAQ.) |
|
55 |
-OPT = s |
|
56 |
- |
|
57 |
- |
|
58 |
-# List C source files here. (C dependencies are automatically generated.) |
|
59 |
-SRC = $(TARGET).c |
|
60 |
- |
|
61 |
-# If there is more than one source file, append them above, or modify and |
|
62 |
-# uncomment the following: |
|
63 |
-SRC += arp.c bus.c cf.c checksum.c config.c dhcp.c dart.c \ |
|
64 |
- eeprom.c ethernet.c http.c icmp.c ip.c random.c \ |
|
65 |
- rtl8019.c status.c tcp.c timing.c uart.c udp.c \ |
|
66 |
- xtea.c |
|
67 |
- |
|
68 |
-# You can also wrap lines by appending a backslash to the end of the line: |
|
69 |
-#SRC += baz.c \ |
|
70 |
-#xyzzy.c |
|
71 |
- |
|
72 |
- |
|
73 |
- |
|
74 |
-# List Assembler source files here. |
|
75 |
-# Make them always end in a capital .S. Files ending in a lowercase .s |
|
76 |
-# will not be considered source files but generated files (assembler |
|
77 |
-# output from the compiler), and will be deleted upon "make clean"! |
|
78 |
-# Even though the DOS/Win* filesystem matches both .s and .S the same, |
|
79 |
-# it will preserve the spelling of the filenames, and gcc itself does |
|
80 |
-# care about how the name is spelled on its command-line. |
|
81 |
-ASRC = |
|
82 |
- |
|
83 |
- |
|
84 |
-# List any extra directories to look for include files here. |
|
85 |
-# Each directory must be seperated by a space. |
|
86 |
-EXTRAINCDIRS = |
|
87 |
- |
|
88 |
- |
|
89 |
-# Optional compiler flags. |
|
90 |
-# -g: generate debugging information (for GDB, or for COFF conversion) |
|
91 |
-# -O*: optimization level |
|
92 |
-# -f...: tuning, see gcc manual and avr-libc documentation |
|
93 |
-# -Wall...: warning level |
|
94 |
-# -Wa,...: tell GCC to pass this to the assembler. |
|
95 |
-# -ahlms: create assembler listing |
|
96 |
-CFLAGS = -g -O$(OPT) \ |
|
97 |
--funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums \ |
|
98 |
--Wall -Wstrict-prototypes \ |
|
99 |
--Wa,-adhlns=$(<:.c=.lst) \ |
|
100 |
-$(patsubst %,-I%,$(EXTRAINCDIRS)) \ |
|
101 |
-$(DBG_FLAGS) |
|
102 |
- |
|
103 |
- |
|
104 |
-# Set a "language standard" compiler flag. |
|
105 |
-# Unremark just one line below to set the language standard to use. |
|
106 |
-# gnu99 = C99 + GNU extensions. See GCC manual for more information. |
|
107 |
-#CFLAGS += -std=c89 |
|
108 |
-#CFLAGS += -std=gnu89 |
|
109 |
-#CFLAGS += -std=c99 |
|
110 |
-CFLAGS += -std=gnu99 |
|
111 |
- |
|
112 |
-# do not use C99 strict aliasing rules |
|
113 |
-# this kills some warnings occuring when casting pointer types |
|
114 |
-CFLAGS += -fno-strict-aliasing |
|
115 |
- |
|
116 |
- |
|
117 |
- |
|
118 |
-# Optional assembler flags. |
|
119 |
-# -Wa,...: tell GCC to pass this to the assembler. |
|
120 |
-# -ahlms: create listing |
|
121 |
-# -gstabs: have the assembler create line number information; note that |
|
122 |
-# for use in COFF files, additional information about filenames |
|
123 |
-# and function names needs to be present in the assembler source |
|
124 |
-# files -- see avr-libc docs [FIXME: not yet described there] |
|
125 |
-ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs |
|
126 |
- |
|
127 |
- |
|
128 |
- |
|
129 |
-# Optional linker flags. |
|
130 |
-# -Wl,...: tell GCC to pass this to linker. |
|
131 |
-# -Map: create map file |
|
132 |
-# --cref: add cross reference to map file |
|
133 |
-LDFLAGS = -Wl,-Map=$(TARGET).map,--cref |
|
134 |
- |
|
135 |
- |
|
136 |
- |
|
137 |
-# Additional libraries |
|
138 |
- |
|
139 |
-# Minimalistic printf version |
|
140 |
-#LDFLAGS += -Wl,-u,vfprintf -lprintf_min |
|
141 |
- |
|
142 |
-# Floating point printf version (requires -lm below) |
|
143 |
-#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt |
|
144 |
- |
|
145 |
-# -lm = math library |
|
146 |
-LDFLAGS += -lm |
|
147 |
- |
|
148 |
- |
|
149 |
- |
|
150 |
-# rebuilding is required if one of the following files is changed |
|
151 |
-REBUILD_DEPS = Makefile.conf |
|
152 |
- |
|
153 |
- |
|
154 |
- |
|
155 |
-# Programming support using avrdude. Settings and variables. |
|
156 |
- |
|
157 |
-# Programming hardware: alf avr910 avrisp bascom bsd |
|
158 |
-# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500 |
|
159 |
-# |
|
160 |
-# Type: avrdude -c ? |
|
161 |
-# to get a full listing. |
|
162 |
-# |
|
163 |
-AVRDUDE_PROGRAMMER = stk200 |
|
164 |
- |
|
165 |
- |
|
166 |
-#AVRDUDE_PORT = com1 # programmer connected to serial device |
|
167 |
-#AVRDUDE_PORT = lpt1 # programmer connected to parallel port |
|
168 |
-AVRDUDE_PORT = /dev/parport0 |
|
169 |
- |
|
170 |
-AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex |
|
171 |
-#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep |
|
172 |
- |
|
173 |
-AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) |
|
174 |
- |
|
175 |
-# Uncomment the following if you want avrdude's erase cycle counter. |
|
176 |
-# Note that this counter needs to be initialized first using -Yn, |
|
177 |
-# see avrdude manual. |
|
178 |
-#AVRDUDE_ERASE += -y |
|
179 |
- |
|
180 |
-# Uncomment the following if you do /not/ wish a verification to be |
|
181 |
-# performed after programming the device. |
|
182 |
-#AVRDUDE_FLAGS += -V |
|
183 |
- |
|
184 |
-# Increase verbosity level. Please use this when submitting bug |
|
185 |
-# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude> |
|
186 |
-# to submit bug reports. |
|
187 |
-#AVRDUDE_FLAGS += -v -v |
|
188 |
- |
|
189 |
-AVRDUDE_WRITE_FUSES = -u -U lfuse:w:0xAF:m -U hfuse:w:0xC9:m -U efuse:w:0xFF:m |
|
190 |
- |
|
191 |
- |
|
192 |
- |
|
193 |
-# --------------------------------------------------------------------------- |
|
194 |
- |
|
195 |
-# Define directories, if needed. |
|
196 |
-DIRAVR = |
|
197 |
-DIRAVRBIN = |
|
198 |
-DIRAVRUTILS = |
|
199 |
-DIRINC = |
|
200 |
-DIRLIB = |
|
201 |
- |
|
202 |
- |
|
203 |
-# Define programs and commands. |
|
204 |
-SHELL = sh |
|
205 |
- |
|
206 |
-CC = avr-gcc |
|
207 |
- |
|
208 |
-OBJCOPY = avr-objcopy |
|
209 |
-OBJDUMP = avr-objdump |
|
210 |
-SIZE = avr-size |
|
211 |
- |
|
212 |
- |
|
213 |
-# Programming support using avrdude. |
|
214 |
-AVRDUDE = avrdude |
|
215 |
- |
|
216 |
- |
|
217 |
-REMOVE = rm -f |
|
218 |
-COPY = cp |
|
219 |
- |
|
220 |
-HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex |
|
221 |
-ELFSIZE = $(SIZE) -A $(TARGET).elf |
|
222 |
- |
|
223 |
- |
|
224 |
- |
|
225 |
-# Define Messages |
|
226 |
-# English |
|
227 |
-MSG_ERRORS_NONE = Errors: none |
|
228 |
-MSG_BEGIN = -------- begin -------- |
|
229 |
-MSG_END = -------- end -------- |
|
230 |
-MSG_SIZE_BEFORE = Size before: |
|
231 |
-MSG_SIZE_AFTER = Size after: |
|
232 |
-MSG_COFF = Converting to AVR COFF: |
|
233 |
-MSG_EXTENDED_COFF = Converting to AVR Extended COFF: |
|
234 |
-MSG_FLASH = Creating load file for Flash: |
|
235 |
-MSG_EEPROM = Creating load file for EEPROM: |
|
236 |
-MSG_EXTENDED_LISTING = Creating Extended Listing: |
|
237 |
-MSG_SYMBOL_TABLE = Creating Symbol Table: |
|
238 |
-MSG_LINKING = Linking: |
|
239 |
-MSG_COMPILING = Compiling: |
|
240 |
-MSG_ASSEMBLING = Assembling: |
|
241 |
-MSG_CLEANING = Cleaning project: |
|
242 |
- |
|
243 |
- |
|
244 |
- |
|
245 |
- |
|
246 |
-# Define all object files. |
|
247 |
-OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) |
|
248 |
- |
|
249 |
-# Define all listing files. |
|
250 |
-LST = $(ASRC:.S=.lst) $(SRC:.c=.lst) |
|
251 |
- |
|
252 |
-# Combine all necessary flags and optional flags. |
|
253 |
-# Add target processor to flags. |
|
254 |
-ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) |
|
255 |
-ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) |
|
256 |
- |
|
257 |
- |
|
258 |
- |
|
259 |
-# Default target. |
|
260 |
-all: my_all begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep \ |
|
261 |
- $(TARGET).lss $(TARGET).sym sizeafter finished end |
|
262 |
- |
|
263 |
-# Debug target. |
|
264 |
-debug: DBG_FLAGS=-DDEBUG |
|
265 |
-debug: all |
|
266 |
- |
|
267 |
- |
|
268 |
-# Eye candy. |
|
269 |
-# AVR Studio 3.x does not check make's exit code but relies on |
|
270 |
-# the following magic strings to be generated by the compile job. |
|
271 |
-begin: |
|
272 |
- @echo |
|
273 |
- @echo $(MSG_BEGIN) |
|
274 |
- |
|
275 |
-finished: |
|
276 |
- @echo $(MSG_ERRORS_NONE) |
|
277 |
- |
|
278 |
-end: |
|
279 |
- @echo $(MSG_END) |
|
280 |
- @echo |
|
281 |
- |
|
282 |
- |
|
283 |
-# Display size of file. |
|
284 |
-sizebefore: |
|
285 |
- @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi |
|
286 |
- |
|
287 |
-sizeafter: |
|
288 |
- @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi |
|
289 |
- |
|
290 |
- |
|
291 |
- |
|
292 |
-# Display compiler version information. |
|
293 |
-gccversion : |
|
294 |
- @$(CC) --version |
|
295 |
- |
|
296 |
- |
|
297 |
- |
|
298 |
- |
|
299 |
-# Convert ELF to COFF for use in debugging / simulating in |
|
300 |
-# AVR Studio or VMLAB. |
|
301 |
-COFFCONVERT=$(OBJCOPY) --debugging \ |
|
302 |
- --change-section-address .data-0x800000 \ |
|
303 |
- --change-section-address .bss-0x800000 \ |
|
304 |
- --change-section-address .noinit-0x800000 \ |
|
305 |
- --change-section-address .eeprom-0x810000 |
|
306 |
- |
|
307 |
- |
|
308 |
-coff: $(TARGET).elf |
|
309 |
- @echo |
|
310 |
- @echo $(MSG_COFF) $(TARGET).cof |
|
311 |
- $(COFFCONVERT) -O coff-avr $< $(TARGET).cof |
|
312 |
- |
|
313 |
- |
|
314 |
-extcoff: $(TARGET).elf |
|
315 |
- @echo |
|
316 |
- @echo $(MSG_EXTENDED_COFF) $(TARGET).cof |
|
317 |
- $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof |
|
318 |
- |
|
319 |
- |
|
320 |
- |
|
321 |
-# Program the device fuses. |
|
322 |
-program_fuses: |
|
323 |
- $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FUSES) |
|
324 |
- |
|
325 |
-# Program the device. |
|
326 |
-program: $(TARGET).hex $(TARGET).eep |
|
327 |
- $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) |
|
328 |
- |
|
329 |
- |
|
330 |
- |
|
331 |
- |
|
332 |
-# Create final output files (.hex, .eep) from ELF output file. |
|
333 |
-%.hex: %.elf |
|
334 |
- @echo |
|
335 |
- @echo $(MSG_FLASH) $@ |
|
336 |
- $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ |
|
337 |
- |
|
338 |
-%.eep: %.elf |
|
339 |
- @echo |
|
340 |
- @echo $(MSG_EEPROM) $@ |
|
341 |
- -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \ |
|
342 |
- --change-section-lma .eeprom=0 -O $(FORMAT) $< $@ |
|
343 |
- |
|
344 |
-# Create extended listing file from ELF output file. |
|
345 |
-%.lss: %.elf |
|
346 |
- @echo |
|
347 |
- @echo $(MSG_EXTENDED_LISTING) $@ |
|
348 |
- $(OBJDUMP) -h -S $< > $@ |
|
349 |
- |
|
350 |
-# Create a symbol table from ELF output file. |
|
351 |
-%.sym: %.elf |
|
352 |
- @echo |
|
353 |
- @echo $(MSG_SYMBOL_TABLE) $@ |
|
354 |
- avr-nm -n $< > $@ |
|
355 |
- |
|
356 |
- |
|
357 |
- |
|
358 |
-# Link: create ELF output file from object files. |
|
359 |
-.SECONDARY : $(TARGET).elf |
|
360 |
-.PRECIOUS : $(OBJ) |
|
361 |
-%.elf: $(OBJ) |
|
362 |
- @echo |
|
363 |
- @echo $(MSG_LINKING) $@ |
|
364 |
- $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS) |
|
365 |
- |
|
366 |
- |
|
367 |
-# Compile: create object files from C source files. |
|
368 |
-%.o : %.c $(REBUILD_DEPS) |
|
369 |
- @echo |
|
370 |
- @echo $(MSG_COMPILING) $< |
|
371 |
- $(CC) -c $(ALL_CFLAGS) $< -o $@ |
|
372 |
- |
|
373 |
- |
|
374 |
-# Compile: create assembler files from C source files. |
|
375 |
-%.s : %.c $(REBUILD_DEPS) |
|
376 |
- $(CC) -S $(ALL_CFLAGS) $< -o $@ |
|
377 |
- |
|
378 |
- |
|
379 |
-# Assemble: create object files from assembler source files. |
|
380 |
-%.o : %.S $(REBUILD_DEPS) |
|
381 |
- @echo |
|
382 |
- @echo $(MSG_ASSEMBLING) $< |
|
383 |
- $(CC) -c $(ALL_ASFLAGS) $< -o $@ |
|
384 |
- |
|
385 |
- |
|
386 |
- |
|
387 |
- |
|
388 |
- |
|
389 |
- |
|
390 |
-# Target: clean project. |
|
391 |
-clean: my_clean begin clean_list finished end |
|
392 |
- |
|
393 |
-clean_list : |
|
394 |
- @echo |
|
395 |
- @echo $(MSG_CLEANING) |
|
396 |
- $(REMOVE) $(TARGET).hex |
|
397 |
- $(REMOVE) $(TARGET).eep |
|
398 |
- $(REMOVE) $(TARGET).obj |
|
399 |
- $(REMOVE) $(TARGET).cof |
|
400 |
- $(REMOVE) $(TARGET).elf |
|
401 |
- $(REMOVE) $(TARGET).map |
|
402 |
- $(REMOVE) $(TARGET).obj |
|
403 |
- $(REMOVE) $(TARGET).a90 |
|
404 |
- $(REMOVE) $(TARGET).sym |
|
405 |
- $(REMOVE) $(TARGET).lnk |
|
406 |
- $(REMOVE) $(TARGET).lss |
|
407 |
- $(REMOVE) $(OBJ) |
|
408 |
- $(REMOVE) $(LST) |
|
409 |
- $(REMOVE) $(SRC:.c=.s) |
|
410 |
- $(REMOVE) $(SRC:.c=.d) |
|
411 |
- |
|
412 |
- |
|
413 |
-# Automatically generate C source code dependencies. |
|
414 |
-# (Code originally taken from the GNU make user manual and modified |
|
415 |
-# (See README.txt Credits).) |
|
416 |
-# |
|
417 |
-# Note that this will work with sh (bash) and sed that is shipped with WinAVR |
|
418 |
-# (see the SHELL variable defined above). |
|
419 |
-# This may not work with other shells or other seds. |
|
420 |
-# |
|
421 |
-%.d: %.c $(REBUILD_DEPS) |
|
422 |
- set -e; $(CC) -MM $(ALL_CFLAGS) $< \ |
|
423 |
- | sed 's,\(.*\)\.o[ :]*,\1.o \1.d : ,g' > $@; \ |
|
424 |
- [ -s $@ ] || rm -f $@ |
|
425 |
- |
|
426 |
-http.d: http.c http_content.inc |
|
427 |
- |
|
428 |
- |
|
429 |
-# Remove the '-' if you want to see the dependency files generated. |
|
430 |
-include $(SRC:.c=.d) |
|
431 |
- |
|
432 |
- |
|
433 |
- |
|
434 |
-my_all: http_content.inc |
|
435 |
- |
|
436 |
-http_content.inc: http_content.pl http_$(HTTP_SKIN)/* $(REBUILD_DEPS) |
|
437 |
- ./http_content.pl http_$(HTTP_SKIN) http_content.inc || rm -f http_content.inc http_content.inc |
|
438 |
- |
|
439 |
-my_clean: |
|
440 |
- rm -f http_content.inc |
|
441 |
- |
|
442 |
- |
|
443 |
- |
|
444 |
-# Listing of phony targets. |
|
445 |
-.PHONY : all begin finish end sizebefore sizeafter gccversion coff extcoff \ |
|
446 |
- clean clean_list program_fuses program my_all my_clean |
|
447 |
- |
... | ... |
@@ -1,8 +0,0 @@ |
1 |
-# flaneth - flash and ethernet |
|
2 |
-# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
3 |
-# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
4 |
-# a BlinkenArea project - http://www.blinkenarea.org/ |
|
5 |
- |
|
6 |
-# skin to use on http interface |
|
7 |
-# HTTP_SKIN=[simple] |
|
8 |
-HTTP_SKIN = simple |
... | ... |
@@ -1,240 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include "arp.h" |
|
9 |
-#include "config.h" |
|
10 |
-#include "debug.h" |
|
11 |
-#include "ethernet.h" |
|
12 |
-#include "ip.h" |
|
13 |
-#include "macros.h" |
|
14 |
-#include "nethelp.h" |
|
15 |
- |
|
16 |
-// timing parameters |
|
17 |
-#define ArpTicksMax 150 // maximum age of ARP table entries (in 200ms steps) |
|
18 |
-#define ArpNoMacTicksMax 50 // maximum age of ARP table entries without MAC (in 200ms steps) |
|
19 |
-#define ArpRetryTicks 8 // time after which to retry ARP query (must be power of 2, in 200ms steps) |
|
20 |
- |
|
21 |
-// ARP table |
|
22 |
-#define ArpTabFlagInUse 0x01 |
|
23 |
-#define ArpTabFlagMacOk 0x02 |
|
24 |
-struct ArpTable |
|
25 |
-{ |
|
26 |
- unsigned char Flags; // flags - see constants |
|
27 |
- unsigned char Ticks; // age of entry in 200ms steps |
|
28 |
- unsigned char Mac[6]; |
|
29 |
- unsigned char Ip[4]; |
|
30 |
-} ArpTab[12]; |
|
31 |
- |
|
32 |
-// initialize |
|
33 |
-void ArpInit( void ) // (extern) |
|
34 |
-{ |
|
35 |
- unsigned char i; |
|
36 |
- |
|
37 |
- // empty ARP tabale |
|
38 |
- for( i = 0; i < count( ArpTab ); i++ ) |
|
39 |
- ArpTab[i].Flags = 0; |
|
40 |
-} |
|
41 |
- |
|
42 |
-// send an ARP request |
|
43 |
-static void ArpSendRequest( unsigned char * pIp ) |
|
44 |
-{ |
|
45 |
- struct ArpPacket ArpRequest; |
|
46 |
- |
|
47 |
- debug_arp_printf( "send req ip=%u.%u.%u.%u", |
|
48 |
- pIp[0], pIp[1], pIp[2], pIp[3] ); |
|
49 |
- |
|
50 |
- // build ARP request |
|
51 |
- ArpRequest.ArpHdr.HwType = htons( 0x0001 ); // ethernet |
|
52 |
- ArpRequest.ArpHdr.ProtoType = htons( 0x0800 ); // IP |
|
53 |
- ArpRequest.ArpHdr.HwLen = 0x06; // length of a MAC address |
|
54 |
- ArpRequest.ArpHdr.ProtoLen = 0x04; // length of an IP address |
|
55 |
- ArpRequest.ArpHdr.Op = htons( 0x0001 ); // ARP request |
|
56 |
- mac_cpy( ArpRequest.ArpHdr.SrcMac, ConfigMac ); // own MAC |
|
57 |
- ip_cpy( ArpRequest.ArpHdr.SrcIp, ConfigIp ); // own IP |
|
58 |
- mac_cpy( ArpRequest.ArpHdr.DestMac, "\xFF\xFF\xFF\xFF\xFF\xFF" ); // broadcast MAC |
|
59 |
- ip_cpy( ArpRequest.ArpHdr.DestIp, pIp ); // requested IP |
|
60 |
- |
|
61 |
- // sent ARP request |
|
62 |
- mac_cpy( ArpRequest.EthHdr.Dest, ArpRequest.ArpHdr.DestMac ); // ethernet destination address |
|
63 |
- ArpRequest.EthHdr.Type = htons( 0x0806 ); // ethernet packet type: ARP |
|
64 |
- EthernetSend( (unsigned char *)&ArpRequest, sizeof( ArpRequest ) ); |
|
65 |
-} |
|
66 |
- |
|
67 |
-// tick procedure - call every 200ms |
|
68 |
-void ArpTick200( void ) // (extern) |
|
69 |
-{ |
|
70 |
- unsigned char i; |
|
71 |
- |
|
72 |
- // increase age of ARP table entires and remove timed out ones |
|
73 |
- for( i = 0; i < count( ArpTab ); i++ ) |
|
74 |
- { |
|
75 |
- if( ArpTab[i].Flags & ArpTabFlagInUse ) // entry in use |
|
76 |
- { |
|
77 |
- ArpTab[i].Ticks++; // increase age |
|
78 |
- if( ArpTab[i].Flags & ArpTabFlagMacOk ) // entry has got a MAC |
|
79 |
- { |
|
80 |
- if( ArpTab[i].Ticks > ArpTicksMax ) // too old |
|
81 |
- ArpTab[i].Flags = 0; // remove entry |
|
82 |
- } |
|
83 |
- else // entry has not got a MAC |
|
84 |
- { |
|
85 |
- if( ArpTab[i].Ticks > ArpNoMacTicksMax ) // too old |
|
86 |
- ArpTab[i].Flags = 0; // remove entry |
|
87 |
- else if( (ArpTab[i].Ticks & (ArpRetryTicks - 1)) == 0 ) // retry ARP request |
|
88 |
- ArpSendRequest( ArpTab[i].Ip ); |
|
89 |
- } |
|
90 |
- } |
|
91 |
- } |
|
92 |
-} |
|
93 |
- |
|
94 |
-// process a received ARP packet |
|
95 |
-void ArpRecv( unsigned char * pData, unsigned short Length ) // (extern) |
|
96 |
-{ |
|
97 |
- struct ArpPacket * pArpPack; |
|
98 |
- |
|
99 |
- // packet too short |
|
100 |
- if( Length < sizeof( struct ArpPacket ) ) |
|
101 |
- return; |
|
102 |
- |
|
103 |
- // convert pointer to ARP packet |
|
104 |
- // (this saves us from always casting pData) |
|
105 |
- pArpPack = (struct ArpPacket *)pData; |
|
106 |
- |
|
107 |
- // not IP over ethernet |
|
108 |
- if( pArpPack->ArpHdr.HwType != htons( 0x0001 ) || // ethernet |
|
109 |
- pArpPack->ArpHdr.ProtoType != htons( 0x0800 ) || // IP |
|
110 |
- pArpPack->ArpHdr.HwLen != 0x06 || // length of a MAC address |
|
111 |
- pArpPack->ArpHdr.ProtoLen != 0x04 ) // length of an IP address |
|
112 |
- // we do not support other protocols than IP over ethernet |
|
113 |
- return; |
|
114 |
- |
|
115 |
- // source MAC is broadcast MAC |
|
116 |
- if( mac_eq( pArpPack->ArpHdr.SrcMac, "\xFF\xFF\xFF\xFF\xFF\xFF" ) ) |
|
117 |
- // broadcast MAC cannot be source, this is some kind of attack, get lost! |
|
118 |
- return; |
|
119 |
- |
|
120 |
- // ARP request for own IP address |
|
121 |
- if( pArpPack->ArpHdr.Op == htons( 0x0001 ) && // ARP request |
|
122 |
- ip_eq( pArpPack->ArpHdr.DestIp, ConfigIp ) ) // own IP address |
|
123 |
- { |
|
124 |
- struct ArpPacket ArpReply; |
|
125 |
- // build ARP reply |
|
126 |
- ArpReply.ArpHdr.HwType = htons( 0x0001 ); // ethernet |
|
127 |
- ArpReply.ArpHdr.ProtoType = htons( 0x0800 ); // IP |
|
128 |
- ArpReply.ArpHdr.HwLen = 0x06; // length of a MAC address |
|
129 |
- ArpReply.ArpHdr.ProtoLen = 0x04; // length of an IP address |
|
130 |
- ArpReply.ArpHdr.Op = htons( 0x0002 ); // ARP reply |
|
131 |
- mac_cpy( ArpReply.ArpHdr.SrcMac, ConfigMac ); // own MAC |
|
132 |
- ip_cpy( ArpReply.ArpHdr.SrcIp, ConfigIp ); // own IP |
|
133 |
- mac_cpy( ArpReply.ArpHdr.DestMac, pArpPack->ArpHdr.SrcMac ); // requestor's MAC |
|
134 |
- ip_cpy( ArpReply.ArpHdr.DestIp, pArpPack->ArpHdr.SrcIp ); // requestor's IP |
|
135 |
- |
|
136 |
- debug_arp_printf( "recv req src=%02X:%02X:%02X:%02X:%02X:%02X ip=%u.%u.%u.%u", |
|
137 |
- pArpPack->ArpHdr.SrcMac[0], pArpPack->ArpHdr.SrcMac[1], pArpPack->ArpHdr.SrcMac[2], |
|
138 |
- pArpPack->ArpHdr.SrcMac[3], pArpPack->ArpHdr.SrcMac[4], pArpPack->ArpHdr.SrcMac[5], |
|
139 |
- pArpPack->ArpHdr.SrcIp[0], pArpPack->ArpHdr.SrcIp[1], |
|
140 |
- pArpPack->ArpHdr.SrcIp[2], pArpPack->ArpHdr.SrcIp[3] ); |
|
141 |
- |
|
142 |
- // sent ARP reply |
|
143 |
- mac_cpy( ArpReply.EthHdr.Dest, ArpReply.ArpHdr.DestMac ); // ethernet destination address |
|
144 |
- ArpReply.EthHdr.Type = htons( 0x0806 ); // ethernet packet type: ARP |
|
145 |
- EthernetSend( (unsigned char *)&ArpReply, sizeof( ArpReply ) ); |
|
146 |
- return; |
|
147 |
- } |
|
148 |
- |
|
149 |
- // ARP reply to own MAC address and own IP address |
|
150 |
- if( pArpPack->ArpHdr.Op == htons( 0x0002 ) && // ARP reply |
|
151 |
- mac_eq( pArpPack->ArpHdr.DestMac, ConfigMac ) && // own MAC address |
|
152 |
- ip_eq( pArpPack->ArpHdr.DestIp, ConfigIp ) ) // own IP address |
|
153 |
- { |
|
154 |
- unsigned char i; |
|
155 |
- |
|
156 |
- debug_arp_printf( "recv reply src=%02X:%02X:%02X:%02X:%02X:%02X ip=%u.%u.%u.%u", |
|
157 |
- pArpPack->ArpHdr.SrcMac[0], pArpPack->ArpHdr.SrcMac[1], pArpPack->ArpHdr.SrcMac[2], |
|
158 |
- pArpPack->ArpHdr.SrcMac[3], pArpPack->ArpHdr.SrcMac[4], pArpPack->ArpHdr.SrcMac[5], |
|
159 |
- pArpPack->ArpHdr.SrcIp[0], pArpPack->ArpHdr.SrcIp[1], |
|
160 |
- pArpPack->ArpHdr.SrcIp[2], pArpPack->ArpHdr.SrcIp[3] ); |
|
161 |
- |
|
162 |
- // search IP in ARP tabale |
|
163 |
- for( i = 0; i < count( ArpTab ); i++ ) |
|
164 |
- if( (ArpTab[i].Flags & ArpTabFlagInUse) && |
|
165 |
- ip_eq( pArpPack->ArpHdr.SrcIp, ArpTab[i].Ip ) ) |
|
166 |
- break; |
|
167 |
- // if found in ARP table |
|
168 |
- // (we do not want to put an entry in the ARP table |
|
169 |
- // if we have not asked for the MAC of this IP) |
|
170 |
- if( i < count( ArpTab ) ) |
|
171 |
- { |
|
172 |
- // update ARP table entry |
|
173 |
- ArpTab[i].Flags = ArpTabFlagInUse | ArpTabFlagMacOk; |
|
174 |
- ArpTab[i].Ticks = 0; |
|
175 |
- mac_cpy( ArpTab[i].Mac, pArpPack->ArpHdr.SrcMac ); |
|
176 |
- // notify IP |
|
177 |
- // - IP might be waiting for the MAC to transmit a packet |
|
178 |
- IpGotMac( ArpTab[i].Ip, ArpTab[i].Mac ); |
|
179 |
- } |
|
180 |
- return; |
|
181 |
- } |
|
182 |
- |
|
183 |
-} |
|
184 |
- |
|
185 |
-// lookup the MAC for an IP address |
|
186 |
-// returns 0x00 in case of success, 0x01 if the MAC address is unknown |
|
187 |
-unsigned char ArpLookup( unsigned char * pIp, unsigned char * pMac ) // (extern) |
|
188 |
-{ |
|
189 |
- unsigned char i, j; |
|
190 |
- |
|
191 |
- // own IP |
|
192 |
- if( ip_eq( pIp, ConfigIp ) ) |
|
193 |
- // own IP may not be looked up via ARP |
|
194 |
- return 0x01; |
|
195 |
- |
|
196 |
- // search IP in ARP tabale |
|
197 |
- for( i = 0; i < count( ArpTab ); i++ ) |
|
198 |
- if( (ArpTab[i].Flags & ArpTabFlagInUse) && |
|
199 |
- ip_eq( pIp, ArpTab[i].Ip ) ) |
|
200 |
- break; |
|
201 |
- |
|
202 |
- // not found |
|
203 |
- if( i >= count( ArpTab ) ) |
|
204 |
- { |
|
205 |
- // find a free entry |
|
206 |
- for( i = 0; i < count( ArpTab ); i++ ) |
|
207 |
- if( ! (ArpTab[i].Flags & ArpTabFlagInUse) ) |
|
208 |
- break; |
|
209 |
- |
|
210 |
- // no free entry |
|
211 |
- if( i >= count( ArpTab ) ) |
|
212 |
- { |
|
213 |
- // find oldest entry |
|
214 |
- i = 0; |
|
215 |
- for( j = 1; j < count( ArpTab ); j++ ) |
|
216 |
- if( ArpTab[j].Ticks > ArpTab[i].Ticks ) |
|
217 |
- i = j; |
|
218 |
- } |
|
219 |
- |
|
220 |
- // set up this entry |
|
221 |
- ArpTab[i].Flags = ArpTabFlagInUse; |
|
222 |
- ArpTab[i].Ticks = 0; |
|
223 |
- ip_cpy( ArpTab[i].Ip, pIp ); |
|
224 |
- } |
|
225 |
- |
|
226 |
- // MAC available |
|
227 |
- if( ArpTab[i].Flags & ArpTabFlagMacOk ) |
|
228 |
- { |
|
229 |
- // return MAC and success |
|
230 |
- mac_cpy( pMac, ArpTab[i].Mac ); |
|
231 |
- return 0x00; |
|
232 |
- } |
|
233 |
- |
|
234 |
- // send ARP request |
|
235 |
- ArpSendRequest( pIp ); |
|
236 |
- |
|
237 |
- // return no success for now |
|
238 |
- return 0x01; |
|
239 |
-} |
|
240 |
- |
... | ... |
@@ -1,48 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_arp |
|
9 |
-#define INC_arp |
|
10 |
- |
|
11 |
-#include "ethernet.h" |
|
12 |
- |
|
13 |
-// header of an ARP packet |
|
14 |
-struct ArpHeader |
|
15 |
-{ |
|
16 |
- unsigned short HwType; |
|
17 |
- unsigned short ProtoType; |
|
18 |
- unsigned char HwLen; |
|
19 |
- unsigned char ProtoLen; |
|
20 |
- unsigned short Op; |
|
21 |
- unsigned char SrcMac[6]; |
|
22 |
- unsigned char SrcIp[4]; |
|
23 |
- unsigned char DestMac[6]; |
|
24 |
- unsigned char DestIp[4]; |
|
25 |
-}; |
|
26 |
- |
|
27 |
-// an ARP packet |
|
28 |
-struct ArpPacket |
|
29 |
-{ |
|
30 |
- struct EthernetHeader EthHdr; |
|
31 |
- struct ArpHeader ArpHdr; |
|
32 |
-}; |
|
33 |
- |
|
34 |
-// initialize |
|
35 |
-extern void ArpInit( void ); |
|
36 |
- |
|
37 |
-// tick procedure - call every 200ms |
|
38 |
-extern void ArpTick200( void ); |
|
39 |
- |
|
40 |
-// process a received ARP packet |
|
41 |
-extern void ArpRecv( unsigned char * pData, unsigned short Length ); |
|
42 |
- |
|
43 |
-// lookup the MAC for an IP address |
|
44 |
-// returns 0x00 in case of success, 0x01 if the MAC address is unknown |
|
45 |
-extern unsigned char ArpLookup( unsigned char * pIp, unsigned char * pMac ); |
|
46 |
- |
|
47 |
-#endif // #ifdef INC_arp |
|
48 |
- |
... | ... |
@@ -1,31 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/io.h> |
|
9 |
- |
|
10 |
-#include "bus.h" |
|
11 |
- |
|
12 |
-// initialize |
|
13 |
-void BusInit( void ) // (extern) |
|
14 |
-{ |
|
15 |
- // address port to output |
|
16 |
- BUS_ADDR = 0x00; // default address |
|
17 |
- BUS_ADDR_DDR = 0xFF; // output |
|
18 |
- |
|
19 |
- // data port to input |
|
20 |
- BUS_DATA = 0x00; // pull-ups off |
|
21 |
- BUS_DATA_DDR = 0x00; // input |
|
22 |
- |
|
23 |
- // read pin to output |
|
24 |
- bit_set( BUS_PORT_nRD, BUS_BIT_nRD ); // nRD to high |
|
25 |
- bit_set( BUS_DDR_nRD, BUS_BIT_nRD ); // output |
|
26 |
- |
|
27 |
- // write pin to output |
|
28 |
- bit_set( BUS_PORT_nWR, BUS_BIT_nWR ); // nWR to high |
|
29 |
- bit_set( BUS_DDR_nWR, BUS_BIT_nWR ); // output |
|
30 |
-} |
|
31 |
- |
... | ... |
@@ -1,36 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_bus |
|
9 |
-#define INC_bus |
|
10 |
- |
|
11 |
-#include "macros.h" |
|
12 |
- |
|
13 |
-// IO pins of bus |
|
14 |
-#define BUS_ADDR_DDR (DDRG) |
|
15 |
-#define BUS_ADDR (PORTG) |
|
16 |
-#define BUS_DATA_DDR (DDRA) |
|
17 |
-#define BUS_DATA (PORTA) |
|
18 |
-#define BUS_DATA_IN (PINA) |
|
19 |
-#define BUS_DDR_nRD (DDRE) |
|
20 |
-#define BUS_PORT_nRD (PORTE) |
|
21 |
-#define BUS_BIT_nRD (6) |
|
22 |
-#define BUS_DDR_nWR (DDRE) |
|
23 |
-#define BUS_PORT_nWR (PORTE) |
|
24 |
-#define BUS_BIT_nWR (7) |
|
25 |
- |
|
26 |
-// special pin commands |
|
27 |
-#define BUS_READ_ACT( ) (bit_clear( BUS_PORT_nRD, BUS_BIT_nRD )) |
|
28 |
-#define BUS_READ_IDLE( ) (bit_set( BUS_PORT_nRD, BUS_BIT_nRD )) |
|
29 |
-#define BUS_WRITE_ACT( ) (bit_clear( BUS_PORT_nWR, BUS_BIT_nWR )) |
|
30 |
-#define BUS_WRITE_IDLE( ) (bit_set( BUS_PORT_nWR, BUS_BIT_nWR )) |
|
31 |
- |
|
32 |
-// initialize |
|
33 |
-extern void BusInit( void ); |
|
34 |
- |
|
35 |
-#endif // #ifndef INC_bus |
|
36 |
- |
... | ... |
@@ -1,605 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/io.h> |
|
9 |
- |
|
10 |
-#include "bus.h" |
|
11 |
-#include "cf.h" |
|
12 |
-#include "config.h" |
|
13 |
-#include "debug.h" |
|
14 |
-#include "macros.h" |
|
15 |
-#include "status.h" |
|
16 |
-#include "timing.h" |
|
17 |
- |
|
18 |
-// IO pins of compact flash |
|
19 |
-#define CF_DDR_nCD (DDRB) |
|
20 |
-#define CF_PORT_nCD (PORTB) |
|
21 |
-#define CF_PIN_nCD (PINB) |
|
22 |
-#define CF_BIT_nCD (4) |
|
23 |
-#define CF_DDR_nRST (DDRB) |
|
24 |
-#define CF_PORT_nRST (PORTB) |
|
25 |
-#define CF_BIT_nRST (5) |
|
26 |
-#define CF_DDR_RDY (DDRB) |
|
27 |
-#define CF_PORT_RDY (PORTB) |
|
28 |
-#define CF_PIN_RDY (PINB) |
|
29 |
-#define CF_BIT_RDY (7) |
|
30 |
-#define CF_DDR_nCE (DDRB) |
|
31 |
-#define CF_PORT_nCE (PORTB) |
|
32 |
-#define CF_BIT_nCE (6) |
|
33 |
-// special pin commands |
|
34 |
-#define CF_IS_DETECT( ) (is_bit_clear( CF_PIN_nCD, CF_BIT_nCD )) |
|
35 |
-#define CF_RESET_ACT( ) (bit_clear( CF_PORT_nRST, CF_BIT_nRST )) |
|
36 |
-#define CF_RESET_IDLE( ) (bit_set( CF_PORT_nRST, CF_BIT_nRST )) |
|
37 |
-#define CF_IS_READY( ) (is_bit_set( CF_PIN_RDY, CF_BIT_RDY )) |
|
38 |
-#define CF_CE_ACT( ) (bit_clear( CF_PORT_nCE, CF_BIT_nCE )) |
|
39 |
-#define CF_CE_IDLE( ) (bit_set( CF_PORT_nCE, CF_BIT_nCE )) |
|
40 |
- |
|
41 |
-// compact flash registers |
|
42 |
-#define CF_REG_DATA (0x00) |
|
43 |
-#define CF_REG_ERR (0x01) |
|
44 |
-#define CF_REG_SEC_CNT (0x02) |
|
45 |
-#define CF_REG_SEC_NO (0x03) |
|
46 |
-#define CF_REG_CYL_L (0x04) |
|
47 |
-#define CF_REG_CYL_H (0x05) |
|
48 |
-#define CF_REG_HEAD (0x06) |
|
49 |
-#define CF_REG_STATUS (0x07) |
|
50 |
-#define CF_REG_CMD (0x07) |
|
51 |
- |
|
52 |
-// compact flash status bits |
|
53 |
-#define CF_SB_BUSY (7) |
|
54 |
-#define CF_SB_RDY (6) |
|
55 |
-#define CF_SB_DWF (5) |
|
56 |
-#define CF_SB_DSC (4) |
|
57 |
-#define CF_SB_DRQ (3) |
|
58 |
-#define CF_SB_CORR (2) |
|
59 |
-#define CF_SB_IDX (1) |
|
60 |
-#define CF_SB_ERR (0) |
|
61 |
- |
|
62 |
-// compact flash commands |
|
63 |
-#define CF_CMD_IDENTIFY (0xEC) |
|
64 |
-#define CF_CMD_READ_SEC (0x20) |
|
65 |
-#define CF_CMD_WRITE_SEC (0x30) |
|
66 |
- |
|
67 |
-// some number of bytes |
|
68 |
-#define CF_BYTES_AT_ONCE (32) // number of bytes to read/write at once |
|
69 |
-#define CF_BYTES_IDENTIFY (124) // number of bytes to read for identify |
|
70 |
- |
|
71 |
-// interesting locations in identify data |
|
72 |
-#define CF_ID_OFS_ID_16 (0) // CF identifier, 16 bit |
|
73 |
-#define CF_ID_OFS_CAPA_16 (98) // CF capabilities, 16 bit |
|
74 |
-#define CF_ID_OFS_SEC_CNT_32 (120) // number of sectors on CF (in LBA mode), 32 bit |
|
75 |
- |
|
76 |
-// various CF constants |
|
77 |
-#define CF_ID (0x848A) // identifier of compact flash cards |
|
78 |
-#define CF_CAPA_BIT_LBA (9) // bit number of the LBA bit in the CF capabilities |
|
79 |
- |
|
80 |
-// timeout value for wait for ready counter (in 20ms steps) |
|
81 |
-#define CF_WAIT_READY_20_TIMEOUT (4) // 80ms |
|
82 |
- |
|
83 |
-// compact flash insertion state |
|
84 |
-enum CfInsertionState |
|
85 |
-{ |
|
86 |
- CfInsNone, // no compact flash inserted |
|
87 |
- CfInsNew, // new compact flash has been inserted, wait for powerup |
|
88 |
- CfInsReset, // resetting new compact flash |
|
89 |
- CfInsWait, // waiting for new compact flash to get ready after reset |
|
90 |
- CfInsReady, // compact flash inserted and ready to work with |
|
91 |
- CfInsError, // compact flash error occured, compact flash deactivated |
|
92 |
-} CfInsState = CfInsNone; |
|
93 |
- |
|
94 |
-// compact flash working state |
|
95 |
-enum CfWorkingState |
|
96 |
-{ |
|
97 |
- CfWorkNone, // no compact flash work to do |
|
98 |
- CfWorkIdentify, // identification of compact flash active |
|
99 |
-} CfWorkState = CfWorkNone; |
|
100 |
- |
|
101 |
-// compact flash working step |
|
102 |
-enum CfWorkingStep |
|
103 |
-{ |
|
104 |
- CfStepNone, // no step in progress |
|
105 |
- CfStepCmdStatus, // checking command status |
|
106 |
- CfStepDataTransfer, // transferring (reading/writing) data |
|
107 |
- CfStepDataStatus, // checking data status |
|
108 |
-} CfWorkStep = CfStepNone; |
|
109 |
- |
|
110 |
-// number of sectors on compact flash card |
|
111 |
-// - zero if no CF card is present, CF card has not yet been identified or CF card error occured |
|
112 |
-unsigned long CfSectorCnt = 0; |
|
113 |
- |
|
114 |
-// state of active command |
|
115 |
-unsigned long CfSectorNo = 0; // current sector number of compact flash |
|
116 |
-unsigned short CfNextOffset = 0; // next offset in sector that is processed (read, written, ...) |
|
117 |
- |
|
118 |
-// wait for ready counter of compact flash |
|
119 |
-// - counts down in 20ms steps |
|
120 |
-// - zero if inactive |
|
121 |
-unsigned char CfWaitReady20 = 0; |
|
122 |
- |
|
123 |
-// sector buffer |
|
124 |
-unsigned char CfSectorBuffer[CF_SECTOR_SIZE]; // (extern) |
|
125 |
- |
|
126 |
-// write a compact flash register (returns 1 if successful or 0 on error) |
|
127 |
-// - returns 0 on success and -1 on error |
|
128 |
-extern inline char CfWriteReg( unsigned char reg, unsigned char val ) // force inlining by using "extern" |
|
129 |
-{ |
|
130 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
131 |
- return -1; // error |
|
132 |
- BUS_DATA = val; // output value |
|
133 |
- BUS_DATA_DDR = 0xFF; // data port to output |
|
134 |
- BUS_ADDR = reg; // output address |
|
135 |
- CF_CE_ACT( ); // set card enable |
|
136 |
- BUS_WRITE_ACT( ); // activate write signal |
|
137 |
- nop( ); |
|
138 |
- nop( ); |
|
139 |
- nop( ); |
|
140 |
- nop( ); |
|
141 |
- nop( ); |
|
142 |
- nop( ); |
|
143 |
- BUS_WRITE_IDLE( ); // take back write signal |
|
144 |
- CF_CE_IDLE( ); // take back card enable |
|
145 |
- BUS_DATA_DDR = 0x00; // data back port to input |
|
146 |
- BUS_DATA = 0x00; // turn off pullups |
|
147 |
- return 0; // success |
|
148 |
-} |
|
149 |
- |
|
150 |
-// write buffer to compact flash register (returns 1 if successful or 0 on error) |
|
151 |
-// - returns 0 on success and -1 on error |
|
152 |
-extern inline char CfWriteRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern" |
|
153 |
-{ |
|
154 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
155 |
- return -1; // error |
|
156 |
- BUS_DATA = *p_buf; // output first value to initialize port status before switching to output |
|
157 |
- BUS_DATA_DDR = 0xFF; // data port to output |
|
158 |
- BUS_ADDR = reg; // output address |
|
159 |
- CF_CE_ACT( ); // set card enable |
|
160 |
- for( ; len > 0; p_buf++, len-- ) { |
|
161 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
162 |
- break; |
|
163 |
- BUS_DATA = *p_buf; // output value |
|
164 |
- BUS_WRITE_ACT( ); // activate write signal |
|
165 |
- nop( ); |
|
166 |
- nop( ); |
|
167 |
- nop( ); |
|
168 |
- nop( ); |
|
169 |
- nop( ); |
|
170 |
- nop( ); |
|
171 |
- BUS_WRITE_IDLE( ); // take back write signal |
|
172 |
- } |
|
173 |
- CF_CE_IDLE( ); // take back card enable |
|
174 |
- BUS_DATA_DDR = 0x00; // data back port to input |
|
175 |
- BUS_DATA = 0x00; // turn off pullups |
|
176 |
- return len <= 0 ? 0 : -1; // success if everything has been written |
|
177 |
-} |
|
178 |
- |
|
179 |
-// write constant value to compact flash register multiple times (returns 1 if successful or 0 on error) |
|
180 |
-// - returns 0 on success and -1 on error |
|
181 |
-extern inline char CfWriteRegConst( unsigned char reg, unsigned char val, unsigned short cnt ) // force inlining by using "extern" |
|
182 |
-{ |
|
183 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
184 |
- return -1; // error |
|
185 |
- BUS_DATA = val; // output value |
|
186 |
- BUS_DATA_DDR = 0xFF; // data port to output |
|
187 |
- BUS_ADDR = reg; // output address |
|
188 |
- CF_CE_ACT( ); // set card enable |
|
189 |
- for( ; cnt > 0; cnt-- ) { |
|
190 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
191 |
- break; |
|
192 |
- BUS_WRITE_ACT( ); // activate write signal |
|
193 |
- nop( ); |
|
194 |
- nop( ); |
|
195 |
- nop( ); |
|
196 |
- nop( ); |
|
197 |
- nop( ); |
|
198 |
- nop( ); |
|
199 |
- BUS_WRITE_IDLE( ); // take back write signal |
|
200 |
- } |
|
201 |
- CF_CE_IDLE( ); // take back card enable |
|
202 |
- BUS_DATA_DDR = 0x00; // data back port to input |
|
203 |
- BUS_DATA = 0x00; // turn off pullups |
|
204 |
- return cnt <= 0 ? 0 : -1; // success if everything has been written |
|
205 |
-} |
|
206 |
- |
|
207 |
-// read a compact flash register (returns 1 if successful or 0 on error) |
|
208 |
-// - returns 0 on success and -1 on error |
|
209 |
-extern inline char CfReadReg( unsigned char reg, unsigned char * p_var ) // force inlining by using "extern" |
|
210 |
-{ |
|
211 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
212 |
- return -1; // error |
|
213 |
- BUS_ADDR = reg; // output address |
|
214 |
- CF_CE_ACT( ); // set card enable |
|
215 |
- BUS_READ_ACT( ); // activate read signal |
|
216 |
- nop( ); |
|
217 |
- nop( ); |
|
218 |
- nop( ); |
|
219 |
- nop( ); |
|
220 |
- nop( ); |
|
221 |
- nop( ); |
|
222 |
- *p_var = BUS_DATA_IN; // read data |
|
223 |
- BUS_READ_IDLE( ); // take back read signal |
|
224 |
- CF_CE_IDLE( ); // take back card enable |
|
225 |
- return 0; // success |
|
226 |
-} |
|
227 |
- |
|
228 |
-// read buffer from a compact flash register (returns 1 if successful or 0 on error) |
|
229 |
-// - returns 0 on success and -1 on error |
|
230 |
-extern inline char CfReadRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern" |
|
231 |
-{ |
|
232 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
233 |
- return -1; // error |
|
234 |
- BUS_ADDR = reg; // output address |
|
235 |
- CF_CE_ACT( ); // set card enable |
|
236 |
- for( ; len > 0; p_buf++, len-- ) { |
|
237 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
238 |
- break; |
|
239 |
- BUS_READ_ACT( ); // activate read signal |
|
240 |
- nop( ); |
|
241 |
- nop( ); |
|
242 |
- nop( ); |
|
243 |
- nop( ); |
|
244 |
- nop( ); |
|
245 |
- nop( ); |
|
246 |
- *p_buf = BUS_DATA_IN; // read data |
|
247 |
- BUS_READ_IDLE( ); // take back read signal |
|
248 |
- } |
|
249 |
- CF_CE_IDLE( ); // take back card enable |
|
250 |
- return len <= 0 ? 0 : -1; // success if everything has been read |
|
251 |
-} |
|
252 |
- |
|
253 |
-// read a compact flash register multiple times and throw away data (returns 1 if successful or 0 on error) |
|
254 |
-// - returns 0 on success and -1 on error |
|
255 |
-extern inline char CfReadRegMulti( unsigned char reg, unsigned short cnt ) // force inlining by using "extern" |
|
256 |
-{ |
|
257 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
258 |
- return -1; // error |
|
259 |
- BUS_ADDR = reg; // output address |
|
260 |
- CF_CE_ACT( ); // set card enable |
|
261 |
- for( ; cnt > 0; cnt-- ) { |
|
262 |
- if( ! CF_IS_DETECT( ) || ! CF_IS_READY( ) ) // check that card is present and ready |
|
263 |
- break; |
|
264 |
- BUS_READ_ACT( ); // activate read signal |
|
265 |
- nop( ); |
|
266 |
- nop( ); |
|
267 |
- nop( ); |
|
268 |
- nop( ); |
|
269 |
- nop( ); |
|
270 |
- nop( ); |
|
271 |
- BUS_READ_IDLE( ); // take back read signal |
|
272 |
- } |
|
273 |
- CF_CE_IDLE( ); // take back card enable |
|
274 |
- return cnt <= 0 ? 0 : -1; // success if everything has been read |
|
275 |
-} |
|
276 |
- |
|
277 |
-// compact flash work done |
|
278 |
-static void CfDone( void ) |
|
279 |
-{ |
|
280 |
- debug_cf_printf( "CF done" ); |
|
281 |
- |
|
282 |
- // set working state and step to none |
|
283 |
- CfWorkState = CfWorkNone; |
|
284 |
- CfWorkStep = CfStepNone; |
|
285 |
- |
|
286 |
- // reset state of active command |
|
287 |
- CfSectorNo = 0; |
|
288 |
- CfNextOffset = 0; |
|
289 |
- |
|
290 |
- // disable wait for ready counter |
|
291 |
- CfWaitReady20 = 0; |
|
292 |
-} |
|
293 |
- |
|
294 |
-// compact flash error occured |
|
295 |
-static void CfError( void ) |
|
296 |
-{ |
|
297 |
- debug_cf_printf( "CF error" ); |
|
298 |
- |
|
299 |
- // set insertion state to error |
|
300 |
- CfInsState = CfInsError; |
|
301 |
- |
|
302 |
- // set working state and step to none |
|
303 |
- CfWorkState = CfWorkNone; |
|
304 |
- CfWorkStep = CfStepNone; |
|
305 |
- |
|
306 |
- // reset all information about CF card |
|
307 |
- CfSectorCnt = 0; |
|
308 |
- |
|
309 |
- // reset state of active command |
|
310 |
- CfSectorNo = 0; |
|
311 |
- CfNextOffset = 0; |
|
312 |
- |
|
313 |
- // disable wait for ready counter |
|
314 |
- CfWaitReady20 = 0; |
|
315 |
-} |
|
316 |
- |
|
317 |
-// process compact flash insertion |
|
318 |
-static void CfProcIns( void ) |
|
319 |
-{ |
|
320 |
- switch( CfInsState ) |
|
321 |
- { |
|
322 |
- |
|
323 |
- // no compact flash inserted |
|
324 |
- case CfInsNone: |
|
325 |
- // if compact flash is detected, set state to new CF |
|
326 |
- if( CF_IS_DETECT( ) ) { |
|
327 |
- CfInsState = CfInsNew; |
|
328 |
- debug_cf_printf( "new CF" ); |
|
329 |
- break; |
|
330 |
- } |
|
331 |
- break; |
|
332 |
- |
|
333 |
- // new compact flash has been inserted, wait for powerup |
|
334 |
- case CfInsNew: |
|
335 |
- // if compact flash has been removed, set state to none |
|
336 |
- if( ! CF_IS_DETECT( ) ) { |
|
337 |
- CfInsState = CfInsNone; |
|
338 |
- break; |
|
339 |
- } |
|
340 |
- // set reset |
|
341 |
- CF_RESET_ACT( ); |
|
342 |
- CfInsState = CfInsReset; |
|
343 |
- break; |
|
344 |
- |
|
345 |
- // resetting new compact flash |
|
346 |
- case CfInsReset: |
|
347 |
- // take back reset |
|
348 |
- CF_RESET_IDLE( ); |
|
349 |
- // if compact flash has been removed, set state to none |
|
350 |
- if( ! CF_IS_DETECT( ) ) { |
|
351 |
- CfInsState = CfInsNone; |
|
352 |
- break; |
|
353 |
- } |
|
354 |
- break; |
|
355 |
- |
|
356 |
- // waiting for new compact flash to get ready after reset |
|
357 |
- case CfInsWait: |
|
358 |
- // if compact flash has been removed, set state to none |
|
359 |
- if( ! CF_IS_DETECT( ) ) { |
|
360 |
- CfInsState = CfInsNone; |
|
361 |
- break; |
|
362 |
- } |
|
363 |
- // if compact flash card is ready, set state to ready |
|
364 |
- if( CF_IS_READY( ) ) { |
|
365 |
- CfInsState = CfInsReady; |
|
366 |
- debug_cf_printf( "CF ready" ); |
|
367 |
- } |
|
368 |
- break; |
|
369 |
- |
|
370 |
- // compact flash inserted and ready to work with |
|
371 |
- case CfInsReady: |
|
372 |
- // do nothing here, card work is done by task procedure |
|
373 |
- // (task will detect CF removal or timeout and set state to error) |
|
374 |
- break; |
|
375 |
- |
|
376 |
- // compact flash error occured, compact flash deactivated |
|
377 |
- case CfInsError: |
|
378 |
- // if compact flash has been removed, set state to none |
|
379 |
- if( ! CF_IS_DETECT( ) ) { |
|
380 |
- CfInsState = CfInsNone; |
|
381 |
- debug_cf_printf( "CF removed" ); |
|
382 |
- } |
|
383 |
- break; |
|
384 |
- |
|
385 |
- } // switch( CfInsState ) |
|
386 |
-} |
|
387 |
- |
|
388 |
-// detect compact flash timeout |
|
389 |
-// - called every 20ms |
|
390 |
-static void CfDetectTimeout20( void ) |
|
391 |
-{ |
|
392 |
- // only detect CF timeout if insertion state is ready |
|
393 |
- // (otherwise, the insertion processing is still doing some work) |
|
394 |
- if( CfInsState != CfInsReady ) |
|
395 |
- return; |
|
396 |
- |
|
397 |
- // wait for ready counter not active |
|
398 |
- if( CfWaitReady20 <= 0 ) |
|
399 |
- return; |
|
400 |
- |
|
401 |
- // decrement wait for ready counter |
|
402 |
- CfWaitReady20--; |
|
403 |
- |
|
404 |
- // timeout occured |
|
405 |
- if( CfWaitReady20 <= 0 ) { |
|
406 |
- debug_cf_printf( "timeout while waiting for CF ready" ); |
|
407 |
- CfError( ); |
|
408 |
- } |
|
409 |
-} |
|
410 |
- |
|
411 |
-// continue with identifying compact flash |
|
412 |
-static void CfProcWorkIdentify( void ) |
|
413 |
-{ |
|
414 |
- unsigned char status = 0; |
|
415 |
- unsigned short len, val16; |
|
416 |
- |
|
417 |
- switch( CfWorkStep ) { |
|
418 |
- |
|
419 |
- // no step |
|
420 |
- case CfStepNone: |
|
421 |
- debug_cf_printf( "internal error (identify, CfStepNone)" ); |
|
422 |
- CfError( ); |
|
423 |
- break; |
|
424 |
- |
|
425 |
- // checking command status |
|
426 |
- case CfStepCmdStatus: |
|
427 |
- // read status register |
|
428 |
- CfReadReg( CF_REG_STATUS, &status ); |
|
429 |
- // check that BUSY=0, RDY=1, DWF=0, DSC=1, IDX=0, ERR=0 |
|
430 |
- if( (status & (1 << CF_SB_BUSY | 1 << CF_SB_RDY | 1 << CF_SB_DWF | 1 << CF_SB_DSC | 1 << CF_SB_IDX | 1 << CF_SB_ERR)) != (1 << CF_SB_RDY | 1 << CF_SB_DSC) ) { |
|
431 |
- debug_cf_printf( "unexpected status 0x%02X (identify)", status ); |
|
432 |
- CfError( ); |
|
433 |
- } |
|
434 |
- // continue with data transfer |
|
435 |
- CfWorkStep = CfStepDataTransfer; |
|
436 |
- CfNextOffset = 0; |
|
437 |
- break; |
|
438 |
- |
|
439 |
- // transferring data |
|
440 |
- case CfStepDataTransfer: |
|
441 |
- // still bytes to read |
|
442 |
- if( CfNextOffset < CF_BYTES_IDENTIFY ) { |
|
443 |
- // get number of bytes to read |
|
444 |
- len = CF_BYTES_IDENTIFY - CfNextOffset; |
|
445 |
- if( len > CF_BYTES_AT_ONCE ) |
|
446 |
- len = CF_BYTES_AT_ONCE; |
|
447 |
- // read bytes |
|
448 |
- if( CfReadRegBuf( CF_REG_DATA, &CfSectorBuffer[CfNextOffset], len ) != 0 ) { |
|
449 |
- debug_cf_printf( "reading from CF failed (identify, offset 0x%03X, length 0x%02X)", CfNextOffset, len ); |
|
450 |
- CfError( ); |
|
451 |
- break; |
|
452 |
- } |
|
453 |
- CfNextOffset += len; |
|
454 |
- } |
|
455 |
- // all bytes read |
|
456 |
- if( CfNextOffset >= CF_BYTES_IDENTIFY ) { |
|
457 |
- // check identifier |
|
458 |
- val16 = (unsigned short)CfSectorBuffer[CF_ID_OFS_ID_16 + 0] |
|
459 |
- | (unsigned short)CfSectorBuffer[CF_ID_OFS_ID_16 + 1] << 8; |
|
460 |
- if( val16 != CF_ID ) { |
|
461 |
- debug_cf_printf( "invalid CF identifier: 0x%04X", val16 ); |
|
462 |
- CfError( ); |
|
463 |
- break; |
|
464 |
- } |
|
465 |
- // check if LBA mode is supported |
|
466 |
- val16 = (unsigned short)CfSectorBuffer[CF_ID_OFS_CAPA_16 + 0] |
|
467 |
- | (unsigned short)CfSectorBuffer[CF_ID_OFS_CAPA_16 + 1] << 8; |
|
468 |
- if( (val16 & 1 << CF_CAPA_BIT_LBA) == 0 ) { |
|
469 |
- debug_cf_printf( "CF does not support LBA mode" ); |
|
470 |
- CfError( ); |
|
471 |
- break; |
|
472 |
- } |
|
473 |
- // get number of sectors on CF |
|
474 |
- CfSectorCnt = (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 0] |
|
475 |
- | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 1] << 8 |
|
476 |
- | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 1] << 16 |
|
477 |
- | (unsigned long)CfSectorBuffer[CF_ID_OFS_SEC_CNT_32 + 1] << 24; |
|
478 |
- if( CfSectorCnt <= 0 ) { |
|
479 |
- debug_cf_printf( "CF does not contain any sectors" ); |
|
480 |
- CfError( ); |
|
481 |
- break; |
|
482 |
- } |
|
483 |
- // done |
|
484 |
- CfDone( ); |
|
485 |
- } |
|
486 |
- break; |
|
487 |
- |
|
488 |
- // checking data status |
|
489 |
- case CfStepDataStatus: |
|
490 |
- debug_cf_printf( "internal error (identify, CfStepDataStatus)" ); |
|
491 |
- CfError( ); |
|
492 |
- break; |
|
493 |
- |
|
494 |
- } // switch( CfWorkStep ) |
|
495 |
-} |
|
496 |
- |
|
497 |
-// do normal compact flash work |
|
498 |
-static void CfProcWork( void ) |
|
499 |
-{ |
|
500 |
- // only do CF processing if insertion state is ready |
|
501 |
- // (otherwise, the insertion processing is still doing some work) |
|
502 |
- if( CfInsState != CfInsReady ) |
|
503 |
- return; |
|
504 |
- |
|
505 |
- // compact flash has been removed -> error |
|
506 |
- if( ! CF_IS_DETECT( ) ) { |
|
507 |
- debug_cf_printf( "CF no more present" ); |
|
508 |
- CfError( ); |
|
509 |
- return; |
|
510 |
- } |
|
511 |
- |
|
512 |
- // compact flash is not ready |
|
513 |
- if( ! CF_IS_READY( ) ) { |
|
514 |
- // wait for ready not active --> error |
|
515 |
- if( CfWaitReady20 <= 0 ) { |
|
516 |
- debug_cf_printf( "CF no more ready" ); |
|
517 |
- CfError( ); |
|
518 |
- } |
|
519 |
- // do nothing if CF is not ready |
|
520 |
- return; |
|
521 |
- } |
|
522 |
- |
|
523 |
- switch( CfWorkState ) { |
|
524 |
- |
|
525 |
- // no compact flash work to do |
|
526 |
- case CfWorkNone: |
|
527 |
- // nothing to do here |
|
528 |
- break; |
|
529 |
- |
|
530 |
- // identification of compact flash active |
|
531 |
- case CfWorkIdentify: |
|
532 |
- CfProcWorkIdentify( ); |
|
533 |
- break; |
|
534 |
- |
|
535 |
- } // switch( CfWorkState ) |
|
536 |
-} |
|
537 |
- |
|
538 |
-// identify compact flash |
|
539 |
-// - returns 0 on success, 1 if not idle and -1 on error |
|
540 |
-static char CfIdentify( void ) |
|
541 |
-{ |
|
542 |
- // check that no command is being worked on |
|
543 |
- if( CfWorkState != CfWorkNone ) |
|
544 |
- return 1; |
|
545 |
- |
|
546 |
- debug_cf_printf( "CF identify" ); |
|
547 |
- |
|
548 |
- // issue identify drive command |
|
549 |
- if( CfWriteReg( CF_REG_CMD, CF_CMD_IDENTIFY ) != 0 ) { |
|
550 |
- CfError( ); |
|
551 |
- return -1; |
|
552 |
- } |
|
553 |
- |
|
554 |
- // now identifying compact flash |
|
555 |
- CfWorkState = CfWorkIdentify; |
|
556 |
- CfWorkStep = CfStepCmdStatus; |
|
557 |
- CfNextOffset = 0; |
|
558 |
- CfWaitReady20 = CF_WAIT_READY_20_TIMEOUT; |
|
559 |
- return 0; |
|
560 |
-} |
|
561 |
- |
|
562 |
-// initialize |
|
563 |
-void CfInit( void ) // (extern) |
|
564 |
-{ |
|
565 |
- // setup ports |
|
566 |
- bit_clear( CF_PORT_nCD, CF_BIT_nCD ); // pull-up of card detect pin off (external pull-up is present) |
|
567 |
- bit_clear( CF_DDR_nCD, CF_BIT_nCD ); // card detect pin to input |
|
568 |
- bit_clear( CF_PORT_nRST, CF_BIT_nRST ); // reset pin to LOW |
|
569 |
- bit_set( CF_DDR_nRST, CF_BIT_nRST ); // reset pin to output |
|
570 |
- bit_clear( CF_PORT_RDY, CF_BIT_RDY ); // pull-up of ready pin pin off (external pull-up is present) |
|
571 |
- bit_clear( CF_DDR_RDY, CF_BIT_RDY ); // ready pin to input |
|
572 |
- bit_set( CF_PORT_nCE, CF_BIT_nCE ); // card enable to LOW |
|
573 |
- bit_set( CF_DDR_nCE, CF_BIT_nCE ); // card enable pin to output |
|
574 |
-} |
|
575 |
- |
|
576 |
-// tick procedure - call every 20ms |
|
577 |
-void CfTick20( void ) // (extern) |
|
578 |
-{ |
|
579 |
- // process compact flash insertion |
|
580 |
- CfProcIns( ); |
|
581 |
- |
|
582 |
- // detect compact flash timeout |
|
583 |
- CfDetectTimeout20( ); |
|
584 |
-} |
|
585 |
- |
|
586 |
-// task function to do the work - call from main loop |
|
587 |
-void CfTask( void ) // (extern) |
|
588 |
-{ |
|
589 |
- // do nothing if no CF is inserted |
|
590 |
- if( CfInsState != CfInsReady ) |
|
591 |
- return; |
|
592 |
- |
|
593 |
- // compact flash is ready but not yet identified |
|
594 |
- if( CfSectorCnt == 0 ) { |
|
595 |
- // identify compact flash |
|
596 |
- CfIdentify( ); |
|
597 |
- } |
|
598 |
- |
|
599 |
- // do normal compact flash work |
|
600 |
- CfProcWork( ); |
|
601 |
- |
|
602 |
- // update status |
|
603 |
- StatusInfoCfPresent = CfInsState == CfInsReady; // report working CF if insertion state is ready |
|
604 |
-} |
|
605 |
- |
... | ... |
@@ -1,27 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_cf |
|
9 |
-#define INC_cf |
|
10 |
- |
|
11 |
-// size of a sector in bytes |
|
12 |
-#define CF_SECTOR_SIZE (512) |
|
13 |
- |
|
14 |
-// sector buffer |
|
15 |
-extern unsigned char CfSectorBuffer[CF_SECTOR_SIZE]; |
|
16 |
- |
|
17 |
-// initialize |
|
18 |
-extern void CfInit( void ); |
|
19 |
- |
|
20 |
-// tick procedure - call every 20ms |
|
21 |
-extern void CfTick20( void ); |
|
22 |
- |
|
23 |
-// task function to do the work - call from main loop |
|
24 |
-extern void CfTask( void ); |
|
25 |
- |
|
26 |
-#endif // #ifndef INC_cf |
|
27 |
- |
... | ... |
@@ -1,38 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include "checksum.h" |
|
9 |
-#include "macros.h" |
|
10 |
-#include "nethelp.h" |
|
11 |
- |
|
12 |
-// generate a checksum |
|
13 |
-// also includes Pseudo1 and Pseudo2 in the checksum - set to 0x0000 for normal operation |
|
14 |
-// can also be used to check a checksum (returns 0 if correct) |
|
15 |
-unsigned short Checksum( unsigned char * pData, unsigned short Length, unsigned short Pseudo1, unsigned short Pseudo2 ) // (extern) |
|
16 |
-{ |
|
17 |
- unsigned long sum; |
|
18 |
- |
|
19 |
- // sum up data of pseudo header |
|
20 |
- sum = Pseudo1; // convert to 32 bit first |
|
21 |
- sum += Pseudo2; |
|
22 |
- |
|
23 |
- // add full 16 bit words in header |
|
24 |
- for( ; Length >= 2; pData += 2, Length -= 2 ) |
|
25 |
- sum += ntohs( *(unsigned short *)pData ); |
|
26 |
- |
|
27 |
- // add last byte |
|
28 |
- if( Length >= 1 ) |
|
29 |
- sum += (unsigned short)(*pData << 8); |
|
30 |
- |
|
31 |
- // convert sum to one's complement sum |
|
32 |
- sum = (sum & 0x0000FFFF) + (sum >> 16); // add carries (bits 31..16) to sum (bits 15..0) |
|
33 |
- sum = (sum & 0x0000FFFF) + (sum >> 16); // still a carry possible (from last addition) |
|
34 |
- |
|
35 |
- // return complement of one's complement sum |
|
36 |
- return ~(unsigned short)sum; |
|
37 |
-} |
|
38 |
- |
... | ... |
@@ -1,17 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_checksum |
|
9 |
-#define INC_checksum |
|
10 |
- |
|
11 |
-// generate a checksum |
|
12 |
-// also includes Pseudo1 and Pseudo2 in the checksum - set to 0x0000 for normal operation |
|
13 |
-// can also be used to check a checksum (returns 0 if correct) |
|
14 |
-extern unsigned short Checksum( unsigned char * pData, unsigned short Length, unsigned short Pseudo1, unsigned short Pseudo2 ); |
|
15 |
- |
|
16 |
-#endif // #ifdef INC_checksum |
|
17 |
- |
... | ... |
@@ -1,30 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include "config.h" |
|
9 |
- |
|
10 |
-// MAC address |
|
11 |
-unsigned char ConfigMac[6] = { 0x02, 0xF7, 0xA4, 0xE7, 0x8D, 0xB3 }; // (extern) |
|
12 |
- |
|
13 |
-// IP configuration |
|
14 |
-// - all zero for DHCP |
|
15 |
-unsigned char ConfigIp[4] = { 0, 0, 0, 0 }; // own IP address (extern) |
|
16 |
-unsigned char ConfigMask[4] = { 0, 0, 0, 0 }; // subnet mask (extern) |
|
17 |
-unsigned char ConfigGw[4] = { 0, 0, 0, 0 }; // gateway IP address (extern) |
|
18 |
- |
|
19 |
-// port for S8P |
|
20 |
-unsigned short ConfigS8pPort = 8; // disabled if 0 (extern) |
|
21 |
- |
|
22 |
-// symmetric key for S8P |
|
23 |
-unsigned char ConfigS8pKey[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // (extern) |
|
24 |
- |
|
25 |
-// port for webserver |
|
26 |
-unsigned short ConfigHttpPort = 80; // disabled if 0 (extern) |
|
27 |
- |
|
28 |
-// default output state |
|
29 |
-unsigned char ConfigDefOut = 0x00; // (extern) |
|
30 |
- |
... | ... |
@@ -1,31 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_config |
|
9 |
-#define INC_config |
|
10 |
- |
|
11 |
-// MAC address |
|
12 |
-extern unsigned char ConfigMac[6]; |
|
13 |
- |
|
14 |
-// IP configuration |
|
15 |
-extern unsigned char ConfigIp[4]; // own IP address |
|
16 |
-extern unsigned char ConfigMask[4]; // subnet mask |
|
17 |
-extern unsigned char ConfigGw[4]; // gateway IP address |
|
18 |
- |
|
19 |
-// port for S8P |
|
20 |
-extern unsigned short ConfigS8pPort; // disabled if 0 |
|
21 |
- |
|
22 |
-// symmetric key for S8P |
|
23 |
-extern unsigned char ConfigS8pKey[16]; |
|
24 |
- |
|
25 |
-// port for webserver |
|
26 |
-extern unsigned short ConfigHttpPort; // disabled if 0 |
|
27 |
- |
|
28 |
-// default output state |
|
29 |
-extern unsigned char ConfigDefOut; |
|
30 |
- |
|
31 |
-#endif // #ifndef INC_config |
... | ... |
@@ -1,344 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/io.h> |
|
9 |
-#include <avr/interrupt.h> |
|
10 |
- |
|
11 |
-#include "dart.h" |
|
12 |
-#include "debug.h" |
|
13 |
-#include "macros.h" |
|
14 |
-#include "nethelp.h" |
|
15 |
-#include "udp.h" |
|
16 |
- |
|
17 |
-// dartboard connection |
|
18 |
-// - 7 row pins connected via shottky diode (low passes to dartboard) |
|
19 |
-// - 12 column pins connected directly |
|
20 |
- |
|
21 |
-// IO-Pins |
|
22 |
-// PB0: col10 |
|
23 |
-// PB2: col9 |
|
24 |
-// PB3: col8 |
|
25 |
-// PC[0-7]: col[0-7] |
|
26 |
-// PF[0-6]: row[0-6] |
|
27 |
-// PF7: col11 |
|
28 |
- |
|
29 |
-// constants |
|
30 |
-#define DartRows (7) |
|
31 |
-#define DartCols (12) |
|
32 |
-#define DartFields (DartRows * DartCols) |
|
33 |
-#define DartDisableTicks (5) |
|
34 |
-#define DartQueueSize (16) |
|
35 |
- |
|
36 |
-// if waiting for a field to be hit |
|
37 |
-volatile unsigned char DartActive = 1; |
|
38 |
- |
|
39 |
-// current row being read |
|
40 |
-volatile unsigned char DartRow = DartRows; |
|
41 |
-volatile unsigned char DartRowBits = 1 << DartRows; // always 1 << DartRow |
|
42 |
- |
|
43 |
-// field that has been hit |
|
44 |
-volatile unsigned char DartField = DartFields; |
|
45 |
- |
|
46 |
-// ticks dartboard is disabled |
|
47 |
-// - used after field has been hit to disable board for some time |
|
48 |
-unsigned char DartDisable = 0; |
|
49 |
- |
|
50 |
-// destination to send dart UDP packets to |
|
51 |
-unsigned char DartIp[4]; |
|
52 |
-unsigned short DartPort = 0; |
|
53 |
- |
|
54 |
-// dart queue |
|
55 |
-unsigned char DartQueueStart = 0; |
|
56 |
-unsigned char DartQueueEnd = 0; |
|
57 |
-unsigned char DartQueue[DartQueueSize]; |
|
58 |
- |
|
59 |
-// 128us interrupt (timer 2 overflow) |
|
60 |
-SIGNAL( SIG_OVERFLOW2 ) |
|
61 |
-{ |
|
62 |
- unsigned char b, c, f, col; |
|
63 |
- |
|
64 |
- // do nothing if not waiting for a field to be hit |
|
65 |
- if( ! DartActive ) |
|
66 |
- return; |
|
67 |
- |
|
68 |
- // read inputs |
|
69 |
- b = ~PINB & 0x0D; |
|
70 |
- c = ~PINC; |
|
71 |
- f = ~PINF & 0x80; |
|
72 |
- |
|
73 |
- // check if any input is active |
|
74 |
- // - make common case (no input active) fast |
|
75 |
- if( b | c | f ) { |
|
76 |
- |
|
77 |
- // no column |
|
78 |
- col = DartCols; |
|
79 |
- |
|
80 |
- // find active column (any active column if multiple active) |
|
81 |
- if( b ) { |
|
82 |
- if( b & 0x08 ) col = 8; |
|
83 |
- else if( b & 0x04 ) col = 9; |
|
84 |
- else if( b & 0x01 ) col = 10; |
|
85 |
- } else if( c ) { |
|
86 |
- if( c & 0x0F ) { |
|
87 |
- if( c & 0x01 ) col = 0; |
|
88 |
- else if( c & 0x02 ) col = 1; |
|
89 |
- else if( c & 0x04 ) col = 2; |
|
90 |
- else if( c & 0x08 ) col = 3; |
|
91 |
- } else if( c & 0xF0 ) { |
|
92 |
- if( c & 0x10 ) col = 4; |
|
93 |
- else if( c & 0x20 ) col = 5; |
|
94 |
- else if( c & 0x40 ) col = 6; |
|
95 |
- else if( c & 0x80 ) col = 7; |
|
96 |
- } |
|
97 |
- } else if( f ) { |
|
98 |
- if( f & 0x80 ) col = 11; |
|
99 |
- } |
|
100 |
- |
|
101 |
- // active column found |
|
102 |
- if( col < DartCols ) { |
|
103 |
- // save field number |
|
104 |
- DartField = DartRow * DartCols + col; |
|
105 |
- // do not wait for a field to be hit any more |
|
106 |
- DartActive = 0; |
|
107 |
- } |
|
108 |
- |
|
109 |
- } // if( b | c | f ) |
|
110 |
- |
|
111 |
- // next row |
|
112 |
- DartRow++; |
|
113 |
- DartRowBits <<= 1; |
|
114 |
- if( DartRow >= DartRows ) { |
|
115 |
- DartRow = 0; |
|
116 |
- DartRowBits = 0x01; |
|
117 |
- } |
|
118 |
- |
|
119 |
- // select new row |
|
120 |
- PORTF = 0xFF & ~DartRowBits; |
|
121 |
-} |
|
122 |
- |
|
123 |
-// initialize |
|
124 |
-void DartInit( void ) // (extern) |
|
125 |
-{ |
|
126 |
- // col to input with pull-up |
|
127 |
- // row to output, high |
|
128 |
- PORTB |= 0x0D; |
|
129 |
- DDRB &= ~0x0D; |
|
130 |
- PORTC = 0xFF; |
|
131 |
- DDRC = 0x00; |
|
132 |
- PORTF = 0xFF; |
|
133 |
- DDRF = 0x7F; |
|
134 |
- |
|
135 |
- // configure timer 2 to 128us interval |
|
136 |
- TCCR2 = 0<<FOC2 | 0<<WGM21 | 0<<WGM20 | // normal mode |
|
137 |
- 0<<COM21 | 0<<COM20 | // no waveform generation |
|
138 |
- 0<<CS22 | 1<<CS21 | 0<<CS20; // 1/8 of sysclock (16MHz) -> overflow every 128us |
|
139 |
- |
|
140 |
- // enable timer 2 overflow interrupt |
|
141 |
- TIMSK |= 1<<TOIE2; |
|
142 |
-} |
|
143 |
- |
|
144 |
-// convert field number to meaning |
|
145 |
-void DartField2Meaning( unsigned char field, unsigned char * factor, |
|
146 |
- unsigned char * value ) |
|
147 |
-{ |
|
148 |
- switch( field ) { |
|
149 |
- case 0: *factor = 3; *value = 13; break; |
|
150 |
- case 1: *factor = 1; *value = 18; break; |
|
151 |
- case 2: *factor = 1; *value = 10; break; |
|
152 |
- case 3: *factor = 1; *value = 15; break; |
|
153 |
- case 4: *factor = 2; *value = 15; break; |
|
154 |
- case 5: *factor = 3; *value = 5; break; |
|
155 |
- case 6: *factor = 2; *value = 2; break; |
|
156 |
- case 7: *factor = 1; *value = 2; break; |
|
157 |
- case 8: *factor = 1; *value = 17; break; |
|
158 |
- case 9: *factor = 1; *value = 3; break; |
|
159 |
- case 10: *factor = 1; *value = 8; break; |
|
160 |
- case 11: *factor = 3; *value = 7; break; |
|
161 |
- case 12: *factor = 1; *value = 4; break; |
|
162 |
- case 13: *factor = 3; *value = 6; break; |
|
163 |
- case 14: *factor = 3; *value = 10; break; |
|
164 |
- case 15: *factor = 3; *value = 15; break; |
|
165 |
- case 16: *factor = 0; *value = 0; break; |
|
166 |
- case 17: *factor = 1; *value = 5; break; |
|
167 |
- case 18: *factor = 0; *value = 0; break; |
|
168 |
- case 19: *factor = 1; *value = 2; break; |
|
169 |
- case 20: *factor = 1; *value = 17; break; |
|
170 |
- case 21: *factor = 1; *value = 3; break; |
|
171 |
- case 22: *factor = 1; *value = 19; break; |
|
172 |
- case 23: *factor = 1; *value = 7; break; |
|
173 |
- case 24: *factor = 1; *value = 13; break; |
|
174 |
- case 25: *factor = 1; *value = 6; break; |
|
175 |
- case 26: *factor = 1; *value = 10; break; |
|
176 |
- case 27: *factor = 1; *value = 15; break; |
|
177 |
- case 28: *factor = 2; *value = 25; break; |
|
178 |
- case 29: *factor = 1; *value = 12; break; |
|
179 |
- case 30: *factor = 1; *value = 25; break; |
|
180 |
- case 31: *factor = 3; *value = 2; break; |
|
181 |
- case 32: *factor = 3; *value = 17; break; |
|
182 |
- case 33: *factor = 3; *value = 3; break; |
|
183 |
- case 34: *factor = 3; *value = 19; break; |
|
184 |
- case 35: *factor = 1; *value = 16; break; |
|
185 |
- case 36: *factor = 3; *value = 4; break; |
|
186 |
- case 37: *factor = 1; *value = 6; break; |
|
187 |
- case 38: *factor = 1; *value = 1; break; |
|
188 |
- case 39: *factor = 1; *value = 20; break; |
|
189 |
- case 40: *factor = 2; *value = 10; break; |
|
190 |
- case 41: *factor = 3; *value = 12; break; |
|
191 |
- case 42: *factor = 2; *value = 17; break; |
|
192 |
- case 43: *factor = 1; *value = 9; break; |
|
193 |
- case 44: *factor = 1; *value = 14; break; |
|
194 |
- case 45: *factor = 1; *value = 11; break; |
|
195 |
- case 46: *factor = 1; *value = 19; break; |
|
196 |
- case 47: *factor = 3; *value = 16; break; |
|
197 |
- case 48: *factor = 1; *value = 13; break; |
|
198 |
- case 49: *factor = 3; *value = 18; break; |
|
199 |
- case 50: *factor = 3; *value = 1; break; |
|
200 |
- case 51: *factor = 3; *value = 20; break; |
|
201 |
- case 52: *factor = 2; *value = 6; break; |
|
202 |
- case 53: *factor = 1; *value = 5; break; |
|
203 |
- case 54: *factor = 2; *value = 3; break; |
|
204 |
- case 55: *factor = 3; *value = 9; break; |
|
205 |
- case 56: *factor = 3; *value = 14; break; |
|
206 |
- case 57: *factor = 3; *value = 11; break; |
|
207 |
- case 58: *factor = 3; *value = 8; break; |
|
208 |
- case 59: *factor = 1; *value = 7; break; |
|
209 |
- case 60: *factor = 1; *value = 4; break; |
|
210 |
- case 61: *factor = 1; *value = 18; break; |
|
211 |
- case 62: *factor = 1; *value = 1; break; |
|
212 |
- case 63: *factor = 1; *value = 20; break; |
|
213 |
- case 64: *factor = 2; *value = 13; break; |
|
214 |
- case 65: *factor = 1; *value = 12; break; |
|
215 |
- case 66: *factor = 2; *value = 19; break; |
|
216 |
- case 67: *factor = 1; *value = 9; break; |
|
217 |
- case 68: *factor = 1; *value = 14; break; |
|
218 |
- case 69: *factor = 1; *value = 11; break; |
|
219 |
- case 70: *factor = 1; *value = 8; break; |
|
220 |
- case 71: *factor = 1; *value = 16; break; |
|
221 |
- case 72: *factor = 2; *value = 4; break; |
|
222 |
- case 73: *factor = 2; *value = 18; break; |
|
223 |
- case 74: *factor = 2; *value = 1; break; |
|
224 |
- case 75: *factor = 2; *value = 20; break; |
|
225 |
- case 76: *factor = 2; *value = 5; break; |
|
226 |
- case 77: *factor = 2; *value = 12; break; |
|
227 |
- case 78: *factor = 2; *value = 7; break; |
|
228 |
- case 79: *factor = 2; *value = 9; break; |
|
229 |
- case 80: *factor = 2; *value = 14; break; |
|
230 |
- case 81: *factor = 2; *value = 11; break; |
|
231 |
- case 82: *factor = 2; *value = 8; break; |
|
232 |
- case 83: *factor = 2; *value = 16; break; |
|
233 |
- default: *factor = 0; *value = 0; break; |
|
234 |
- } |
|
235 |
-} |
|
236 |
- |
|
237 |
-// task procedure |
|
238 |
-void DartTask( void ) // (extern) |
|
239 |
-{ |
|
240 |
- unsigned char factor, value, len, idx; |
|
241 |
- struct { |
|
242 |
- struct UdpPacket udp; |
|
243 |
- char text[6]; |
|
244 |
- } data; |
|
245 |
- |
|
246 |
- // a field has been hit |
|
247 |
- if( DartField < DartFields ) { |
|
248 |
- |
|
249 |
- // convert field number to meaning |
|
250 |
- DartField2Meaning( DartField, &factor, &value ); |
|
251 |
- if( factor <= 0 || value <= 0 ) { |
|
252 |
- debug_dart_printf( "field %u hit", DartField ); |
|
253 |
- } else { |
|
254 |
- debug_dart_printf( "%ux%u (field %u) hit", factor, value, DartField ); |
|
255 |
- |
|
256 |
- // put into queue |
|
257 |
- idx = DartQueueEnd + 1; |
|
258 |
- if( idx >= DartQueueSize ) |
|
259 |
- idx = 0; |
|
260 |
- if( idx != DartQueueStart ) { |
|
261 |
- DartQueue[DartQueueEnd] = DartField; |
|
262 |
- DartQueueEnd = idx; |
|
263 |
- } |
|
264 |
- |
|
265 |
- // UDP packets have been requested |
|
266 |
- if( DartPort != 0 ) { |
|
267 |
- len = 0; |
|
268 |
- data.text[len++] = factor + '0'; |
|
269 |
- data.text[len++] = 'x'; |
|
270 |
- if( value >= 10 ) |
|
271 |
- data.text[len++] = value / 10 + '0'; |
|
272 |
- data.text[len++] = value % 10 + '0'; |
|
273 |
- data.text[len++] = '\r'; |
|
274 |
- data.text[len++] = '\n'; |
|
275 |
- // send UDP packet |
|
276 |
- data.udp.UdpHdr.SrcPort = htons( 501 ); |
|
277 |
- data.udp.UdpHdr.DestPort = htons( DartPort ); |
|
278 |
- ip_cpy( data.udp.IpHdr.Dest, DartIp ); |
|
279 |
- UdpSend( (unsigned char *)&data, |
|
280 |
- sizeof( data ) - sizeof( data.text) + len ); |
|
281 |
- } |
|
282 |
- |
|
283 |
- } |
|
284 |
- |
|
285 |
- // reset field |
|
286 |
- DartField = DartFields; |
|
287 |
- // disable dart board for a short time |
|
288 |
- DartDisable = DartDisableTicks; |
|
289 |
- } |
|
290 |
-} |
|
291 |
- |
|
292 |
-// tick procedure - call every 200ms |
|
293 |
-void DartTick200( void ) // (extern) |
|
294 |
-{ |
|
295 |
- // dart board is disabled |
|
296 |
- if( DartDisable > 0 ) { |
|
297 |
- // count down ticks |
|
298 |
- DartDisable--; |
|
299 |
- // disable period elapsed |
|
300 |
- if( DartDisable <= 0 ) { |
|
301 |
- // switch dart board to active |
|
302 |
- DartActive = 1; |
|
303 |
- } |
|
304 |
- } |
|
305 |
-} |
|
306 |
- |
|
307 |
-// a dart request packet has been received |
|
308 |
-void DartRequest( unsigned char ip[4], unsigned short port ) // (extern) |
|
309 |
-{ |
|
310 |
- // save new destination |
|
311 |
- ip_cpy( DartIp, ip ); |
|
312 |
- DartPort = port; |
|
313 |
-} |
|
314 |
- |
|
315 |
-// poll for dart event |
|
316 |
-void DartPoll( unsigned char * factor, unsigned char * value ) // (extern) |
|
317 |
-{ |
|
318 |
- unsigned char field, fac, val; |
|
319 |
- |
|
320 |
- // dart queue empty |
|
321 |
- if( DartQueueStart == DartQueueEnd ) { |
|
322 |
- *factor = 0; |
|
323 |
- *value = 0; |
|
324 |
- return; |
|
325 |
- } |
|
326 |
- |
|
327 |
- // get entry from queue |
|
328 |
- field = DartQueue[DartQueueStart]; |
|
329 |
- DartQueueStart++; |
|
330 |
- if( DartQueueStart >= DartQueueSize ) |
|
331 |
- DartQueueStart = 0; |
|
332 |
- |
|
333 |
- // convert field number to meaning |
|
334 |
- DartField2Meaning( field, &fac, &val ); |
|
335 |
- if( factor <= 0 || value <= 0 ) { |
|
336 |
- debug_dart_printf( "from queue: field %u", field ); |
|
337 |
- } else { |
|
338 |
- debug_dart_printf( "from queue: %ux%u (field %u)", fac, val, field ); |
|
339 |
- } |
|
340 |
- |
|
341 |
- *factor = fac; |
|
342 |
- *value = val; |
|
343 |
-} |
|
344 |
- |
... | ... |
@@ -1,27 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_dart |
|
9 |
-#define INC_dart |
|
10 |
- |
|
11 |
-// initialize |
|
12 |
-extern void DartInit( void ); |
|
13 |
- |
|
14 |
-// task procedure |
|
15 |
-extern void DartTask( void ); |
|
16 |
- |
|
17 |
-// tick procedure - call every 200ms |
|
18 |
-extern void DartTick200( void ); |
|
19 |
- |
|
20 |
-// a dart request packet has been received |
|
21 |
-extern void DartRequest( unsigned char ip[4], unsigned short port ); |
|
22 |
- |
|
23 |
-// poll for dart event |
|
24 |
-extern void DartPoll( unsigned char * factor, unsigned char * value ); |
|
25 |
- |
|
26 |
-#endif // #ifdef INC_dart |
|
27 |
- |
... | ... |
@@ -1,59 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_debug |
|
9 |
-#define INC_debug |
|
10 |
- |
|
11 |
-#include <stdio.h> |
|
12 |
-#include <avr/pgmspace.h> |
|
13 |
- |
|
14 |
-// debug configuration (what to debug) |
|
15 |
-#define DEBUG_INIT 0 |
|
16 |
-#define DEBUG_EEPROM 0 |
|
17 |
-#define DEBUG_CF 0 |
|
18 |
-#define DEBUG_DART 1 |
|
19 |
-#define DEBUG_RTL8019 0 |
|
20 |
-#define DEBUG_ETHER 0 |
|
21 |
-#define DEBUG_ARP 0 |
|
22 |
-#define DEBUG_IP 0 |
|
23 |
-#define DEBUG_ICMP 0 |
|
24 |
-#define DEBUG_UDP 0 |
|
25 |
-#define DEBUG_DHCP 0 |
|
26 |
-#define DEBUG_TCP 0 |
|
27 |
-#define DEBUG_HTTP 1 |
|
28 |
- |
|
29 |
-// debug version of printf |
|
30 |
-#ifdef DEBUG |
|
31 |
-#define debug_printf( fmt, arg... ) \ |
|
32 |
- { \ |
|
33 |
- static const PROGMEM char fmt_pgm[] = fmt"\r\n"; \ |
|
34 |
- char fmt_buf[sizeof( fmt_pgm )]; \ |
|
35 |
- for( int i = 0; i < sizeof( fmt_pgm ); i++ ) \ |
|
36 |
- fmt_buf[i] = (char)pgm_read_byte_near( (uint16_t)fmt_pgm + i ); \ |
|
37 |
- printf( fmt_buf, ##arg ); \ |
|
38 |
- } |
|
39 |
-#else |
|
40 |
-#define debug_printf( fmt, arg... ) { } |
|
41 |
-#endif |
|
42 |
- |
|
43 |
-// specialized debug versions of printf |
|
44 |
-#define debug_specialized_printf( enabled, fmt, arg... ) { if( enabled ) debug_printf( fmt, ##arg ); } |
|
45 |
-#define debug_init_printf( fmt, arg... ) debug_specialized_printf( DEBUG_INIT, "init: "fmt, ##arg ) |
|
46 |
-#define debug_eeprom_printf( fmt, arg... ) debug_specialized_printf( DEBUG_EEPROM, "eeprom: "fmt, ##arg ) |
|
47 |
-#define debug_cf_printf( fmt, arg... ) debug_specialized_printf( DEBUG_CF, "cf: "fmt, ##arg ) |
|
48 |
-#define debug_dart_printf( fmt, arg... ) debug_specialized_printf( DEBUG_DART, "dart: "fmt, ##arg ) |
|
49 |
-#define debug_rtl8019_printf( fmt, arg... ) debug_specialized_printf( DEBUG_RTL8019, "rtl8019: "fmt, ##arg ) |
|
50 |
-#define debug_ether_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ETHER, "ether: "fmt, ##arg ) |
|
51 |
-#define debug_arp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ARP, "arp: "fmt, ##arg ) |
|
52 |
-#define debug_ip_printf( fmt, arg... ) debug_specialized_printf( DEBUG_IP, "ip: "fmt, ##arg ) |
|
53 |
-#define debug_icmp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_ICMP, "icmp: "fmt, ##arg ) |
|
54 |
-#define debug_udp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_UDP, "udp: "fmt, ##arg ) |
|
55 |
-#define debug_dhcp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_DHCP, "dhcp: "fmt, ##arg ) |
|
56 |
-#define debug_tcp_printf( fmt, arg... ) debug_specialized_printf( DEBUG_TCP, "tcp: "fmt, ##arg ) |
|
57 |
-#define debug_http_printf( fmt, arg... ) debug_specialized_printf( DEBUG_HTTP, "http: "fmt, ##arg ) |
|
58 |
- |
|
59 |
-#endif // #ifndef INC_debug |
... | ... |
@@ -1,496 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <string.h> |
|
9 |
- |
|
10 |
-#include "config.h" |
|
11 |
-#include "checksum.h" |
|
12 |
-#include "debug.h" |
|
13 |
-#include "dhcp.h" |
|
14 |
-#include "ethernet.h" |
|
15 |
-#include "ip.h" |
|
16 |
-#include "macros.h" |
|
17 |
-#include "nethelp.h" |
|
18 |
-#include "random.h" |
|
19 |
-#include "udp.h" |
|
20 |
- |
|
21 |
-// configuration |
|
22 |
-static const unsigned char DhcpRetrySecsMax = 10; // avarage timeout after which to retry DHCP action |
|
23 |
-static const unsigned char DhcpRetriesMax = 5; // maximum number of retries before aborting DHCP action |
|
24 |
-static const unsigned long DhcpLeaseRestMin = 300; // when to ask to extend lease |
|
25 |
-static const unsigned char DhcpLeaseRenewFraction = 8; // to renw lease when only this fraction of lease is left |
|
26 |
- |
|
27 |
-// DHCP tick counter to get full seconds |
|
28 |
-static unsigned char DhcpTicks = 0; |
|
29 |
- |
|
30 |
-// time of current DHCP action |
|
31 |
-static unsigned char DhcpInProgress = 0; // if DHCP action is in progress |
|
32 |
-static unsigned char DhcpRetries = 0; // number of retries left |
|
33 |
-static unsigned char DhcpRetrySecs = 0; // rest of time for current retry |
|
34 |
- |
|
35 |
-// current XId |
|
36 |
-static unsigned char DhcpHaveXId = 0; // if an XId exists at the moment |
|
37 |
-static unsigned long DhcpXId = 0; // the current XId data |
|
38 |
-static unsigned int DhcpXIdSecs = 0; // time of XId |
|
39 |
- |
|
40 |
-// DHCP server and lease time |
|
41 |
-static unsigned char DhcpActive = 0; // if own IP is leased from DHCP |
|
42 |
-static unsigned char DhcpServer[4]; // IP address of DHCP server own IP is leased from |
|
43 |
-static unsigned long DhcpLeaseTime = 0; // total lease time |
|
44 |
-static unsigned long DhcpLeaseRest = 0; // rest of lease time |
|
45 |
- |
|
46 |
-// send a DHCP packet |
|
47 |
-// pData must point to a struct DhcpPacket with IpHdr.Dest, DhcpHdr.XId |
|
48 |
-// DhcpHdr.Secs, DhcpHdr.Flags and DhcpHdr.YIAddr already initialized |
|
49 |
-static void DhcpSend( unsigned char * pData, unsigned short Length ) // (extern) |
|
50 |
-{ |
|
51 |
- struct DhcpPacket * pDhcpPack; |
|
52 |
- |
|
53 |
- // packet too short |
|
54 |
- if( Length < sizeof( struct DhcpPacket ) ) |
|
55 |
- return; |
|
56 |
- |
|
57 |
- // convert pointer to DHCP packet |
|
58 |
- // (this saves us from always casting pData) |
|
59 |
- pDhcpPack = (struct DhcpPacket *)pData; |
|
60 |
- |
|
61 |
- debug_dhcp_printf( "send xid=%08lX len=%d", |
|
62 |
- ntohl( pDhcpPack->DhcpHdr.XId ), Length ); |
|
63 |
- |
|
64 |
- // we are DHCP client |
|
65 |
- // - source port must be 68 |
|
66 |
- // - destination port must be 67 |
|
67 |
- pDhcpPack->UdpHdr.SrcPort = htons( 68 ); |
|
68 |
- pDhcpPack->UdpHdr.DestPort = htons( 67 ); |
|
69 |
- // set up DHCP header fields as client |
|
70 |
- pDhcpPack->DhcpHdr.Op = 1; |
|
71 |
- pDhcpPack->DhcpHdr.HType = 1; |
|
72 |
- pDhcpPack->DhcpHdr.HLen = 6; |
|
73 |
- pDhcpPack->DhcpHdr.HOps = 0; |
|
74 |
- memset( pDhcpPack->DhcpHdr.CIAddr, 0, 4 ); |
|
75 |
- memset( pDhcpPack->DhcpHdr.SIAddr, 0, 4 ); |
|
76 |
- memset( pDhcpPack->DhcpHdr.GIAddr, 0, 4 ); |
|
77 |
- mac_cpy( pDhcpPack->DhcpHdr.CHAddr, ConfigMac ); |
|
78 |
- memset( pDhcpPack->DhcpHdr.CHAddr + 6, 0, 10 ); |
|
79 |
- memset( pDhcpPack->DhcpHdr.SName, 0, 64 ); |
|
80 |
- memset( pDhcpPack->DhcpHdr.File, 0, 128 ); |
|
81 |
- pDhcpPack->DhcpHdr.MCookie = htonl( 0x63825363 ); |
|
82 |
- |
|
83 |
- // send DHCP packet |
|
84 |
- UdpSend( pData, Length ); |
|
85 |
-} |
|
86 |
- |
|
87 |
-// send a DHCP discover |
|
88 |
-static void DhcpDiscover( void ) |
|
89 |
-{ |
|
90 |
- struct { |
|
91 |
- struct DhcpPacket DhcpPack; |
|
92 |
- unsigned char OptType[3]; |
|
93 |
- unsigned char OptEnd[2]; |
|
94 |
- } DhcpDiscover; |
|
95 |
- |
|
96 |
- debug_dhcp_printf( "discover" ); |
|
97 |
- |
|
98 |
- ip_cpy( DhcpDiscover.DhcpPack.IpHdr.Dest, "\xFF\xFF\xFF\xFF" ); // broadcast |
|
99 |
- DhcpDiscover.DhcpPack.DhcpHdr.XId = htonl( DhcpXId ); |
|
100 |
- DhcpDiscover.DhcpPack.DhcpHdr.Secs = htons( DhcpXIdSecs ); // use time of XId |
|
101 |
- DhcpDiscover.DhcpPack.DhcpHdr.Flags = htons( 0x8000 ); // broadcast |
|
102 |
- memset( DhcpDiscover.DhcpPack.DhcpHdr.YIAddr, 0, 4 ); |
|
103 |
- DhcpDiscover.OptType[0] = 0x35; // DHCP discover |
|
104 |
- DhcpDiscover.OptType[1] = 0x01; |
|
105 |
- DhcpDiscover.OptType[2] = 0x01; |
|
106 |
- DhcpDiscover.OptEnd[0] = 0xFF; // end of options |
|
107 |
- DhcpDiscover.OptEnd[1] = 0x00; |
|
108 |
- |
|
109 |
- DhcpSend( (unsigned char *)&DhcpDiscover, sizeof( DhcpDiscover ) ); |
|
110 |
-} |
|
111 |
- |
|
112 |
-// send a DHCP request |
|
113 |
-static void DhcpRequest( void ) |
|
114 |
-{ |
|
115 |
- struct { |
|
116 |
- struct DhcpPacket DhcpPack; |
|
117 |
- unsigned char OptType[3]; |
|
118 |
- unsigned char OptReq[6]; |
|
119 |
- unsigned char OptServer[6]; |
|
120 |
- unsigned char OptEnd[2]; |
|
121 |
- } DhcpRequest; |
|
122 |
- |
|
123 |
- debug_dhcp_printf( "request ip=%d.%d.%d.%d", |
|
124 |
- ConfigIp[0], ConfigIp[1], ConfigIp[2], ConfigIp[3] ); |
|
125 |
- |
|
126 |
- ip_cpy( DhcpRequest.DhcpPack.IpHdr.Dest, DhcpServer ); // send to DHCP server |
|
127 |
- DhcpRequest.DhcpPack.DhcpHdr.XId = htonl( DhcpXId ); |
|
128 |
- DhcpRequest.DhcpPack.DhcpHdr.Secs = htons( DhcpXIdSecs ); // use time of XId |
|
129 |
- DhcpRequest.DhcpPack.DhcpHdr.Flags = htons( 0x0000 ); |
|
130 |
- ip_cpy( DhcpRequest.DhcpPack.DhcpHdr.YIAddr, ConfigIp ); |
|
131 |
- DhcpRequest.OptType[0] = 0x35; // DHCP request |
|
132 |
- DhcpRequest.OptType[1] = 0x01; |
|
133 |
- DhcpRequest.OptType[2] = 0x03; |
|
134 |
- DhcpRequest.OptReq[0] = 0x32; // requested IP |
|
135 |
- DhcpRequest.OptReq[1] = 0x04; |
|
136 |
- ip_cpy( &DhcpRequest.OptReq[2], ConfigIp ); |
|
137 |
- DhcpRequest.OptServer[0] = 0x36; // DHCP server |
|
138 |
- DhcpRequest.OptServer[1] = 0x04; |
|
139 |
- ip_cpy( &DhcpRequest.OptServer[2], DhcpServer ); |
|
140 |
- DhcpRequest.OptEnd[0] = 0xFF; // end of options |
|
141 |
- DhcpRequest.OptEnd[1] = 0x00; |
|
142 |
- |
|
143 |
- DhcpSend( (unsigned char *)&DhcpRequest, sizeof( DhcpRequest ) ); |
|
144 |
-} |
|
145 |
- |
|
146 |
-// abort DHCP action |
|
147 |
-static void DhcpAbort( void ) |
|
148 |
-{ |
|
149 |
- // abort DHCP action |
|
150 |
- DhcpInProgress = 0; |
|
151 |
- DhcpRetries = 0; |
|
152 |
- DhcpRetrySecs = 0; |
|
153 |
- |
|
154 |
- // forget XId |
|
155 |
- DhcpHaveXId = 0; |
|
156 |
- DhcpXId = 0; |
|
157 |
- DhcpXIdSecs = 0; |
|
158 |
- |
|
159 |
- // give up IP address if it was leased |
|
160 |
- if( DhcpActive ) { |
|
161 |
- ip_cpy( ConfigIp, "\0\0\0\0" ); |
|
162 |
- ip_cpy( ConfigMask, "\0\0\0\0" ); |
|
163 |
- ip_cpy( ConfigGw, "\0\0\0\0" ); |
|
164 |
- DhcpActive = 0; |
|
165 |
- DhcpLeaseTime = 0; |
|
166 |
- DhcpLeaseRest = 0; |
|
167 |
- } |
|
168 |
-} |
|
169 |
- |
|
170 |
-// retry DHCP action |
|
171 |
-static void DhcpRetry( void ) |
|
172 |
-{ |
|
173 |
- // DHCP lease not active ---> re-send DHCP discover |
|
174 |
- if( ! DhcpActive ) { |
|
175 |
- |
|
176 |
- // get time for next try |
|
177 |
- RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) ); |
|
178 |
- DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2; |
|
179 |
- // re-send DHCP discover |
|
180 |
- DhcpDiscover( ); |
|
181 |
- |
|
182 |
- } |
|
183 |
- |
|
184 |
- // DHCP lease active and lease time almost over ---> re-send DHCP request |
|
185 |
- if( DhcpActive && (DhcpLeaseRest < DhcpLeaseRestMin || |
|
186 |
- DhcpLeaseRest < DhcpLeaseTime / DhcpLeaseRenewFraction) ) { |
|
187 |
- |
|
188 |
- // get time for next try |
|
189 |
- RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) ); |
|
190 |
- DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2; |
|
191 |
- // re-send DHCP request |
|
192 |
- DhcpRequest( ); |
|
193 |
- |
|
194 |
- } |
|
195 |
-} |
|
196 |
- |
|
197 |
-// start new DHCP action |
|
198 |
-static void DhcpStart( void ) |
|
199 |
-{ |
|
200 |
- // DHCP lease not active ---> DHCP discover |
|
201 |
- if( ! DhcpActive ) { |
|
202 |
- |
|
203 |
- // DHCP operation starts |
|
204 |
- DhcpInProgress = 1; |
|
205 |
- DhcpRetries = DhcpRetriesMax; |
|
206 |
- RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) ); |
|
207 |
- DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2; |
|
208 |
- // get new XId |
|
209 |
- RandomGetData( (unsigned char *)&DhcpXId, sizeof( DhcpXId ) ); |
|
210 |
- DhcpXIdSecs++; |
|
211 |
- DhcpHaveXId = 1; |
|
212 |
- // send DHCP discover |
|
213 |
- DhcpDiscover( ); |
|
214 |
- |
|
215 |
- } |
|
216 |
- |
|
217 |
- // DHCP lease active and lease time almost over ---> DHCP request |
|
218 |
- if( DhcpActive && (DhcpLeaseRest < DhcpLeaseRestMin || |
|
219 |
- DhcpLeaseRest < DhcpLeaseTime / DhcpLeaseRenewFraction) ) { |
|
220 |
- |
|
221 |
- // DHCP operation starts |
|
222 |
- DhcpInProgress = 1; |
|
223 |
- DhcpRetries = DhcpRetriesMax; |
|
224 |
- RandomGetData( (unsigned char *)&DhcpRetrySecs, sizeof( DhcpRetrySecs ) ); |
|
225 |
- DhcpRetrySecs = DhcpRetrySecs % DhcpRetrySecsMax + DhcpRetrySecsMax / 2; |
|
226 |
- // get new XId if none available |
|
227 |
- if( ! DhcpHaveXId ) { |
|
228 |
- RandomGetData( (unsigned char *)&DhcpXId, sizeof( DhcpXId ) ); |
|
229 |
- DhcpXIdSecs++; |
|
230 |
- DhcpHaveXId = 1; |
|
231 |
- } |
|
232 |
- // send DHCP request |
|
233 |
- DhcpRequest( ); |
|
234 |
- |
|
235 |
- } |
|
236 |
-} |
|
237 |
- |
|
238 |
-// tick procedure - every 1000ms |
|
239 |
-static void DhcpTick1000( void ) |
|
240 |
-{ |
|
241 |
- // DHCP operation in progress |
|
242 |
- if( DhcpInProgress ) { |
|
243 |
- |
|
244 |
- // count down time of current try of current action |
|
245 |
- DhcpRetrySecs--; |
|
246 |
- if( DhcpRetrySecs <= 0 ) { |
|
247 |
- |
|
248 |
- // count down retries |
|
249 |
- DhcpRetries--; |
|
250 |
- |
|
251 |
- // no more retries left ---> abort, retry otherwise |
|
252 |
- if( DhcpRetries <= 0 ) |
|
253 |
- DhcpAbort( ); |
|
254 |
- else |
|
255 |
- DhcpRetry( ); |
|
256 |
- |
|
257 |
- } |
|
258 |
- |
|
259 |
- } |
|
260 |
- |
|
261 |
- // increase time of XId |
|
262 |
- DhcpXIdSecs++; |
|
263 |
- |
|
264 |
- // dcrease remaining lease time |
|
265 |
- DhcpLeaseRest--; |
|
266 |
- // lease timed out ---> abort DHCP (will also invalidate IP) |
|
267 |
- if( DhcpLeaseRest <= 0 ) { |
|
268 |
- debug_dhcp_printf( "lease expired" ); |
|
269 |
- DhcpAbort( ); |
|
270 |
- } |
|
271 |
-} |
|
272 |
- |
|
273 |
-// tick procedure - call every 200ms |
|
274 |
-void DhcpTick200( void ) // (extern) |
|
275 |
-{ |
|
276 |
- // get 1 second interval |
|
277 |
- DhcpTicks++; |
|
278 |
- if( DhcpTicks >= 5 ) { |
|
279 |
- DhcpTicks = 0; |
|
280 |
- DhcpTick1000( ); |
|
281 |
- } |
|
282 |
- |
|
283 |
- // no DHCP operation in progress |
|
284 |
- if( ! DhcpInProgress ) { |
|
285 |
- // DHCP lease active or no IP address ---> DHCP allowed (i.e. no static IP) |
|
286 |
- if( DhcpActive || ip_eq( ConfigIp, "\0\0\0\0" ) ) { |
|
287 |
- // start new DHCP action |
|
288 |
- DhcpStart( ); |
|
289 |
- } |
|
290 |
- } |
|
291 |
-} |
|
292 |
- |
|
293 |
-// process a received DHCP offer |
|
294 |
-static void DhcpOffer( unsigned char addr[4], unsigned char mask[4], |
|
295 |
- unsigned char gateway[4], unsigned long time, |
|
296 |
- unsigned char server[4] ) |
|
297 |
-{ |
|
298 |
- debug_dhcp_printf( "offer addr=%d.%d.%d.%d mask=%d.%d.%d.%d gw=%d.%d.%d.%d", |
|
299 |
- addr[0], addr[1], addr[2], addr[3], |
|
300 |
- mask[0], mask[1], mask[2], mask[3], |
|
301 |
- gateway[0], gateway[1], gateway[2], gateway[3] ); |
|
302 |
- debug_dhcp_printf( "offer time=%ld server=%d.%d.%d.%d", |
|
303 |
- time, server[0], server[1], server[2], server[3] ); |
|
304 |
- |
|
305 |
- // use this IP address, mask and gateway |
|
306 |
- ip_cpy( ConfigIp, addr ); |
|
307 |
- ip_cpy( ConfigMask, mask ); |
|
308 |
- ip_cpy( ConfigGw, gateway ); |
|
309 |
- |
|
310 |
- // store DHCP server and lease time |
|
311 |
- DhcpActive = 1; |
|
312 |
- ip_cpy( DhcpServer, server ); |
|
313 |
- DhcpLeaseTime = time; |
|
314 |
- DhcpLeaseRest = DhcpLeaseRestMin; // schedule DHCP request |
|
315 |
- |
|
316 |
- // DHCP action finished |
|
317 |
- DhcpInProgress = 0; |
|
318 |
- DhcpRetries = 0; |
|
319 |
- DhcpRetrySecs = 0; |
|
320 |
-} |
|
321 |
- |
|
322 |
-// process a received DHCP ack |
|
323 |
-static void DhcpAck( unsigned char addr[4], unsigned char mask[4], |
|
324 |
- unsigned char gateway[4], unsigned long time, |
|
325 |
- unsigned char server[4] ) |
|
326 |
-{ |
|
327 |
- debug_dhcp_printf( "ack addr=%d.%d.%d.%d mask=%d.%d.%d.%d gw=%d.%d.%d.%d", |
|
328 |
- addr[0], addr[1], addr[2], addr[3], |
|
329 |
- mask[0], mask[1], mask[2], mask[3], |
|
330 |
- gateway[0], gateway[1], gateway[2], gateway[3] ); |
|
331 |
- debug_dhcp_printf( "ack time=%ld server=%d.%d.%d.%d", |
|
332 |
- time, server[0], server[1], server[2], server[3] ); |
|
333 |
- |
|
334 |
- // check if IP address, mask and gateway match |
|
335 |
- if( ! ip_eq( ConfigIp, addr ) || |
|
336 |
- ! ip_eq( ConfigMask, mask ) || |
|
337 |
- ! ip_eq( ConfigGw, gateway ) ) |
|
338 |
- { |
|
339 |
- // mismatch ---> something is wrong, abort |
|
340 |
- DhcpAbort( ); |
|
341 |
- return; |
|
342 |
- } |
|
343 |
- |
|
344 |
- // store DHCP server and lease time |
|
345 |
- DhcpActive = 1; |
|
346 |
- ip_cpy( DhcpServer, server ); |
|
347 |
- DhcpLeaseTime = time; |
|
348 |
- DhcpLeaseRest = time; |
|
349 |
- |
|
350 |
- // DHCP action finished |
|
351 |
- DhcpInProgress = 0; |
|
352 |
- DhcpRetries = 0; |
|
353 |
- DhcpRetrySecs = 0; |
|
354 |
- |
|
355 |
- // forget XId |
|
356 |
- DhcpHaveXId = 0; |
|
357 |
- DhcpXId = 0; |
|
358 |
- DhcpXIdSecs = 0; |
|
359 |
-} |
|
360 |
- |
|
361 |
-// process a received DHCP packet |
|
362 |
-void DhcpRecv( unsigned char * pData, unsigned short Length ) // (extern) |
|
363 |
-{ |
|
364 |
- struct DhcpPacket * pDhcpPack; |
|
365 |
- unsigned char *opt_ptr, tag, len; |
|
366 |
- unsigned short opt_len; |
|
367 |
- unsigned char type; |
|
368 |
- unsigned char have_mask, mask[4], have_gateway, gateway[4]; |
|
369 |
- unsigned char have_time, have_server, server[4]; |
|
370 |
- unsigned long time; |
|
371 |
- |
|
372 |
- // packet too short |
|
373 |
- if( Length < sizeof( struct DhcpPacket ) ) |
|
374 |
- return; |
|
375 |
- |
|
376 |
- // convert pointer to UDP packet |
|
377 |
- // (this saves us from always casting pData) |
|
378 |
- pDhcpPack = (struct DhcpPacket *)pData; |
|
379 |
- |
|
380 |
- // we are DHCP client |
|
381 |
- // - source port must be 67 |
|
382 |
- // - destination port must be 68 |
|
383 |
- if( pDhcpPack->UdpHdr.SrcPort != htons( 67 ) || |
|
384 |
- pDhcpPack->UdpHdr.DestPort != htons( 68 ) ) |
|
385 |
- return; |
|
386 |
- // check DHCP fields |
|
387 |
- if( pDhcpPack->DhcpHdr.Op != 2 || |
|
388 |
- pDhcpPack->DhcpHdr.HType != 1 || |
|
389 |
- pDhcpPack->DhcpHdr.HLen != 6 || |
|
390 |
- pDhcpPack->DhcpHdr.HOps != 0 || |
|
391 |
- pDhcpPack->DhcpHdr.MCookie != htonl( 0x63825363 ) ) |
|
392 |
- return; |
|
393 |
- |
|
394 |
- debug_dhcp_printf( "recv xid=%08lX len=%d", |
|
395 |
- ntohl( pDhcpPack->DhcpHdr.XId ), Length ); |
|
396 |
- |
|
397 |
- // check XId |
|
398 |
- if( ! DhcpHaveXId || ntohl( pDhcpPack->DhcpHdr.XId ) != DhcpXId ) |
|
399 |
- return; |
|
400 |
- |
|
401 |
- // get options |
|
402 |
- opt_ptr = pData + sizeof( struct DhcpPacket ); |
|
403 |
- opt_len = Length - sizeof( struct DhcpPacket ); |
|
404 |
- |
|
405 |
- // parse options |
|
406 |
- type = 0; |
|
407 |
- have_mask = 0; |
|
408 |
- have_gateway = 0; |
|
409 |
- time = 0; |
|
410 |
- have_time = 0; |
|
411 |
- have_server = 0; |
|
412 |
- while( opt_len > 2 ) { |
|
413 |
- |
|
414 |
- // get tag and length |
|
415 |
- tag = *opt_ptr++; |
|
416 |
- len = *opt_ptr++; |
|
417 |
- if( opt_len < 2 + len ) |
|
418 |
- break; |
|
419 |
- |
|
420 |
- // get option |
|
421 |
- switch( tag ) { |
|
422 |
- |
|
423 |
- // type |
|
424 |
- case 0x35: |
|
425 |
- if( len >= 1 ) |
|
426 |
- type = opt_ptr[0]; |
|
427 |
- break; |
|
428 |
- |
|
429 |
- // subnet mask |
|
430 |
- case 0x01: |
|
431 |
- if( len >= 4 ) |
|
432 |
- memcpy( mask, opt_ptr, 4 ); |
|
433 |
- have_mask = 1; |
|
434 |
- break; |
|
435 |
- |
|
436 |
- // gateway |
|
437 |
- case 0x03: |
|
438 |
- if( len >= 4 ) { |
|
439 |
- memcpy( gateway, opt_ptr, 4 ); |
|
440 |
- have_gateway = 1; |
|
441 |
- } |
|
442 |
- break; |
|
443 |
- |
|
444 |
- // lease time |
|
445 |
- case 0x33: |
|
446 |
- if( len >= 4 ) { |
|
447 |
- time = ntohl( *(unsigned long *)opt_ptr ); |
|
448 |
- have_time = 1; |
|
449 |
- } |
|
450 |
- break; |
|
451 |
- |
|
452 |
- // DHCP server |
|
453 |
- case 0x36: |
|
454 |
- if( len >= 4 ) { |
|
455 |
- memcpy( server, opt_ptr, 4 ); |
|
456 |
- have_server = 1; |
|
457 |
- } |
|
458 |
- break; |
|
459 |
- |
|
460 |
- } |
|
461 |
- |
|
462 |
- // skip option |
|
463 |
- opt_ptr += len; |
|
464 |
- opt_len -= len; |
|
465 |
- } |
|
466 |
- |
|
467 |
- debug_dhcp_printf( "type=%d%s%s%s%s", type, |
|
468 |
- have_mask ? " mask" : "", |
|
469 |
- have_gateway ? " gateway" : "", |
|
470 |
- have_time ? " time" : "", |
|
471 |
- have_server ? " server" : "" ); |
|
472 |
- |
|
473 |
- // fill in server from source address if not present |
|
474 |
- if( ! have_server ) { |
|
475 |
- ip_cpy( server, pDhcpPack->IpHdr.Src ); |
|
476 |
- have_server = 1; |
|
477 |
- } |
|
478 |
- |
|
479 |
- // process DHCP response |
|
480 |
- switch( type ) { |
|
481 |
- |
|
482 |
- // DHCP offer |
|
483 |
- case 2: |
|
484 |
- if( have_mask && have_gateway && have_time && have_server ) |
|
485 |
- DhcpOffer( pDhcpPack->DhcpHdr.YIAddr, mask, gateway, time, server ); |
|
486 |
- break; |
|
487 |
- |
|
488 |
- // DHCP ack |
|
489 |
- case 5: |
|
490 |
- if( have_mask && have_gateway && have_time && have_server ) |
|
491 |
- DhcpAck( pDhcpPack->DhcpHdr.YIAddr, mask, gateway, time, server ); |
|
492 |
- break; |
|
493 |
- |
|
494 |
- } |
|
495 |
-} |
|
496 |
- |
... | ... |
@@ -1,51 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_dhcp |
|
9 |
-#define INC_dhcp |
|
10 |
- |
|
11 |
-#include "ethernet.h" |
|
12 |
-#include "ip.h" |
|
13 |
-#include "udp.h" |
|
14 |
- |
|
15 |
-// header of an DHCP packet |
|
16 |
-struct DhcpHeader |
|
17 |
-{ |
|
18 |
- unsigned char Op; |
|
19 |
- unsigned char HType; |
|
20 |
- unsigned char HLen; |
|
21 |
- unsigned char HOps; |
|
22 |
- unsigned long XId; |
|
23 |
- unsigned int Secs; |
|
24 |
- unsigned int Flags; |
|
25 |
- unsigned char CIAddr[4]; |
|
26 |
- unsigned char YIAddr[4]; |
|
27 |
- unsigned char SIAddr[4]; |
|
28 |
- unsigned char GIAddr[4]; |
|
29 |
- unsigned char CHAddr[16]; |
|
30 |
- unsigned char SName[64]; |
|
31 |
- unsigned char File[128]; |
|
32 |
- unsigned long MCookie; |
|
33 |
-}; |
|
34 |
- |
|
35 |
-// a DHCP packet |
|
36 |
-struct DhcpPacket |
|
37 |
-{ |
|
38 |
- struct EthernetHeader EthHdr; |
|
39 |
- struct IpHeader IpHdr; |
|
40 |
- struct UdpHeader UdpHdr; |
|
41 |
- struct DhcpHeader DhcpHdr; |
|
42 |
-}; |
|
43 |
- |
|
44 |
-// tick procedure - call every 200ms |
|
45 |
-extern void DhcpTick200( void ); |
|
46 |
- |
|
47 |
-// process a received UDP packet |
|
48 |
-extern void DhcpRecv( unsigned char * pData, unsigned short Length ); |
|
49 |
- |
|
50 |
-#endif // #ifdef INC_dhcp |
|
51 |
- |
... | ... |
@@ -1,217 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/interrupt.h> |
|
9 |
-#include <avr/eeprom.h> |
|
10 |
- |
|
11 |
-#include "config.h" |
|
12 |
-#include "debug.h" |
|
13 |
-#include "eeprom.h" |
|
14 |
-#include "macros.h" |
|
15 |
-#include "rtl8019.h" |
|
16 |
- |
|
17 |
-// flags for what needs to be written to the EEPROM |
|
18 |
-unsigned char EepromNeedWrite = 0x00; // (extern) |
|
19 |
- |
|
20 |
-// writing what where |
|
21 |
-unsigned char EepromWriteFlags = 0; // some flags |
|
22 |
-#define EepromWriteFlagActive 0x01 // if writing something to EEPROM |
|
23 |
-#define EepromWriteFlagCheck 0x02 // if writing check byte to EEPROM |
|
24 |
-unsigned char * pEepromWriteSrc; // pointer to source data |
|
25 |
-unsigned short EepromWriteDestAddr; // destination address in EEPROM |
|
26 |
-unsigned char EepromWriteCnt; // number of bytes still to write |
|
27 |
- |
|
28 |
-// memory layout of EEPROM |
|
29 |
-// - every byte B is stored as B, ~B for data safety |
|
30 |
-// - so everythings needs double space |
|
31 |
-#define EEPROM_ADDR_MAC 0 |
|
32 |
-#define EEPROM_ADDR_IP (EEPROM_ADDR_MAC + 2 * sizeof( ConfigMac )) |
|
33 |
-#define EEPROM_ADDR_MASK (EEPROM_ADDR_IP + 2 * sizeof( ConfigIp )) |
|
34 |
-#define EEPROM_ADDR_GW (EEPROM_ADDR_MASK + 2 * sizeof( ConfigMask )) |
|
35 |
-#define EEPROM_ADDR_S8P_PORT (EEPROM_ADDR_GW + 2 * sizeof( ConfigGw )) |
|
36 |
-#define EEPROM_ADDR_S8P_KEY (EEPROM_ADDR_S8P_PORT + 2 * sizeof( ConfigS8pPort )) |
|
37 |
-#define EEPROM_ADDR_HTTP_PORT (EEPROM_ADDR_S8P_KEY + 2 * sizeof( ConfigS8pKey )) |
|
38 |
-#define EEPROM_ADDR_DEF_OUT (EEPROM_ADDR_HTTP_PORT + 2 * sizeof( ConfigHttpPort )) |
|
39 |
-#define EEPROM_ADDR_FreeFromHere (EEPROM_ADDR_DEF_OUT + 2 * sizeof( ConfigDefOut )) |
|
40 |
- |
|
41 |
-// get configuration from EEPROM - helper function |
|
42 |
-// checks data in EEPROM |
|
43 |
-// gets data from EEPROM |
|
44 |
-// returns 0x00 if successful |
|
45 |
-static inline unsigned char EepromGetConfigHelp( unsigned short SrcAddr, unsigned char * pDest, unsigned char Len ) |
|
46 |
-{ |
|
47 |
- unsigned char i, b; |
|
48 |
- |
|
49 |
- // check data in EEPROM |
|
50 |
- EEAR = SrcAddr; |
|
51 |
- for( i = 0; i < Len; i++ ) |
|
52 |
- { |
|
53 |
- // read byte |
|
54 |
- bit_set( EECR, EERE ); |
|
55 |
- b = EEDR; |
|
56 |
- EEAR++; |
|
57 |
- // XOR in check byte |
|
58 |
- bit_set( EECR, EERE ); |
|
59 |
- b ^= EEDR; |
|
60 |
- EEAR++; |
|
61 |
- // XOR result must be 0xFF |
|
62 |
- if( b != 0xFF ) |
|
63 |
- return 0x01; // error |
|
64 |
- } |
|
65 |
- |
|
66 |
- // read data from EEPROM |
|
67 |
- EEAR = SrcAddr; |
|
68 |
- for( ; Len > 0; Len-- ) |
|
69 |
- { |
|
70 |
- // read byte |
|
71 |
- bit_set( EECR, EERE ); |
|
72 |
- *(pDest++) = EEDR; |
|
73 |
- EEAR += 2; // skip check byte |
|
74 |
- } |
|
75 |
- return 0x00; // success |
|
76 |
-} |
|
77 |
- |
|
78 |
-// get configuration from EEPROM |
|
79 |
-void EepromGetConfig( void ) // (extern) |
|
80 |
-{ |
|
81 |
- // get MAC |
|
82 |
- if( EepromGetConfigHelp( EEPROM_ADDR_MAC, ConfigMac, sizeof( ConfigMac ) ) == 0x00 ) |
|
83 |
- // re-initialize RTL8019 |
|
84 |
- RtlReinit( ); |
|
85 |
- |
|
86 |
- // get IP, subnet mask, gateway IP |
|
87 |
- EepromGetConfigHelp( EEPROM_ADDR_IP, ConfigIp, sizeof( ConfigIp ) ); |
|
88 |
- EepromGetConfigHelp( EEPROM_ADDR_MASK, ConfigMask, sizeof( ConfigMask ) ); |
|
89 |
- EepromGetConfigHelp( EEPROM_ADDR_GW, ConfigGw, sizeof( ConfigGw ) ); |
|
90 |
- |
|
91 |
- // get port for S8P |
|
92 |
- EepromGetConfigHelp( EEPROM_ADDR_S8P_PORT, (unsigned char *)&ConfigS8pPort, sizeof( ConfigS8pPort ) ); |
|
93 |
- |
|
94 |
- // get symmetric key for S8P |
|
95 |
- EepromGetConfigHelp( EEPROM_ADDR_S8P_KEY, ConfigS8pKey, sizeof( ConfigS8pKey ) ); |
|
96 |
- |
|
97 |
- // get port for webserver |
|
98 |
- EepromGetConfigHelp( EEPROM_ADDR_HTTP_PORT, (unsigned char *)&ConfigHttpPort, sizeof( ConfigHttpPort ) ); |
|
99 |
- |
|
100 |
- // get default output state |
|
101 |
- EepromGetConfigHelp( EEPROM_ADDR_DEF_OUT, &ConfigDefOut, sizeof( ConfigDefOut ) ); |
|
102 |
-} |
|
103 |
- |
|
104 |
-// task function to do the work - call from main loop |
|
105 |
-void EepromTask( void ) // (extern) |
|
106 |
-{ |
|
107 |
- // not writing something to EEPROM |
|
108 |
- if( ! (EepromWriteFlags & EepromWriteFlagActive) ) |
|
109 |
- { |
|
110 |
- // MAC needs to be written |
|
111 |
- if( EepromNeedWrite & EepromNeedWriteMac ) |
|
112 |
- { |
|
113 |
- EepromNeedWrite &= ~EepromNeedWriteMac; |
|
114 |
- pEepromWriteSrc = ConfigMac; |
|
115 |
- EepromWriteDestAddr = EEPROM_ADDR_MAC; |
|
116 |
- EepromWriteCnt = sizeof( ConfigMac ); |
|
117 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
118 |
- } |
|
119 |
- // IP needs to be written |
|
120 |
- else if( EepromNeedWrite & EepromNeedWriteIp ) |
|
121 |
- { |
|
122 |
- EepromNeedWrite &= ~EepromNeedWriteIp; |
|
123 |
- pEepromWriteSrc = ConfigIp; |
|
124 |
- EepromWriteDestAddr = EEPROM_ADDR_IP; |
|
125 |
- EepromWriteCnt = sizeof( ConfigIp ); |
|
126 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
127 |
- } |
|
128 |
- // subnet mask needs to be written |
|
129 |
- else if( EepromNeedWrite & EepromNeedWriteMask ) |
|
130 |
- { |
|
131 |
- EepromNeedWrite &= ~EepromNeedWriteMask; |
|
132 |
- pEepromWriteSrc = ConfigMask; |
|
133 |
- EepromWriteDestAddr = EEPROM_ADDR_MASK; |
|
134 |
- EepromWriteCnt = sizeof( ConfigMask ); |
|
135 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
136 |
- } |
|
137 |
- // gateway IP needs to be written |
|
138 |
- else if( EepromNeedWrite & EepromNeedWriteGw ) |
|
139 |
- { |
|
140 |
- EepromNeedWrite &= ~EepromNeedWriteGw; |
|
141 |
- pEepromWriteSrc = ConfigGw; |
|
142 |
- EepromWriteDestAddr = EEPROM_ADDR_GW; |
|
143 |
- EepromWriteCnt = sizeof( ConfigGw ); |
|
144 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
145 |
- } |
|
146 |
- // port for S8P needs to be written |
|
147 |
- else if( EepromNeedWrite & EepromNeedWriteS8pPort ) |
|
148 |
- { |
|
149 |
- EepromNeedWrite &= ~EepromNeedWriteS8pPort; |
|
150 |
- pEepromWriteSrc = (unsigned char *)&ConfigS8pPort; |
|
151 |
- EepromWriteDestAddr = EEPROM_ADDR_S8P_PORT; |
|
152 |
- EepromWriteCnt = sizeof( ConfigS8pPort ); |
|
153 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
154 |
- } |
|
155 |
- // symmetric key for S8P needs to be written |
|
156 |
- else if( EepromNeedWrite & EepromNeedWriteS8pKey ) |
|
157 |
- { |
|
158 |
- EepromNeedWrite &= ~EepromNeedWriteS8pKey; |
|
159 |
- pEepromWriteSrc = ConfigS8pKey; |
|
160 |
- EepromWriteDestAddr = EEPROM_ADDR_S8P_KEY; |
|
161 |
- EepromWriteCnt = sizeof( ConfigS8pKey ); |
|
162 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
163 |
- } |
|
164 |
- // port for webserver needs to be written |
|
165 |
- else if( EepromNeedWrite & EepromNeedWriteHttpPort ) |
|
166 |
- { |
|
167 |
- EepromNeedWrite &= ~EepromNeedWriteHttpPort; |
|
168 |
- pEepromWriteSrc = (unsigned char *)&ConfigHttpPort; |
|
169 |
- EepromWriteDestAddr = EEPROM_ADDR_HTTP_PORT; |
|
170 |
- EepromWriteCnt = sizeof( ConfigHttpPort ); |
|
171 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
172 |
- } |
|
173 |
- // if default output state needs to be written |
|
174 |
- else if( EepromNeedWrite & EepromNeedWriteDefOut ) |
|
175 |
- { |
|
176 |
- EepromNeedWrite &= ~EepromNeedWriteDefOut; |
|
177 |
- pEepromWriteSrc = &ConfigDefOut; |
|
178 |
- EepromWriteDestAddr = EEPROM_ADDR_DEF_OUT; |
|
179 |
- EepromWriteCnt = sizeof( ConfigDefOut ); |
|
180 |
- EepromWriteFlags = EepromWriteFlagActive; |
|
181 |
- } |
|
182 |
- // nothing needs to be written |
|
183 |
- else |
|
184 |
- return; |
|
185 |
- |
|
186 |
- debug_eeprom_printf( "write adr=0x%04X len=%u", EepromWriteDestAddr, EepromWriteCnt ); |
|
187 |
- } |
|
188 |
- |
|
189 |
- // EEPROM still busy |
|
190 |
- if( bit_is_set( EECR, EEWE ) ) |
|
191 |
- // try again later |
|
192 |
- return; |
|
193 |
- |
|
194 |
- // disable interrupts |
|
195 |
- cli( ); |
|
196 |
- |
|
197 |
- // get address in EEPROM and data to write |
|
198 |
- EEAR = EepromWriteDestAddr++; |
|
199 |
- if( EepromWriteFlags & EepromWriteFlagCheck ) // check byte |
|
200 |
- { |
|
201 |
- EEDR = ~*(pEepromWriteSrc++); // invert and advance source pointer |
|
202 |
- EepromWriteCnt--; // count down number of bytes to write |
|
203 |
- if( EepromWriteCnt <= 0 ) // finished |
|
204 |
- EepromWriteFlags &= ~EepromWriteFlagActive; |
|
205 |
- } |
|
206 |
- else // not check byte |
|
207 |
- EEDR = *pEepromWriteSrc; // use data byte as it is |
|
208 |
- EepromWriteFlags ^= EepromWriteFlagCheck; // toggle check byte bit |
|
209 |
- |
|
210 |
- // initiate write to EEPROM |
|
211 |
- bit_set( EECR, EEMWE ); |
|
212 |
- bit_set( EECR, EEWE ); |
|
213 |
- |
|
214 |
- // enable interrupts |
|
215 |
- sei( ); |
|
216 |
-} |
|
217 |
- |
... | ... |
@@ -1,28 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_eeprom |
|
9 |
-#define INC_eeprom |
|
10 |
- |
|
11 |
-// flags for what needs to be written to the EEPROM |
|
12 |
-#define EepromNeedWriteMac 0x01 |
|
13 |
-#define EepromNeedWriteIp 0x02 |
|
14 |
-#define EepromNeedWriteMask 0x04 |
|
15 |
-#define EepromNeedWriteGw 0x08 |
|
16 |
-#define EepromNeedWriteS8pPort 0x10 |
|
17 |
-#define EepromNeedWriteS8pKey 0x20 |
|
18 |
-#define EepromNeedWriteHttpPort 0x40 |
|
19 |
-#define EepromNeedWriteDefOut 0x80 |
|
20 |
-extern unsigned char EepromNeedWrite; |
|
21 |
- |
|
22 |
-// get configuration from EEPROM |
|
23 |
-extern void EepromGetConfig( void ); |
|
24 |
- |
|
25 |
-// task function to do the work - call from main loop |
|
26 |
-extern void EepromTask( void ); |
|
27 |
- |
|
28 |
-#endif // #ifndef INC_eeprom |
... | ... |
@@ -1,74 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include "arp.h" |
|
9 |
-#include "config.h" |
|
10 |
-#include "debug.h" |
|
11 |
-#include "ethernet.h" |
|
12 |
-#include "ip.h" |
|
13 |
-#include "macros.h" |
|
14 |
-#include "nethelp.h" |
|
15 |
-#include "rtl8019.h" |
|
16 |
- |
|
17 |
-// process a received ethernet packet |
|
18 |
-void EthernetRecv( unsigned char * pData, unsigned short Length ) // (extern) |
|
19 |
-{ |
|
20 |
- struct EthernetPacket * pEthPack; |
|
21 |
- |
|
22 |
- // packet too short |
|
23 |
- if( Length < sizeof( struct EthernetPacket ) ) |
|
24 |
- return; |
|
25 |
- |
|
26 |
- // convert pointer to ethernet packet |
|
27 |
- // (this saves us from always casting pData) |
|
28 |
- pEthPack = (struct EthernetPacket *)pData; |
|
29 |
- |
|
30 |
- debug_ether_printf( "recv len=%u type=0x%04X src=%02X:%02X:%02X:%02X:%02X:%02X", |
|
31 |
- Length, ntohs( pEthPack->EthHdr.Type ), |
|
32 |
- pEthPack->EthHdr.Src[0], pEthPack->EthHdr.Src[1], pEthPack->EthHdr.Src[2], |
|
33 |
- pEthPack->EthHdr.Src[3], pEthPack->EthHdr.Src[4], pEthPack->EthHdr.Src[5] ); |
|
34 |
- |
|
35 |
- // branch according to packet type |
|
36 |
- switch( pEthPack->EthHdr.Type ) |
|
37 |
- { |
|
38 |
- // ARP |
|
39 |
- case htons( 0x0806 ): |
|
40 |
- ArpRecv( pData, Length ); |
|
41 |
- break; |
|
42 |
- // IP |
|
43 |
- case htons( 0x0800 ): |
|
44 |
- IpRecv( pData, Length ); |
|
45 |
- break; |
|
46 |
- } |
|
47 |
-} |
|
48 |
- |
|
49 |
-// send an ethernet packet |
|
50 |
-// pData must point to a struct EthernetPacket with EthHdr.Dest and EthHdr.Type already initialized |
|
51 |
-void EthernetSend( unsigned char * pData, unsigned short Length ) // (extern) |
|
52 |
-{ |
|
53 |
- struct EthernetPacket * pEthPack; |
|
54 |
- |
|
55 |
- // packet too short |
|
56 |
- if( Length < sizeof( struct EthernetPacket ) ) |
|
57 |
- return; |
|
58 |
- |
|
59 |
- // convert pointer to ethernet packet |
|
60 |
- // (this saves us from always casting pData) |
|
61 |
- pEthPack = (struct EthernetPacket *)pData; |
|
62 |
- |
|
63 |
- debug_ether_printf( "send len=%u type=0x%04X dest=%02X:%02X:%02X:%02X:%02X:%02X", |
|
64 |
- Length, ntohs( pEthPack->EthHdr.Type ), |
|
65 |
- pEthPack->EthHdr.Dest[0], pEthPack->EthHdr.Dest[1], pEthPack->EthHdr.Dest[2], |
|
66 |
- pEthPack->EthHdr.Dest[3], pEthPack->EthHdr.Dest[4], pEthPack->EthHdr.Dest[5] ); |
|
67 |
- |
|
68 |
- // fill in source address |
|
69 |
- mac_cpy( pEthPack->EthHdr.Src, ConfigMac ); |
|
70 |
- |
|
71 |
- // send packet |
|
72 |
- RtlWriteFrame( (unsigned char *)pData, Length ); |
|
73 |
-} |
|
74 |
- |
... | ... |
@@ -1,33 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_ethernet |
|
9 |
-#define INC_ethernet |
|
10 |
- |
|
11 |
-// header of an ethernet packet |
|
12 |
-struct EthernetHeader |
|
13 |
-{ |
|
14 |
- unsigned char Dest[6]; |
|
15 |
- unsigned char Src[6]; |
|
16 |
- unsigned short Type; |
|
17 |
-}; |
|
18 |
- |
|
19 |
-// an ethernet packet |
|
20 |
-struct EthernetPacket |
|
21 |
-{ |
|
22 |
- struct EthernetHeader EthHdr; |
|
23 |
-}; |
|
24 |
- |
|
25 |
-// process a received ethernet packet |
|
26 |
-extern void EthernetRecv( unsigned char * pData, unsigned short Length ); |
|
27 |
- |
|
28 |
-// send an ethernet packet |
|
29 |
-// pData must point to a struct EthernetPacket with EthHdr.Dest and EthHdr.Type already initialized |
|
30 |
-extern void EthernetSend( unsigned char * pData, unsigned short Length ); |
|
31 |
- |
|
32 |
-#endif // #ifdef INC_ethernet |
|
33 |
- |
... | ... |
@@ -1,579 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <string.h> |
|
9 |
-#include <avr/pgmspace.h> |
|
10 |
- |
|
11 |
-#include "dart.h" |
|
12 |
-#include "debug.h" |
|
13 |
-#include "http.h" |
|
14 |
-#include "macros.h" |
|
15 |
-#include "tcp.h" |
|
16 |
- |
|
17 |
-// receive states while parsing HTTP request |
|
18 |
-#define HTTP_RCV_CMD 0 // receiving HTTP command (e.g. GET) |
|
19 |
-#define HTTP_RCV_FILE 1 // receiving filename |
|
20 |
-#define HTTP_RCV_LEN 2 // receiving content length |
|
21 |
-#define HTTP_RCV_HDR_END 3 // receiving header until end |
|
22 |
-#define HTTP_RCV_DATA 4 // receiving post data |
|
23 |
-#define HTTP_RCV_DONE 5 // receiving completed |
|
24 |
- |
|
25 |
-// knwon HTTP commands |
|
26 |
-#define HTTP_CMD_UNKNOWN 0 // unknown HTTP command |
|
27 |
-#define HTTP_CMD_GET 1 // GET command |
|
28 |
-#define HTTP_CMD_POST 2 // POST command |
|
29 |
- |
|
30 |
-// files available using HTTP |
|
31 |
-#define HTTP_FILE_NOT_FOUND 0 // file not found file |
|
32 |
-#define HTTP_FILE_INDEX 1 // index file |
|
33 |
-#define HTTP_FILE_DART 10 // dartboard response, still waiting |
|
34 |
-#define HTTP_FILE_DART_NO 11 // dartboard response, no hit |
|
35 |
-#define HTTP_FILE_DART_1D 12 // dartboard response, 1 digit hit |
|
36 |
-#define HTTP_FILE_DART_2D 13 // dartboard response, 2 digit hit |
|
37 |
- |
|
38 |
-// maximum HTTP/SOAP timeout (must be less than TCP timeout) |
|
39 |
-#define HttpMaxTimeout 45 |
|
40 |
- |
|
41 |
-// content of webpages and strings to fill in for variables |
|
42 |
-#include "http_content.inc" |
|
43 |
- |
|
44 |
-// table with HTTP connections |
|
45 |
-struct HttpConnection |
|
46 |
-{ |
|
47 |
- unsigned char ConnNo; // number of the TCP connection, 0xFF is unused |
|
48 |
- unsigned long RcvCnt; // number of received bytes on connection |
|
49 |
- unsigned char RcvState; // what is being received at the moment |
|
50 |
- unsigned char RcvBuf[32]; // receive buffer |
|
51 |
- unsigned char RcvBufLen; // length of data in receive buffer |
|
52 |
- unsigned char Command; // the command the client issued |
|
53 |
- char PreHttp1; // flag if a HTTP version before 1.0 is used |
|
54 |
- unsigned char File; // the file the client requested |
|
55 |
- unsigned long DataLen; // length of the data the client posts |
|
56 |
- unsigned char DataTag; // flag if currently in a tag in HTTP request body |
|
57 |
- unsigned long DataValue; // numeric value posted in HTTP request body |
|
58 |
- uint16_t pSndData; // the data to send (progmem pointer) |
|
59 |
- unsigned short SndDataLen; // the length of the data to send |
|
60 |
- char Vars; // flag if to interpret variables |
|
61 |
- unsigned char DartFactor; // factor hit on dart board to transmit |
|
62 |
- unsigned char DartValue; // value hit on dart board to transmit |
|
63 |
-} HttpConns[4]; |
|
64 |
- |
|
65 |
-// parse HTTP command |
|
66 |
-static void HttpParseCommand( struct HttpConnection * pConn ) |
|
67 |
-{ |
|
68 |
- // GET command |
|
69 |
- if( pConn->RcvBufLen == 3 && strncasecmp( (const char *)pConn->RcvBuf, "GET", 3 ) == 0 ) |
|
70 |
- pConn->Command = HTTP_CMD_GET; |
|
71 |
- // POST command |
|
72 |
- else if( pConn->RcvBufLen == 4 && strncasecmp( (const char *)pConn->RcvBuf, "POST", 4 ) == 0 ) |
|
73 |
- { |
|
74 |
- pConn->Command = HTTP_CMD_POST; |
|
75 |
- pConn->DataLen = 0; |
|
76 |
- } |
|
77 |
- // unknown command is the default |
|
78 |
- else |
|
79 |
- pConn->Command = HTTP_CMD_UNKNOWN; |
|
80 |
-} |
|
81 |
- |
|
82 |
-// parse HTTP file |
|
83 |
-static void HttpParseFile( struct HttpConnection * pConn ) |
|
84 |
-{ |
|
85 |
- // index file |
|
86 |
- if( (pConn->RcvBufLen == 1 && strncasecmp( (const char *)pConn->RcvBuf, "/", 1 ) == 0) || |
|
87 |
- (pConn->RcvBufLen == 2 && strncasecmp( (const char *)pConn->RcvBuf, "/i", 2 ) == 0) ) |
|
88 |
- pConn->File = HTTP_FILE_INDEX; |
|
89 |
- // dartboard response |
|
90 |
- else if( pConn->RcvBufLen == 5 && strncasecmp( (const char *)pConn->RcvBuf, "/dart", 5 ) == 0 ) |
|
91 |
- pConn->File = HTTP_FILE_DART; |
|
92 |
- // error file is the default |
|
93 |
- else |
|
94 |
- pConn->File = HTTP_FILE_NOT_FOUND; |
|
95 |
-} |
|
96 |
- |
|
97 |
-// process HTTP request |
|
98 |
-static void HttpProcessRequest( struct HttpConnection * pConn ) |
|
99 |
-{ |
|
100 |
- // different commands |
|
101 |
- switch( pConn->Command ) |
|
102 |
- { |
|
103 |
- |
|
104 |
- case HTTP_CMD_GET: |
|
105 |
- case HTTP_CMD_POST: |
|
106 |
- |
|
107 |
- // different files |
|
108 |
- switch( pConn->File ) |
|
109 |
- { |
|
110 |
- |
|
111 |
- case HTTP_FILE_INDEX: |
|
112 |
- if( pConn->PreHttp1 ) |
|
113 |
- { |
|
114 |
- pConn->pSndData = (uint16_t)HttpIndex + HttpIndexHeaderSize; |
|
115 |
- pConn->SndDataLen = sizeof( HttpIndex ) - 1 - HttpIndexHeaderSize; |
|
116 |
- } |
|
117 |
- else |
|
118 |
- { |
|
119 |
- pConn->pSndData = (uint16_t)HttpIndex; |
|
120 |
- pConn->SndDataLen = sizeof( HttpIndex ) - 1; |
|
121 |
- } |
|
122 |
- pConn->Vars = 0; |
|
123 |
- break; |
|
124 |
- |
|
125 |
- case HTTP_FILE_DART_NO: |
|
126 |
- if( pConn->PreHttp1 ) |
|
127 |
- { |
|
128 |
- pConn->pSndData = (uint16_t)HttpDartNo + HttpDartNoHeaderSize; |
|
129 |
- pConn->SndDataLen = sizeof( HttpDartNo ) - 1 - HttpDartNoHeaderSize; |
|
130 |
- } |
|
131 |
- else |
|
132 |
- { |
|
133 |
- pConn->pSndData = (uint16_t)HttpDartNo; |
|
134 |
- pConn->SndDataLen = sizeof( HttpDartNo ) - 1; |
|
135 |
- } |
|
136 |
- pConn->Vars = 1; |
|
137 |
- break; |
|
138 |
- |
|
139 |
- case HTTP_FILE_DART_1D: |
|
140 |
- if( pConn->PreHttp1 ) |
|
141 |
- { |
|
142 |
- pConn->pSndData = (uint16_t)HttpDart1d + HttpDart1dHeaderSize; |
|
143 |
- pConn->SndDataLen = sizeof( HttpDart1d ) - 1 - HttpDart1dHeaderSize; |
|
144 |
- } |
|
145 |
- else |
|
146 |
- { |
|
147 |
- pConn->pSndData = (uint16_t)HttpDart1d; |
|
148 |
- pConn->SndDataLen = sizeof( HttpDart1d ) - 1; |
|
149 |
- } |
|
150 |
- pConn->Vars = 1; |
|
151 |
- break; |
|
152 |
- |
|
153 |
- case HTTP_FILE_DART_2D: |
|
154 |
- if( pConn->PreHttp1 ) |
|
155 |
- { |
|
156 |
- pConn->pSndData = (uint16_t)HttpDart2d + HttpDart2dHeaderSize; |
|
157 |
- pConn->SndDataLen = sizeof( HttpDart2d ) - 1 - HttpDart2dHeaderSize; |
|
158 |
- } |
|
159 |
- else |
|
160 |
- { |
|
161 |
- pConn->pSndData = (uint16_t)HttpDart2d; |
|
162 |
- pConn->SndDataLen = sizeof( HttpDart2d ) - 1; |
|
163 |
- } |
|
164 |
- pConn->Vars = 1; |
|
165 |
- break; |
|
166 |
- |
|
167 |
- case HTTP_FILE_NOT_FOUND: |
|
168 |
- default: |
|
169 |
- if( pConn->PreHttp1 ) |
|
170 |
- { |
|
171 |
- pConn->pSndData = (uint16_t)HttpNotFound + HttpNotFoundHeaderSize; |
|
172 |
- pConn->SndDataLen = sizeof( HttpNotFound ) - 1 - HttpNotFoundHeaderSize; |
|
173 |
- } |
|
174 |
- else |
|
175 |
- { |
|
176 |
- pConn->pSndData = (uint16_t)HttpNotFound; |
|
177 |
- pConn->SndDataLen = sizeof( HttpNotFound ) - 1; |
|
178 |
- } |
|
179 |
- pConn->Vars = 0; |
|
180 |
- |
|
181 |
- } // switch( pConn->File ) |
|
182 |
- break; |
|
183 |
- |
|
184 |
- case HTTP_CMD_UNKNOWN: |
|
185 |
- default: |
|
186 |
- if( pConn->PreHttp1 ) |
|
187 |
- { |
|
188 |
- pConn->pSndData = (uint16_t)HttpBadRequest + HttpBadRequestHeaderSize; |
|
189 |
- pConn->SndDataLen = sizeof( HttpBadRequest ) - 1 - HttpBadRequestHeaderSize; |
|
190 |
- } |
|
191 |
- else |
|
192 |
- { |
|
193 |
- pConn->pSndData = (uint16_t)HttpBadRequest; |
|
194 |
- pConn->SndDataLen = sizeof( HttpBadRequest ) - 1; |
|
195 |
- } |
|
196 |
- pConn->Vars = 0; |
|
197 |
- |
|
198 |
- } // switch( pConn->Command ) |
|
199 |
-} |
|
200 |
- |
|
201 |
-// called when connection is established |
|
202 |
-void HttpConnect( unsigned char ConnNo ) |
|
203 |
-{ |
|
204 |
- unsigned char i; |
|
205 |
- struct HttpConnection * pConn; |
|
206 |
- |
|
207 |
- // find connection in table (in case TCP calls us twice, this should never happen) |
|
208 |
- for( i = 0; i < count( HttpConns ); i++ ) |
|
209 |
- if( HttpConns[i].ConnNo == ConnNo ) |
|
210 |
- break; |
|
211 |
- // connection not found |
|
212 |
- if( i >= count( HttpConns ) ) |
|
213 |
- { |
|
214 |
- // find a free entry |
|
215 |
- for( i = 0; i < count( HttpConns ); i++ ) |
|
216 |
- if( HttpConns[i].ConnNo == 0xFF ) |
|
217 |
- break; |
|
218 |
- if( i >= count( HttpConns ) ) // no free entry found |
|
219 |
- return; // ignore this connection (will be closed in first call of HttpSend) |
|
220 |
- } |
|
221 |
- // get pointer to connection |
|
222 |
- pConn = &HttpConns[i]; |
|
223 |
- |
|
224 |
- debug_http_printf( "accept no=%u", ConnNo ); |
|
225 |
- |
|
226 |
- // put new connection into table |
|
227 |
- pConn->ConnNo = ConnNo; |
|
228 |
- pConn->RcvCnt = 0; |
|
229 |
- pConn->RcvState = HTTP_RCV_CMD; |
|
230 |
- pConn->RcvBufLen = 0; |
|
231 |
-} |
|
232 |
- |
|
233 |
-// called when connection is closed / reset |
|
234 |
-// (after this, the connection number may not be used any more) |
|
235 |
-void HttpClose( unsigned char ConnNo ) |
|
236 |
-{ |
|
237 |
- unsigned char i; |
|
238 |
- struct HttpConnection * pConn; |
|
239 |
- |
|
240 |
- // find connection in table |
|
241 |
- for( i = 0; i < count( HttpConns ); i++ ) |
|
242 |
- if( HttpConns[i].ConnNo == ConnNo ) |
|
243 |
- break; |
|
244 |
- if( i >= count( HttpConns ) ) // connection not found |
|
245 |
- return; // ignore this (now already closed) connection |
|
246 |
- // get pointer to connection |
|
247 |
- pConn = &HttpConns[i]; |
|
248 |
- |
|
249 |
- debug_http_printf( "close no=%u", ConnNo ); |
|
250 |
- |
|
251 |
- // drop connection from table |
|
252 |
- pConn->ConnNo = 0xFF; |
|
253 |
-} |
|
254 |
- |
|
255 |
-// called when sending data is possible |
|
256 |
-// (return length of available data, 0xFFFF to close connection) |
|
257 |
-unsigned short HttpSend( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short MaxLen ) |
|
258 |
-{ |
|
259 |
- unsigned char i; |
|
260 |
- struct HttpConnection * pConn; |
|
261 |
- unsigned short len, j; |
|
262 |
- uint16_t src; // progmem pointer |
|
263 |
- char chr, * dest; |
|
264 |
- |
|
265 |
- // find connection in table |
|
266 |
- for( i = 0; i < count( HttpConns ); i++ ) |
|
267 |
- if( HttpConns[i].ConnNo == ConnNo ) |
|
268 |
- break; |
|
269 |
- if( i >= count( HttpConns ) ) // connection not found |
|
270 |
- return 0xFFFF; // close connection |
|
271 |
- // get pointer to connection |
|
272 |
- pConn = &HttpConns[i]; |
|
273 |
- |
|
274 |
- // not done with receiving |
|
275 |
- if( pConn->RcvState != HTTP_RCV_DONE ) |
|
276 |
- return 0; // do not send anything yet |
|
277 |
- |
|
278 |
- // still waiting for dartboard |
|
279 |
- if( pConn->File == HTTP_FILE_DART ) |
|
280 |
- return 0; // do not send anything yet |
|
281 |
- |
|
282 |
- // at or behind end of data |
|
283 |
- if( Pos >= (unsigned long)pConn->SndDataLen ) |
|
284 |
- return 0xFFFF; // request to close connection |
|
285 |
- |
|
286 |
- // get number of bytes to send |
|
287 |
- len = min( pConn->SndDataLen - (unsigned short)Pos, MaxLen ); |
|
288 |
- if( len == 0 ) // nothing to send |
|
289 |
- return 0; |
|
290 |
- |
|
291 |
- // copy data to buffer |
|
292 |
- src = pConn->pSndData + (uint16_t)Pos; |
|
293 |
- dest = (char *)pBuffer; |
|
294 |
- for( j = 0; j < len; j++ ) |
|
295 |
- { |
|
296 |
- // read current character |
|
297 |
- chr = (char)pgm_read_byte_near( src ); |
|
298 |
- // variable |
|
299 |
- if( pConn->Vars && (unsigned char)chr >= 0x80 ) |
|
300 |
- { |
|
301 |
- switch( chr ) { |
|
302 |
- case 0x80: chr = pConn->DartFactor + '0'; break; |
|
303 |
- case 0x90: chr = pConn->DartValue % 10 + '0'; break; |
|
304 |
- case 0x91: chr = pConn->DartValue / 10 + '0'; break; |
|
305 |
- default: chr = ' '; break; |
|
306 |
- } |
|
307 |
- } |
|
308 |
- *dest = chr; // copy character |
|
309 |
- // next character |
|
310 |
- src++; |
|
311 |
- dest++; |
|
312 |
- } // for( j ... |
|
313 |
- |
|
314 |
- // return length of data in buffer |
|
315 |
- debug_http_printf( "send no=%u pos=%lu len=%u", ConnNo, Pos, len ); |
|
316 |
- return len; |
|
317 |
-} |
|
318 |
- |
|
319 |
-// called when data was sent and ACKed |
|
320 |
-void HttpSent( unsigned char ConnNo, unsigned long Pos ) |
|
321 |
-{ |
|
322 |
- // nothing needs to be done here |
|
323 |
-} |
|
324 |
- |
|
325 |
-// called when data was received |
|
326 |
-// must return new window size (not smaller than curWnd) |
|
327 |
-unsigned short HttpReceived( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short Len, unsigned short curWnd ) |
|
328 |
-{ |
|
329 |
- unsigned char i; |
|
330 |
- struct HttpConnection * pConn; |
|
331 |
- |
|
332 |
- // find connection in table |
|
333 |
- for( i = 0; i < count( HttpConns ); i++ ) |
|
334 |
- if( HttpConns[i].ConnNo == ConnNo ) |
|
335 |
- break; |
|
336 |
- if( i >= count( HttpConns ) ) // connection not found |
|
337 |
- return max( curWnd, 256 ); // ignore this connection (will be closed in first call of HttpSend) |
|
338 |
- // get pointer to connection |
|
339 |
- pConn = &HttpConns[i]; |
|
340 |
- |
|
341 |
- // received duplicate data or missed some data |
|
342 |
- // (just to be on the safe side, this should never happen) |
|
343 |
- if( pConn->RcvCnt != Pos ) |
|
344 |
- { |
|
345 |
- // close connection |
|
346 |
- TcpClose( pConn->ConnNo ); |
|
347 |
- pConn->ConnNo = 0xFF; |
|
348 |
- return max( curWnd, 256 ); |
|
349 |
- } |
|
350 |
- |
|
351 |
- // process received data |
|
352 |
- for( ; Len > 0; pBuffer++, Len--, pConn->RcvCnt++ ) |
|
353 |
- { |
|
354 |
- // store character in receive buffer (if it fits into it) |
|
355 |
- if( pConn->RcvBufLen < sizeof( pConn->RcvBuf ) ) |
|
356 |
- { |
|
357 |
- pConn->RcvBuf[pConn->RcvBufLen] = *pBuffer; |
|
358 |
- pConn->RcvBufLen++; |
|
359 |
- } |
|
360 |
- |
|
361 |
- // actions according to state |
|
362 |
- switch( pConn->RcvState ) |
|
363 |
- { |
|
364 |
- |
|
365 |
- // receiving HTTP command (e.g GET) |
|
366 |
- case HTTP_RCV_CMD: |
|
367 |
- if( *pBuffer == '\r' || *pBuffer == '\n' ) // newline |
|
368 |
- { |
|
369 |
- pConn->RcvBufLen--; // remove newline from buffer |
|
370 |
- HttpParseCommand( pConn ); // parse command |
|
371 |
- pConn->PreHttp1 = 1; // older than HTTP 1.0 |
|
372 |
- pConn->File = HTTP_FILE_INDEX; // send index file |
|
373 |
- pConn->RcvState = HTTP_RCV_DONE; // receiving completed |
|
374 |
- debug_http_printf( "pre1+end no=%u", pConn->ConnNo ); |
|
375 |
- pConn->RcvBufLen = 0; // empty receive buffer |
|
376 |
- HttpProcessRequest( pConn ); // now process request |
|
377 |
- } |
|
378 |
- else if( *pBuffer == ' ' || *pBuffer == '\t' ) // whitespace |
|
379 |
- { |
|
380 |
- pConn->RcvBufLen--; // remove whitespace from buffer |
|
381 |
- HttpParseCommand( pConn ); // parse command |
|
382 |
- pConn->RcvState = HTTP_RCV_FILE; // now receive filename |
|
383 |
- debug_http_printf( "cmd no=%u cmd=%u", pConn->ConnNo, pConn->Command ); |
|
384 |
- pConn->RcvBufLen = 0; // empty receive buffer |
|
385 |
- } |
|
386 |
- break; |
|
387 |
- |
|
388 |
- // receiving filename |
|
389 |
- case HTTP_RCV_FILE: |
|
390 |
- if( *pBuffer == '\r' || *pBuffer == '\n' ) // newline |
|
391 |
- { |
|
392 |
- pConn->RcvBufLen--; // remove newline from buffer |
|
393 |
- HttpParseFile( pConn ); // parse file |
|
394 |
- pConn->PreHttp1 = 1; // older than HTTP 1.0 |
|
395 |
- pConn->RcvState = HTTP_RCV_DONE; // receiving completed |
|
396 |
- debug_http_printf( "file+end no=%u file=%u", pConn->ConnNo, pConn->File ); |
|
397 |
- pConn->RcvBufLen = 0; // empty receive buffer |
|
398 |
- HttpProcessRequest( pConn ); // now process request |
|
399 |
- } |
|
400 |
- else if( *pBuffer == ' ' || *pBuffer == '\t' ) // whitespace |
|
401 |
- { |
|
402 |
- pConn->RcvBufLen--; // remove whitespace from buffer |
|
403 |
- HttpParseFile( pConn ); // parse file |
|
404 |
- pConn->PreHttp1 = 0; // HTTP 1.0 or newer |
|
405 |
- if( pConn->Command == HTTP_CMD_POST ) |
|
406 |
- pConn->RcvState = HTTP_RCV_LEN; // now receive content length |
|
407 |
- else |
|
408 |
- pConn->RcvState = HTTP_RCV_HDR_END; // now receive header until end |
|
409 |
- debug_http_printf( "file no=%u file=%u", pConn->ConnNo, pConn->File ); |
|
410 |
- pConn->RcvBufLen = 0; // empty receive buffer |
|
411 |
- } |
|
412 |
- break; |
|
413 |
- |
|
414 |
- // receiving content length |
|
415 |
- case HTTP_RCV_LEN: |
|
416 |
- if( *pBuffer == '\n' || *pBuffer == '\r' ) // newline |
|
417 |
- { |
|
418 |
- pConn->RcvBuf[pConn->RcvBufLen-1] = 0; |
|
419 |
- // content length line |
|
420 |
- if( pConn->RcvBufLen >= 15 && memcmp( pConn->RcvBuf, "content-length:", 15 ) == 0 ) |
|
421 |
- { |
|
422 |
- for( i = 15; i < pConn->RcvBufLen; i++ ) |
|
423 |
- if( pConn->RcvBuf[i] >= '0' && pConn->RcvBuf[i] <= '9' ) |
|
424 |
- pConn->DataLen = pConn->DataLen * 10 + pConn->RcvBuf[i] - '0'; |
|
425 |
- debug_http_printf( "data len %lu", pConn->DataLen ); |
|
426 |
- pConn->RcvState = HTTP_RCV_HDR_END; // now receive header until end |
|
427 |
- } |
|
428 |
- // empty receive buffer |
|
429 |
- pConn->RcvBufLen = 0; |
|
430 |
- // re-insert newline if now receiving header until end |
|
431 |
- if( pConn->RcvState == HTTP_RCV_HDR_END ) |
|
432 |
- pConn->RcvBuf[pConn->RcvBufLen++] = *pBuffer; |
|
433 |
- } |
|
434 |
- else if( *pBuffer >= 'A' && *pBuffer <= 'Z' ) // capital letter |
|
435 |
- { |
|
436 |
- pConn->RcvBuf[pConn->RcvBufLen - 1] |= 0x20; // convert to lower case |
|
437 |
- } |
|
438 |
- break; |
|
439 |
- |
|
440 |
- // receiving header until end |
|
441 |
- case HTTP_RCV_HDR_END: |
|
442 |
- if( *pBuffer != '\r' && *pBuffer != '\n' ) // not a newline |
|
443 |
- { |
|
444 |
- pConn->RcvBufLen = 0; // empty receive buffer |
|
445 |
- break; |
|
446 |
- } |
|
447 |
- if( (pConn->RcvBufLen == 2 && memcmp( pConn->RcvBuf, "\r\r", 2 ) == 0) || // CR CR |
|
448 |
- (pConn->RcvBufLen == 2 && memcmp( pConn->RcvBuf, "\n\n", 2 ) == 0) || // LF LF |
|
449 |
- (pConn->RcvBufLen == 3 && memcmp( pConn->RcvBuf, "\r\n\n", 3 ) == 0) || // CR LF LF |
|
450 |
- (pConn->RcvBufLen == 3 && memcmp( pConn->RcvBuf, "\n\r\n", 3 ) == 0) || // LF CR LF |
|
451 |
- pConn->RcvBufLen == 4 ) // CR LF CR LF (or some other combination of 4 times CR or LF) |
|
452 |
- { |
|
453 |
- if( pConn->Command == HTTP_CMD_POST && pConn->DataLen > 0 ) |
|
454 |
- { |
|
455 |
- pConn->RcvState = HTTP_RCV_DATA; // now receive post data |
|
456 |
- pConn->DataTag = 0; // not in a tag |
|
457 |
- pConn->DataValue = 0; // no value yet |
|
458 |
- } |
|
459 |
- else |
|
460 |
- pConn->RcvState = HTTP_RCV_DONE; // receiving completed |
|
461 |
- debug_http_printf( "end no=%u", pConn->ConnNo ); |
|
462 |
- pConn->RcvBufLen = 0; // empty receive buffer |
|
463 |
- HttpProcessRequest( pConn ); // now process request |
|
464 |
- } |
|
465 |
- break; |
|
466 |
- |
|
467 |
- // receiving post data |
|
468 |
- case HTTP_RCV_DATA: |
|
469 |
- pConn->RcvBufLen = 0; // ignore any data in receive buffer |
|
470 |
- // process data byte for byte |
|
471 |
- if( pConn->DataTag ) { // in a tag |
|
472 |
- if( *pBuffer == '>' ) // end of tag |
|
473 |
- pConn->DataTag = 0; |
|
474 |
- } else { // not in a tag |
|
475 |
- if( *pBuffer == '<' ) // start of tag |
|
476 |
- pConn->DataTag = 1; |
|
477 |
- if( *pBuffer >= '0' && *pBuffer <= '9' ) // a digit |
|
478 |
- pConn->DataValue = pConn->DataValue * 10 + *pBuffer - '0'; // collect digits |
|
479 |
- } |
|
480 |
- // count down number of bytes to receive |
|
481 |
- if( pConn->DataLen > 0 ) |
|
482 |
- pConn->DataLen--; |
|
483 |
- if( pConn->DataLen <= 0 ) { |
|
484 |
- debug_http_printf( "data value %lu", pConn->DataValue ); |
|
485 |
- if( pConn->DataValue > HttpMaxTimeout ) // limit timeout (must be less than TCP timeout) |
|
486 |
- pConn->DataValue = HttpMaxTimeout; |
|
487 |
- pConn->DataValue *= 5; // convert from seconds to ticks |
|
488 |
- pConn->RcvState = HTTP_RCV_DONE; // receiving completed |
|
489 |
- } |
|
490 |
- break; |
|
491 |
- |
|
492 |
- // receiving completed |
|
493 |
- case HTTP_RCV_DONE: |
|
494 |
- pConn->RcvBufLen = 0; // ignore any additional data |
|
495 |
- break; |
|
496 |
- |
|
497 |
- } // switch( pConn->RcvState ) |
|
498 |
- } // for( ; Len > 0; pBuffer++, Len--, pConn->RcvCnt++ ) |
|
499 |
- |
|
500 |
- // return at least 256 bytes window size |
|
501 |
- // - we are always able to receive data |
|
502 |
- return max( curWnd, 256 ); |
|
503 |
-} |
|
504 |
- |
|
505 |
-// http notification functions |
|
506 |
-struct TcpNotify HttpNotify = // (extern) |
|
507 |
-{ |
|
508 |
- .Connect = HttpConnect, |
|
509 |
- .Close = HttpClose, |
|
510 |
- .Send = HttpSend, |
|
511 |
- .Sent = HttpSent, |
|
512 |
- .Received = HttpReceived, |
|
513 |
-}; |
|
514 |
- |
|
515 |
-// initialize |
|
516 |
-void HttpInit( void ) // (extern) |
|
517 |
-{ |
|
518 |
- unsigned char i; |
|
519 |
- |
|
520 |
- // no HTTP connections yet |
|
521 |
- for( i = 0; i < count( HttpConns ); i++ ) |
|
522 |
- HttpConns[i].ConnNo = 0xFF; |
|
523 |
-} |
|
524 |
- |
|
525 |
-// http tick procedure - call every 200ms |
|
526 |
-void HttpTick200( void ) // (extern) |
|
527 |
-{ |
|
528 |
- unsigned char i, factor, value; |
|
529 |
- |
|
530 |
- // process all HTTP connections |
|
531 |
- for( i = 0; i < count( HttpConns ); i++ ) { |
|
532 |
- struct HttpConnection * pConn = &HttpConns[i]; |
|
533 |
- |
|
534 |
- // connection in use and waiting for dart |
|
535 |
- if( pConn->ConnNo != 0xFF && |
|
536 |
- pConn->RcvState == HTTP_RCV_DONE && |
|
537 |
- pConn->File == HTTP_FILE_DART ) { |
|
538 |
- |
|
539 |
- // poll dart |
|
540 |
- DartPoll( &factor, &value ); |
|
541 |
- |
|
542 |
- // 2 digit field hit |
|
543 |
- if( factor > 0 && value >= 10 ) { |
|
544 |
- pConn->DartFactor = factor; |
|
545 |
- pConn->DartValue = value; |
|
546 |
- pConn->File = HTTP_FILE_DART_2D; |
|
547 |
- HttpProcessRequest( pConn ); // re-process request |
|
548 |
- TcpSend( pConn->ConnNo ); // data to send is available now |
|
549 |
- } |
|
550 |
- |
|
551 |
- // 1 digit field hit |
|
552 |
- else if( factor > 0 && value > 0 ) { |
|
553 |
- pConn->DartFactor = factor; |
|
554 |
- pConn->DartValue = value; |
|
555 |
- pConn->File = HTTP_FILE_DART_1D; |
|
556 |
- HttpProcessRequest( pConn ); // re-process request |
|
557 |
- TcpSend( pConn->ConnNo ); // data to send is available now |
|
558 |
- } |
|
559 |
- |
|
560 |
- // no field hit |
|
561 |
- else { |
|
562 |
- // no timeout yet ---> count down time |
|
563 |
- if( pConn->DataValue > 0 ) { |
|
564 |
- pConn->DataValue--; |
|
565 |
- } |
|
566 |
- // timeout |
|
567 |
- else { |
|
568 |
- pConn->DartFactor = 0; |
|
569 |
- pConn->DartValue = 0; |
|
570 |
- pConn->File = HTTP_FILE_DART_NO; |
|
571 |
- HttpProcessRequest( pConn ); // re-process request |
|
572 |
- TcpSend( pConn->ConnNo ); // data to send is available now |
|
573 |
- } |
|
574 |
- } |
|
575 |
- |
|
576 |
- } // in use |
|
577 |
- } // for( i ... |
|
578 |
-} |
|
579 |
- |
... | ... |
@@ -1,23 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_http |
|
9 |
-#define INC_http |
|
10 |
- |
|
11 |
-#include "tcp.h" |
|
12 |
- |
|
13 |
-// initialize |
|
14 |
-extern void HttpInit( void ); |
|
15 |
- |
|
16 |
-// http notification functions |
|
17 |
-extern struct TcpNotify HttpNotify; |
|
18 |
- |
|
19 |
-// http tick procedure - call every 200ms |
|
20 |
-extern void HttpTick200( void ); |
|
21 |
- |
|
22 |
-#endif // #ifdef INC_http |
|
23 |
- |
... | ... |
@@ -1,221 +0,0 @@ |
1 |
-#! /usr/bin/perl |
|
2 |
- |
|
3 |
-# flaneth - flash and ethernet - dartboard mod |
|
4 |
-# version 0.1 date 2008-11-09 |
|
5 |
-# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
6 |
-# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
7 |
-# a BlinkenArea project - http://www.blinkenarea.org/ |
|
8 |
- |
|
9 |
-use strict; |
|
10 |
- |
|
11 |
-my $VERSION="version 0.1 date 2008-11-09"; |
|
12 |
- |
|
13 |
- |
|
14 |
- |
|
15 |
-die( "usage: $0 <http_dir> <http_content.inc>\n" ) if( @ARGV < 2 ); |
|
16 |
- |
|
17 |
-my $dir = @ARGV[0]; |
|
18 |
-my $output = @ARGV[1]; |
|
19 |
- |
|
20 |
- |
|
21 |
- |
|
22 |
-# maximum |
|
23 |
-# usage: $m = max( $a, $b ) |
|
24 |
-sub max |
|
25 |
-{ |
|
26 |
- my $a = shift; |
|
27 |
- my $b = shift; |
|
28 |
- return $a > $b ? $a : $b; |
|
29 |
-} |
|
30 |
- |
|
31 |
- |
|
32 |
- |
|
33 |
-# convert a character to a string |
|
34 |
-# usage: $txt = chr2str( $ascii_code, $cnt ) |
|
35 |
-sub chr2str |
|
36 |
-{ |
|
37 |
- my $ascii_code = shift; |
|
38 |
- my $cnt = shift; |
|
39 |
- |
|
40 |
- my $txt = ""; |
|
41 |
- |
|
42 |
- for( ; $cnt > 0; $cnt-- ) { |
|
43 |
- $txt .= pack( "C", $ascii_code ); |
|
44 |
- } |
|
45 |
- |
|
46 |
- return $txt; |
|
47 |
-} |
|
48 |
- |
|
49 |
- |
|
50 |
- |
|
51 |
-# c string escaping |
|
52 |
-# usage: $escaped = str_esc( $txt ) |
|
53 |
-sub str_esc |
|
54 |
-{ |
|
55 |
- my $txt = shift; |
|
56 |
- |
|
57 |
- my $escaped = ""; |
|
58 |
- for( my $i = 0; $i < length( $txt ); $i++ ) { |
|
59 |
- my $chr = substr( $txt, $i, 1 ); |
|
60 |
- if( $chr eq '\\' ) { |
|
61 |
- $escaped .= "\\\\"; |
|
62 |
- } elsif( $chr eq '"' ) { |
|
63 |
- $escaped .= "\\\""; |
|
64 |
- } elsif( $chr eq "\t" ) { |
|
65 |
- $escaped .= "\\t"; |
|
66 |
- } elsif( $chr eq "\r" ) { |
|
67 |
- $escaped .= "\\r"; |
|
68 |
- } elsif( $chr eq "\n" ) { |
|
69 |
- $escaped .= "\\n"; |
|
70 |
- } elsif( $chr ge ' ' && $chr le '~' ) { |
|
71 |
- $escaped .= $chr; |
|
72 |
- } else { |
|
73 |
- $escaped .= sprintf( "\\x%02X", unpack( "C", $chr ) ); |
|
74 |
- } |
|
75 |
- } |
|
76 |
- |
|
77 |
- return $escaped; |
|
78 |
-} |
|
79 |
- |
|
80 |
- |
|
81 |
- |
|
82 |
-# replace variables |
|
83 |
-# usage: $line_replaced = var_replace( $line ) |
|
84 |
-sub var_replace |
|
85 |
-{ |
|
86 |
- my $line = shift; |
|
87 |
- |
|
88 |
- my $var; |
|
89 |
- $line =~ s/__VERSION__/$VERSION/g; |
|
90 |
- $var = chr2str( 0x80, 1 ); |
|
91 |
- $line =~ s/__FACTOR__/$var/g; |
|
92 |
- $var = chr2str( 0x90, 1 ); |
|
93 |
- $line =~ s/__VALUE_L__/$var/g; |
|
94 |
- $var = chr2str( 0x91, 1 ); |
|
95 |
- $line =~ s/__VALUE_H__/$var/g; |
|
96 |
- |
|
97 |
- return $line; |
|
98 |
-} |
|
99 |
- |
|
100 |
- |
|
101 |
- |
|
102 |
-# get file size |
|
103 |
-# usage: $size = file_size( $filename ) |
|
104 |
-sub file_size |
|
105 |
-{ |
|
106 |
- my $filename = shift; |
|
107 |
- |
|
108 |
- my @info = stat( $filename ); |
|
109 |
- |
|
110 |
- return @info[7] if( @info > 7 ); # @info[7] is the size (see documentation of stat) |
|
111 |
- |
|
112 |
- return 0; |
|
113 |
-} |
|
114 |
- |
|
115 |
- |
|
116 |
- |
|
117 |
-# convert a text file to c code |
|
118 |
-# usage: ($code, $len) = textfile2code( $filename ) |
|
119 |
-sub textfile2code |
|
120 |
-{ |
|
121 |
- my $filename = shift; |
|
122 |
- |
|
123 |
- my $txt = ""; |
|
124 |
- my $len = 0; |
|
125 |
- |
|
126 |
- open( TEXTFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" ); |
|
127 |
- |
|
128 |
- my $line; |
|
129 |
- while( $line = <TEXTFILE> ) { |
|
130 |
- $line = var_replace( $line ); |
|
131 |
- $txt .= "\"" . str_esc( $line ) . "\"\n"; |
|
132 |
- $len += length( $line ); |
|
133 |
- } |
|
134 |
- |
|
135 |
- |
|
136 |
- close( TEXTFILE ); |
|
137 |
- |
|
138 |
- return ($txt, $len); |
|
139 |
-} |
|
140 |
- |
|
141 |
- |
|
142 |
- |
|
143 |
-# convert a binary file to c code |
|
144 |
-# usage: ($code, $len) = binfile2code( $filename ) |
|
145 |
-sub binfile2code |
|
146 |
-{ |
|
147 |
- my $filename = shift; |
|
148 |
- |
|
149 |
- my $txt = ""; |
|
150 |
- my $len = 0; |
|
151 |
- |
|
152 |
- open( BINFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" ); |
|
153 |
- binmode( BINFILE ); |
|
154 |
- |
|
155 |
- my $val; |
|
156 |
- while( 1 ) { |
|
157 |
- $txt.= "\""; |
|
158 |
- my $i; |
|
159 |
- for( $i = 0; $i < 0x10; $i++ ) { |
|
160 |
- read( BINFILE, $val, 1 ) or last; |
|
161 |
- $txt .= sprintf( "\\x%02X", unpack( "C", $val ) ); |
|
162 |
- $len++; |
|
163 |
- } |
|
164 |
- $txt .= "\"\n"; |
|
165 |
- last if( $i < 0x10 ); |
|
166 |
- } |
|
167 |
- |
|
168 |
- close( BINFILE ); |
|
169 |
- |
|
170 |
- return ($txt, $len); |
|
171 |
-} |
|
172 |
- |
|
173 |
- |
|
174 |
- |
|
175 |
-# generate page |
|
176 |
-# usage: $page = gen_page( $ret, $file, $name, $ctype, $bin ) |
|
177 |
-sub gen_page |
|
178 |
-{ |
|
179 |
- my $ret = shift; |
|
180 |
- my $file = shift; |
|
181 |
- my $name = shift; |
|
182 |
- my $ctype = shift; |
|
183 |
- my $bin = shift; |
|
184 |
- |
|
185 |
- my ($code, $len); |
|
186 |
- if( $bin ) { |
|
187 |
- ($code, $len) = binfile2code( $file ); |
|
188 |
- } else { |
|
189 |
- ($code, $len) = textfile2code( $file ); |
|
190 |
- } |
|
191 |
- |
|
192 |
- my $header = |
|
193 |
- "const char PROGMEM Http${name}[] =\n" . |
|
194 |
- "\"HTTP/1.0 $ret\\r\\n\"\n" . |
|
195 |
- "\"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n\"\n" . |
|
196 |
- "\"Connection: close\\r\\n\"\n" . |
|
197 |
- "\"Content-Type: $ctype\\r\\n\"\n" . |
|
198 |
- "\"Content-Length: $len\\r\\n\"\n" . |
|
199 |
- "\"\\r\\n\"\n"; |
|
200 |
- my $hlen = length( $header ); |
|
201 |
- |
|
202 |
- return "#define Http${name}HeaderSize $hlen\n$header$code;\n\n" |
|
203 |
-} |
|
204 |
- |
|
205 |
-open( OUTPUT, ">", "$output" ) or die( "cannot open \"$output\" for writing: $!\n" ); |
|
206 |
- |
|
207 |
-print OUTPUT <<EOF; |
|
208 |
-//content for webpages |
|
209 |
-// - characters from 0x80..0xFF indicate a 1 character variable |
|
210 |
- |
|
211 |
-EOF |
|
212 |
- |
|
213 |
-print( OUTPUT gen_page( "400 Bad Request", "$dir/bad_request.html", "BadRequest", "text/html", 0 ) ); |
|
214 |
-print( OUTPUT gen_page( "404 Not Found", "$dir/not_found.html", "NotFound", "text/html", 0 ) ); |
|
215 |
-print( OUTPUT gen_page( "200 Ok", "$dir/index.html", "Index", "text/html", 0 ) ); |
|
216 |
-print( OUTPUT gen_page( "200 Ok", "$dir/dart_no.xml", "DartNo", "text/xml", 0 ) ); |
|
217 |
-print( OUTPUT gen_page( "200 Ok", "$dir/dart_1d.xml", "Dart1d", "text/xml", 0 ) ); |
|
218 |
-print( OUTPUT gen_page( "200 Ok", "$dir/dart_2d.xml", "Dart2d", "text/xml", 0 ) ); |
|
219 |
- |
|
220 |
-close( OUTPUT ); |
|
221 |
- |
... | ... |
@@ -1,10 +0,0 @@ |
1 |
-<soap:Envelope |
|
2 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
3 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
4 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
5 |
- <GetHitResponse> |
|
6 |
- <factor>__FACTOR__</factor> |
|
7 |
- <value>__VALUE_L__</value> |
|
8 |
- </GetHitResponse> |
|
9 |
- </soap:Body> |
|
10 |
-</soap:Envelope> |
... | ... |
@@ -1,10 +0,0 @@ |
1 |
-<soap:Envelope |
|
2 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
3 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
4 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
5 |
- <GetHitResponse> |
|
6 |
- <factor>__FACTOR__</factor> |
|
7 |
- <value>__VALUE_H____VALUE_L__</value> |
|
8 |
- </GetHitResponse> |
|
9 |
- </soap:Body> |
|
10 |
-</soap:Envelope> |
... | ... |
@@ -1,8 +0,0 @@ |
1 |
-<soap:Envelope |
|
2 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
3 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
4 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
5 |
- <GetHitResponse> |
|
6 |
- </GetHitResponse> |
|
7 |
- </soap:Body> |
|
8 |
-</soap:Envelope> |
... | ... |
@@ -1,85 +0,0 @@ |
1 |
-<html> |
|
2 |
- <head> |
|
3 |
- <title>flaneth - dartboard mod</title> |
|
4 |
- <meta http-equiv="pragma" content="no-cache"> |
|
5 |
- </head> |
|
6 |
- <body> |
|
7 |
- <h1>UDP interface</h1> |
|
8 |
- <ul> |
|
9 |
- <li>send empty UDP datagram to UDP port 501</li> |
|
10 |
- <li>receive UDP datagrams containing hit field (e.g. 2x25 for double bull)</li> |
|
11 |
- </ul> |
|
12 |
- <br><br> |
|
13 |
- <h1>SOAP interface</h1> |
|
14 |
- <ul> |
|
15 |
- <li>URL: http://flaneth-dartboard-mod:80/dart</li> |
|
16 |
- </ul> |
|
17 |
- <ul> |
|
18 |
- <li> |
|
19 |
- example request: |
|
20 |
-<pre> |
|
21 |
-<soap:Envelope |
|
22 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
23 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
24 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
25 |
- <GetHit> |
|
26 |
- <timeout>5</timeout> |
|
27 |
- </GetHit> |
|
28 |
- </soap:Body> |
|
29 |
-</soap:Envelope> |
|
30 |
-</pre> |
|
31 |
- timeout: time in seconds to wait for field to be hit<br> |
|
32 |
- </li> |
|
33 |
- <li> |
|
34 |
- example response (double bull): |
|
35 |
-<pre> |
|
36 |
-<soap:Envelope |
|
37 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
38 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
39 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
40 |
- <GetHitResponse> |
|
41 |
- <factor>2</factor> |
|
42 |
- <value>25</value> |
|
43 |
- </GetHitResponse> |
|
44 |
- </soap:Body> |
|
45 |
-</soap:Envelope> |
|
46 |
-</pre> |
|
47 |
- |
|
48 |
- factor: 1 for single, 2 for double, 3 for triple<br> |
|
49 |
- value: value of field that was hit<br> |
|
50 |
- </li> |
|
51 |
- <li> |
|
52 |
- example response (single one): |
|
53 |
-<pre> |
|
54 |
-<soap:Envelope |
|
55 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
56 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
57 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
58 |
- <GetHitResponse> |
|
59 |
- <factor>1</factor> |
|
60 |
- <value>1</value> |
|
61 |
- </GetHitResponse> |
|
62 |
- </soap:Body> |
|
63 |
-</soap:Envelope> |
|
64 |
-</pre> |
|
65 |
- factor: 1 for single, 2 for double, 3 for triple<br> |
|
66 |
- value: value of field that was hit<br> |
|
67 |
- </li> |
|
68 |
- <li> |
|
69 |
- example response (nothing hit): |
|
70 |
-<pre> |
|
71 |
-<soap:Envelope |
|
72 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
73 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
74 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
75 |
- <GetHitResponse> |
|
76 |
- </GetHitResponse> |
|
77 |
- </soap:Body> |
|
78 |
-</soap:Envelope> |
|
79 |
-</pre> |
|
80 |
- </li> |
|
81 |
- </ul> |
|
82 |
- <br><br> |
|
83 |
- flaneth - __VERSION__ |
|
84 |
- </body> |
|
85 |
-</html> |
... | ... |
@@ -1,104 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <string.h> |
|
9 |
- |
|
10 |
-#include "checksum.h" |
|
11 |
-#include "debug.h" |
|
12 |
-#include "ethernet.h" |
|
13 |
-#include "icmp.h" |
|
14 |
-#include "ip.h" |
|
15 |
-#include "macros.h" |
|
16 |
-#include "nethelp.h" |
|
17 |
- |
|
18 |
-// send an ICMP packet |
|
19 |
-// pData must point to a struct IcmpPacket with IcmpHdr.Type, IcmpHdr.Code and IpHdr.Dest already initialized |
|
20 |
-static void IcmpSend( unsigned char * pData, unsigned short Length ) |
|
21 |
-{ |
|
22 |
- struct IcmpPacket * pIcmpPack; |
|
23 |
- unsigned int chk; |
|
24 |
- |
|
25 |
- // packet too short |
|
26 |
- if( Length < sizeof( struct IcmpPacket ) ) |
|
27 |
- return; |
|
28 |
- |
|
29 |
- // convert pointer to ICMP packet |
|
30 |
- // (this saves us from always casting pData) |
|
31 |
- pIcmpPack = (struct IcmpPacket *)pData; |
|
32 |
- |
|
33 |
- debug_icmp_printf( "send type=0x%02X len=%u", pIcmpPack->IcmpHdr.Type, Length ); |
|
34 |
- |
|
35 |
- // fill in header values |
|
36 |
- pIcmpPack->IcmpHdr.Chk = 0x0000; |
|
37 |
- |
|
38 |
- // generate checksum |
|
39 |
- chk = Checksum( (unsigned char *)&pIcmpPack->IcmpHdr, Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ), 0x0000, 0x0000 ); |
|
40 |
- pIcmpPack->IcmpHdr.Chk = htons( chk ); |
|
41 |
- |
|
42 |
- // send ICMP packet |
|
43 |
- pIcmpPack->IpHdr.Proto = 0x01; // ICMP |
|
44 |
- IpSend( pData, Length ); |
|
45 |
-} |
|
46 |
- |
|
47 |
-// process a received ICMP echo request packet |
|
48 |
-static void IcmpEchoReqRecv( unsigned char * pData, unsigned short Length ) |
|
49 |
-{ |
|
50 |
- struct IcmpEchoPacket * pIcmpEchoPack; |
|
51 |
- |
|
52 |
- // packet too short |
|
53 |
- if( Length < sizeof( struct IcmpEchoPacket ) ) |
|
54 |
- return; |
|
55 |
- |
|
56 |
- // convert pointer to ICMP echo request/reply packet |
|
57 |
- // (this saves us from always casting pData) |
|
58 |
- pIcmpEchoPack = (struct IcmpEchoPacket *)pData; |
|
59 |
- |
|
60 |
- // code not 0 |
|
61 |
- if( pIcmpEchoPack->IcmpHdr.Code != 0x00 ) |
|
62 |
- return; |
|
63 |
- |
|
64 |
- debug_icmp_printf( "icmp echo len=%u", Length ); |
|
65 |
- |
|
66 |
- // send an ICMP echo reply |
|
67 |
- // - use same buffer to send reply |
|
68 |
- // - this saves us from needing to allocate a new buffer |
|
69 |
- // - this saves us from needing to copy EchoHdr.Id, EchoHdr.Seq and the data |
|
70 |
- pIcmpEchoPack->IcmpHdr.Type = 0x00; // ICMP echo reply |
|
71 |
- pIcmpEchoPack->IcmpHdr.Code = 0x00; |
|
72 |
- ip_cpy( pIcmpEchoPack->IpHdr.Dest, pIcmpEchoPack->IpHdr.Src ); // destination IP is source IP of request |
|
73 |
- IcmpSend( pData, Length ); |
|
74 |
-} |
|
75 |
- |
|
76 |
-// process a received ICMP packet |
|
77 |
-void IcmpRecv( unsigned char * pData, unsigned short Length ) // (extern) |
|
78 |
-{ |
|
79 |
- struct IcmpPacket * pIcmpPack; |
|
80 |
- |
|
81 |
- // packet too short |
|
82 |
- if( Length < sizeof( struct IcmpPacket ) ) |
|
83 |
- return; |
|
84 |
- |
|
85 |
- // convert pointer to ICMP packet |
|
86 |
- // (this saves us from always casting pData) |
|
87 |
- pIcmpPack = (struct IcmpPacket *)pData; |
|
88 |
- |
|
89 |
- // test checksum |
|
90 |
- if( Checksum( (unsigned char*)&pIcmpPack->IcmpHdr, Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ), 0x0000, 0x0000 ) != 0 ) |
|
91 |
- return; |
|
92 |
- |
|
93 |
- debug_icmp_printf( "recv type=0x%02X len=%u", pIcmpPack->IcmpHdr.Type, Length ); |
|
94 |
- |
|
95 |
- // branch according to type |
|
96 |
- switch( pIcmpPack->IcmpHdr.Type ) |
|
97 |
- { |
|
98 |
- // ICMP echo request |
|
99 |
- case 0x08: |
|
100 |
- IcmpEchoReqRecv( pData, Length ); |
|
101 |
- break; |
|
102 |
- } |
|
103 |
-} |
|
104 |
- |
... | ... |
@@ -1,50 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_icmp |
|
9 |
-#define INC_icmp |
|
10 |
- |
|
11 |
-#include "ethernet.h" |
|
12 |
-#include "ip.h" |
|
13 |
- |
|
14 |
-// header of an ICMP packet |
|
15 |
-struct IcmpHeader |
|
16 |
-{ |
|
17 |
- unsigned char Type; |
|
18 |
- unsigned char Code; |
|
19 |
- unsigned int Chk; |
|
20 |
-}; |
|
21 |
- |
|
22 |
-// an ICMP packet |
|
23 |
-struct IcmpPacket |
|
24 |
-{ |
|
25 |
- struct EthernetHeader EthHdr; |
|
26 |
- struct IpHeader IpHdr; |
|
27 |
- struct IcmpHeader IcmpHdr; |
|
28 |
-}; |
|
29 |
- |
|
30 |
-// header of an ICMP echo request/reply packet |
|
31 |
-struct IcmpEchoHeader |
|
32 |
-{ |
|
33 |
- unsigned int Id; |
|
34 |
- unsigned int Seq; |
|
35 |
-}; |
|
36 |
- |
|
37 |
-// an ICMP echo request/reply packet |
|
38 |
-struct IcmpEchoPacket |
|
39 |
-{ |
|
40 |
- struct EthernetHeader EthHdr; |
|
41 |
- struct IpHeader IpHdr; |
|
42 |
- struct IcmpHeader IcmpHdr; |
|
43 |
- struct IcmpEchoHeader EchoHdr; |
|
44 |
-}; |
|
45 |
- |
|
46 |
-// process a received ICMP packet |
|
47 |
-extern void IcmpRecv( unsigned char * pData, unsigned short Length ); |
|
48 |
- |
|
49 |
-#endif // #ifdef INC_icmp |
|
50 |
- |
... | ... |
@@ -1,319 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <string.h> |
|
9 |
- |
|
10 |
-#include "arp.h" |
|
11 |
-#include "checksum.h" |
|
12 |
-#include "config.h" |
|
13 |
-#include "debug.h" |
|
14 |
-#include "ethernet.h" |
|
15 |
-#include "icmp.h" |
|
16 |
-#include "ip.h" |
|
17 |
-#include "macros.h" |
|
18 |
-#include "nethelp.h" |
|
19 |
-#include "tcp.h" |
|
20 |
-#include "udp.h" |
|
21 |
- |
|
22 |
-// timing parameters |
|
23 |
-#define IpBufferTicksMax 50 // maximum age of buffered IP packet (in 200ms steps) |
|
24 |
- |
|
25 |
-// buffers for IP packets to transmit |
|
26 |
-// - used if MAC is unknown when packet shall be transmitted |
|
27 |
-// - packet is sent when MAC becomes known |
|
28 |
-unsigned char IpBuffer0[80]; // some buffers with different length (IP packets have different length) |
|
29 |
-unsigned char IpBuffer1[80]; |
|
30 |
-unsigned char IpBuffer2[160]; |
|
31 |
-unsigned char IpBuffer3[320]; |
|
32 |
-struct IpBufferTable // table with buffers |
|
33 |
-{ |
|
34 |
- unsigned char * pBuffer; // pointer to buffer for packet |
|
35 |
- unsigned short BufferLength; // length of buffer |
|
36 |
- unsigned short PacketLength; // length of packet in buffer, 0 if no packet in this buffer |
|
37 |
- unsigned char Ticks; // age of entry in 200ms steps |
|
38 |
-} IpBufferTab[] = |
|
39 |
-{ // put smaller buffers in front of larger buffers |
|
40 |
- // - then short packets will use smaller buffers more often |
|
41 |
- { IpBuffer0, sizeof( IpBuffer0 ), 0, 0 }, |
|
42 |
- { IpBuffer1, sizeof( IpBuffer1 ), 0, 0 }, |
|
43 |
- { IpBuffer2, sizeof( IpBuffer2 ), 0, 0 }, |
|
44 |
- { IpBuffer3, sizeof( IpBuffer3 ), 0, 0 }, |
|
45 |
-}; |
|
46 |
- |
|
47 |
-// tick procedure - call every 200ms |
|
48 |
-void IpTick200( void ) // (extern) |
|
49 |
-{ |
|
50 |
- unsigned char i; |
|
51 |
- |
|
52 |
- // increase age of buffered IP packets and remove timed out ones |
|
53 |
- for( i = 0; i < count( IpBufferTab ); i++ ) |
|
54 |
- { |
|
55 |
- if( IpBufferTab[i].PacketLength > 0 ) // buffer in use |
|
56 |
- { |
|
57 |
- IpBufferTab[i].Ticks++; // increase age |
|
58 |
- if( IpBufferTab[i].Ticks > IpBufferTicksMax ) // too old |
|
59 |
- IpBufferTab[i].PacketLength = 0; // discard packet |
|
60 |
- } |
|
61 |
- } |
|
62 |
-} |
|
63 |
- |
|
64 |
-// process a received IP packet |
|
65 |
-void IpRecv( unsigned char * pData, unsigned short Length ) // (extern) |
|
66 |
-{ |
|
67 |
- struct IpPacket * pIpPack; |
|
68 |
- unsigned int len; |
|
69 |
- |
|
70 |
- // packet too short |
|
71 |
- if( Length < sizeof( struct IpPacket ) ) |
|
72 |
- return; |
|
73 |
- |
|
74 |
- // convert pointer to IP packet |
|
75 |
- // (this saves us from always casting pData) |
|
76 |
- pIpPack = (struct IpPacket *)pData; |
|
77 |
- |
|
78 |
- // not IPv4 |
|
79 |
- if( pIpPack->IpHdr.Ver_HdrLen != 0x45 ) // IPv4 with no options present |
|
80 |
- return; |
|
81 |
- |
|
82 |
- // check destination address |
|
83 |
- do { |
|
84 |
- if( ip_eq( pIpPack->IpHdr.Dest, ConfigIp ) ) // own IP |
|
85 |
- break; |
|
86 |
- if( ip_eq( pIpPack->IpHdr.Dest, "\xFF\xFF\xFF\xFF" ) ) // broadcast |
|
87 |
- break; |
|
88 |
- if( pIpPack->IpHdr.Dest[0] == (ConfigIp[0] & ConfigMask[0]) && // local broadcast |
|
89 |
- pIpPack->IpHdr.Dest[1] == (ConfigIp[1] & ConfigMask[1]) && |
|
90 |
- pIpPack->IpHdr.Dest[2] == (ConfigIp[2] & ConfigMask[2]) && |
|
91 |
- pIpPack->IpHdr.Dest[3] == (ConfigIp[3] & ConfigMask[3]) ) |
|
92 |
- break; |
|
93 |
- return; // packet not to this node |
|
94 |
- } while( 0 ); |
|
95 |
- |
|
96 |
- // ignore packets sent from invalid source adresses |
|
97 |
- // - this might be some attack or some router fault |
|
98 |
- if( pIpPack->IpHdr.Src[0] >= 0xE0 || // broadcast, reserved or multicast addresses |
|
99 |
- pIpPack->IpHdr.Src[0] == 0x7F || // loopback network |
|
100 |
- ip_eq( pIpPack->IpHdr.Src, "\x00\x00\x00\x00" ) ) // IP 0.0.0.0 |
|
101 |
- return; |
|
102 |
- // ignore packets sent from local network address or broadcast address |
|
103 |
- if( (pIpPack->IpHdr.Src[0] & ConfigMask[0]) == (ConfigIp[0] & ConfigMask[0]) && // source IP is in own subnet |
|
104 |
- (pIpPack->IpHdr.Src[1] & ConfigMask[1]) == (ConfigIp[1] & ConfigMask[1]) && |
|
105 |
- (pIpPack->IpHdr.Src[2] & ConfigMask[2]) == (ConfigIp[2] & ConfigMask[2]) && |
|
106 |
- (pIpPack->IpHdr.Src[3] & ConfigMask[3]) == (ConfigIp[3] & ConfigMask[3]) ) |
|
107 |
- { |
|
108 |
- if( (pIpPack->IpHdr.Src[0] & ~ConfigMask[0]) == 0x00 && // local network address |
|
109 |
- (pIpPack->IpHdr.Src[1] & ~ConfigMask[1]) == 0x00 && |
|
110 |
- (pIpPack->IpHdr.Src[2] & ~ConfigMask[2]) == 0x00 && |
|
111 |
- (pIpPack->IpHdr.Src[3] & ~ConfigMask[3]) == 0x00 ) |
|
112 |
- return; |
|
113 |
- if( (pIpPack->IpHdr.Src[0] & ~ConfigMask[0]) == 0xFF && // local broadcast address |
|
114 |
- (pIpPack->IpHdr.Src[1] & ~ConfigMask[1]) == 0xFF && |
|
115 |
- (pIpPack->IpHdr.Src[2] & ~ConfigMask[2]) == 0xFF && |
|
116 |
- (pIpPack->IpHdr.Src[3] & ~ConfigMask[3]) == 0xFF ) |
|
117 |
- return; |
|
118 |
- } |
|
119 |
- // ignore packets sent from own IP address |
|
120 |
- if( ip_eq( pIpPack->IpHdr.Src, ConfigIp ) ) |
|
121 |
- return; |
|
122 |
- |
|
123 |
- // ignore fragmented packets |
|
124 |
- // BUG: fragmentation must be supported according to RFC781 |
|
125 |
- // but there is no way of assembling packets with up to 64kB on a processor with 4kB of RAM |
|
126 |
- if( (ntohs( pIpPack->IpHdr.FragOfs ) & 0xBFFF) != 0x0000 ) // fragment offset 0, MoreFrags=0, DontFrag=x, reservedFlag=0 |
|
127 |
- return; |
|
128 |
- |
|
129 |
- // check total length |
|
130 |
- len = sizeof( struct EthernetHeader ) + ntohs( pIpPack->IpHdr.TotalLen ); // length according to IP header |
|
131 |
- if( Length < len ) // packet is truncated |
|
132 |
- return; |
|
133 |
- Length = len; // remove ethernet padding from packet (maybe Length > len) |
|
134 |
- |
|
135 |
- // test header checksum |
|
136 |
- if( Checksum( (unsigned char*)&pIpPack->IpHdr, sizeof( struct IpHeader ), 0x0000, 0x0000 ) != 0 ) |
|
137 |
- return; |
|
138 |
- |
|
139 |
- debug_ip_printf( "recv src=%u.%u.%u.%u protocol=%u len=%u", |
|
140 |
- pIpPack->IpHdr.Src[0], pIpPack->IpHdr.Src[1], |
|
141 |
- pIpPack->IpHdr.Src[2], pIpPack->IpHdr.Src[3], |
|
142 |
- pIpPack->IpHdr.Proto, Length ); |
|
143 |
- |
|
144 |
- // branch according to protocol |
|
145 |
- switch( pIpPack->IpHdr.Proto ) |
|
146 |
- { |
|
147 |
- // ICMP |
|
148 |
- case 0x01: |
|
149 |
- IcmpRecv( pData, Length ); |
|
150 |
- break; |
|
151 |
- // TCP |
|
152 |
- case 0x06: |
|
153 |
- TcpRecv( pData, Length ); |
|
154 |
- break; |
|
155 |
- // UDP |
|
156 |
- case 0x11: |
|
157 |
- UdpRecv( pData, Length ); |
|
158 |
- break; |
|
159 |
- } |
|
160 |
-} |
|
161 |
- |
|
162 |
-// send an IP packet |
|
163 |
-// pData must point to a struct IpPacket with IpHdr.Proto and IpHdr.Dest already initialized |
|
164 |
-void IpSend( unsigned char * pData, unsigned short Length ) // (extern) |
|
165 |
-{ |
|
166 |
- struct IpPacket * pIpPack; |
|
167 |
- unsigned int chk; |
|
168 |
- unsigned char i; |
|
169 |
- |
|
170 |
- // packet too short |
|
171 |
- if( Length < sizeof( struct IpPacket ) ) |
|
172 |
- return; |
|
173 |
- |
|
174 |
- // convert pointer to IP packet |
|
175 |
- // (this saves us from always casting pData) |
|
176 |
- pIpPack = (struct IpPacket *)pData; |
|
177 |
- |
|
178 |
- debug_ip_printf( "send dest=%u.%u.%u.%u protocol=%u len=%u", |
|
179 |
- pIpPack->IpHdr.Dest[0], pIpPack->IpHdr.Dest[1], |
|
180 |
- pIpPack->IpHdr.Dest[2], pIpPack->IpHdr.Dest[3], |
|
181 |
- pIpPack->IpHdr.Proto, Length ); |
|
182 |
- |
|
183 |
- // fill in header values |
|
184 |
- pIpPack->IpHdr.Ver_HdrLen = 0x45; |
|
185 |
- pIpPack->IpHdr.Tos = 0x00; |
|
186 |
- pIpPack->IpHdr.TotalLen = htons( Length - sizeof( struct EthernetHeader ) ); |
|
187 |
- pIpPack->IpHdr.Id = 0x0000; |
|
188 |
- pIpPack->IpHdr.FragOfs = 0x0000; |
|
189 |
- pIpPack->IpHdr.Ttl = 0x40; |
|
190 |
- pIpPack->IpHdr.HdrChk = 0x0000; |
|
191 |
- ip_cpy( pIpPack->IpHdr.Src, ConfigIp ); |
|
192 |
- |
|
193 |
- // generate header checksum |
|
194 |
- chk = Checksum( (unsigned char *)&pIpPack->IpHdr, sizeof( struct IpHeader ), 0x0000, 0x0000 ); |
|
195 |
- pIpPack->IpHdr.HdrChk = htons( chk ); |
|
196 |
- |
|
197 |
- // destination is in own subnet |
|
198 |
- if( (pIpPack->IpHdr.Dest[0] & ConfigMask[0]) == (ConfigIp[0] & ConfigMask[0]) && |
|
199 |
- (pIpPack->IpHdr.Dest[1] & ConfigMask[1]) == (ConfigIp[1] & ConfigMask[1]) && |
|
200 |
- (pIpPack->IpHdr.Dest[2] & ConfigMask[2]) == (ConfigIp[2] & ConfigMask[2]) && |
|
201 |
- (pIpPack->IpHdr.Dest[3] & ConfigMask[3]) == (ConfigIp[3] & ConfigMask[3]) ) |
|
202 |
- { |
|
203 |
- // broadcast |
|
204 |
- if( (pIpPack->IpHdr.Dest[0] | ConfigMask[0]) == 255 && |
|
205 |
- (pIpPack->IpHdr.Dest[1] | ConfigMask[1]) == 255 && |
|
206 |
- (pIpPack->IpHdr.Dest[2] | ConfigMask[2]) == 255 && |
|
207 |
- (pIpPack->IpHdr.Dest[3] | ConfigMask[3]) == 255 ) |
|
208 |
- { |
|
209 |
- mac_cpy( pIpPack->EthHdr.Dest, "\xFF\xFF\xFF\xFF\xFF\xFF" ); |
|
210 |
- i = 0x00; |
|
211 |
- } |
|
212 |
- // unicast |
|
213 |
- else |
|
214 |
- { |
|
215 |
- // lookup MAC address of destination |
|
216 |
- i = ArpLookup( pIpPack->IpHdr.Dest, pIpPack->EthHdr.Dest ); |
|
217 |
- } |
|
218 |
- } |
|
219 |
- // destination is not in own subnet |
|
220 |
- else |
|
221 |
- { |
|
222 |
- // broadcast |
|
223 |
- if( pIpPack->IpHdr.Dest[0] == 255 && |
|
224 |
- pIpPack->IpHdr.Dest[1] == 255 && |
|
225 |
- pIpPack->IpHdr.Dest[2] == 255 && |
|
226 |
- pIpPack->IpHdr.Dest[3] == 255 ) |
|
227 |
- { |
|
228 |
- mac_cpy( pIpPack->EthHdr.Dest, "\xFF\xFF\xFF\xFF\xFF\xFF" ); |
|
229 |
- i = 0x00; |
|
230 |
- } |
|
231 |
- // unicast |
|
232 |
- else |
|
233 |
- { |
|
234 |
- // lookup MAC address of default gateway |
|
235 |
- i = ArpLookup( ConfigGw, pIpPack->EthHdr.Dest ); |
|
236 |
- } |
|
237 |
- } |
|
238 |
- |
|
239 |
- // MAC available |
|
240 |
- if( i == 0x00 ) |
|
241 |
- { |
|
242 |
- // sent IP packet |
|
243 |
- pIpPack->EthHdr.Type = htons( 0x0800 ); // ethernet packet type: IP |
|
244 |
- EthernetSend( pData, Length ); |
|
245 |
- return; |
|
246 |
- } |
|
247 |
- |
|
248 |
- // find a buffer to store the packet in |
|
249 |
- for( i = 0; i < count( IpBufferTab ); i++ ) |
|
250 |
- { |
|
251 |
- if( IpBufferTab[i].PacketLength == 0 && // buffer not in use |
|
252 |
- Length < IpBufferTab[i].BufferLength ) // buffer long enough |
|
253 |
- { |
|
254 |
- // put packet into buffer |
|
255 |
- memcpy( IpBufferTab[i].pBuffer, pData, Length ); |
|
256 |
- IpBufferTab[i].PacketLength = Length; |
|
257 |
- IpBufferTab[i].Ticks = 0; |
|
258 |
- debug_ip_printf( "queued" ); |
|
259 |
- break; |
|
260 |
- } |
|
261 |
- } |
|
262 |
- // if no buffer was found, we cannnot do anything about it and must discard the packet (i.e. do nothing here) |
|
263 |
-} |
|
264 |
- |
|
265 |
-// a MAC address was discovered |
|
266 |
-// called by ARP to notify IP |
|
267 |
-void IpGotMac( unsigned char Ip[4], unsigned char Mac[6] ) // (extern) |
|
268 |
-{ |
|
269 |
- unsigned char i; |
|
270 |
- struct IpPacket * pIpPack; |
|
271 |
- |
|
272 |
- // search for buffered packets that can be sent now |
|
273 |
- for( i = 0; i < count( IpBufferTab ); i++ ) |
|
274 |
- { |
|
275 |
- if( IpBufferTab[i].PacketLength > 0 ) // buffer in use |
|
276 |
- { |
|
277 |
- // convert pointer to IP packet |
|
278 |
- pIpPack = (struct IpPacket *)IpBufferTab[i].pBuffer; |
|
279 |
- |
|
280 |
- debug_ip_printf( "send queued dest=%u.%u.%u.%u protocol=%u len=%u", |
|
281 |
- pIpPack->IpHdr.Dest[0], pIpPack->IpHdr.Dest[1], |
|
282 |
- pIpPack->IpHdr.Dest[2], pIpPack->IpHdr.Dest[3], |
|
283 |
- pIpPack->IpHdr.Proto, IpBufferTab[i].PacketLength ); |
|
284 |
- |
|
285 |
- // destination is in own subnet |
|
286 |
- if( (pIpPack->IpHdr.Dest[0] & ConfigMask[0]) == (ConfigIp[0] & ConfigMask[0]) && |
|
287 |
- (pIpPack->IpHdr.Dest[1] & ConfigMask[1]) == (ConfigIp[1] & ConfigMask[1]) && |
|
288 |
- (pIpPack->IpHdr.Dest[2] & ConfigMask[2]) == (ConfigIp[2] & ConfigMask[2]) && |
|
289 |
- (pIpPack->IpHdr.Dest[3] & ConfigMask[3]) == (ConfigIp[3] & ConfigMask[3]) ) |
|
290 |
- { |
|
291 |
- // packet can be sent to destination |
|
292 |
- if( ip_eq( pIpPack->IpHdr.Dest, Ip ) ) |
|
293 |
- { |
|
294 |
- // send IP packet |
|
295 |
- pIpPack->EthHdr.Type = htons( 0x0800 ); // ethernet packet type: IP |
|
296 |
- mac_cpy( pIpPack->EthHdr.Dest, Mac ); |
|
297 |
- EthernetSend( IpBufferTab[i].pBuffer, IpBufferTab[i].PacketLength ); |
|
298 |
- // buffer is now free |
|
299 |
- IpBufferTab[i].PacketLength = 0; |
|
300 |
- } |
|
301 |
- } |
|
302 |
- // destination is not in own subnet |
|
303 |
- else |
|
304 |
- { |
|
305 |
- // packet can be sent to gateway |
|
306 |
- if( ip_eq( ConfigGw, Ip ) ) |
|
307 |
- { |
|
308 |
- // send IP packet |
|
309 |
- pIpPack->EthHdr.Type = htons( 0x0800 ); // ethernet packet type: IP |
|
310 |
- mac_cpy( pIpPack->EthHdr.Dest, Mac ); |
|
311 |
- EthernetSend( IpBufferTab[i].pBuffer, IpBufferTab[i].PacketLength ); |
|
312 |
- // buffer is now free |
|
313 |
- IpBufferTab[i].PacketLength = 0; |
|
314 |
- } |
|
315 |
- } |
|
316 |
- } |
|
317 |
- } // for( i ... |
|
318 |
-} |
|
319 |
- |
... | ... |
@@ -1,50 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_ip |
|
9 |
-#define INC_ip |
|
10 |
- |
|
11 |
-#include "ethernet.h" |
|
12 |
- |
|
13 |
-// header of an IP packet |
|
14 |
-struct IpHeader |
|
15 |
-{ |
|
16 |
- unsigned char Ver_HdrLen; |
|
17 |
- unsigned char Tos; |
|
18 |
- unsigned int TotalLen; |
|
19 |
- unsigned int Id; |
|
20 |
- unsigned int FragOfs; |
|
21 |
- unsigned char Ttl; |
|
22 |
- unsigned char Proto; |
|
23 |
- unsigned int HdrChk; |
|
24 |
- unsigned char Src[4]; |
|
25 |
- unsigned char Dest[4]; |
|
26 |
-}; |
|
27 |
- |
|
28 |
-// an IP packet |
|
29 |
-struct IpPacket |
|
30 |
-{ |
|
31 |
- struct EthernetHeader EthHdr; |
|
32 |
- struct IpHeader IpHdr; |
|
33 |
-}; |
|
34 |
- |
|
35 |
-// tick procedure - call every 200ms |
|
36 |
-extern void IpTick200( void ); |
|
37 |
- |
|
38 |
-// process a received IP packet |
|
39 |
-extern void IpRecv( unsigned char * pData, unsigned short Length ); |
|
40 |
- |
|
41 |
-// send an IP packet |
|
42 |
-// pData must point to a struct IpPacket with IpHdr.Proto and IpHdr.Dest already initialized |
|
43 |
-extern void IpSend( unsigned char * pData, unsigned short Length ); |
|
44 |
- |
|
45 |
-// a MAC address was discovered |
|
46 |
-// called by ARP to notify IP |
|
47 |
-extern void IpGotMac( unsigned char Ip[4], unsigned char Mac[6] ); |
|
48 |
- |
|
49 |
-#endif // #ifdef INC_ip |
|
50 |
- |
... | ... |
@@ -1,29 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_macros |
|
9 |
-#define INC_macros |
|
10 |
- |
|
11 |
-// minimum and maximum |
|
12 |
-#define min( a, b ) ((a) < (b) ? (a) : (b)) |
|
13 |
-#define max( a, b ) ((a) > (b) ? (a) : (b)) |
|
14 |
- |
|
15 |
-// number of entries in an array |
|
16 |
-#define count( array ) (sizeof( (array) ) / sizeof( (array)[0] )) |
|
17 |
- |
|
18 |
-// waiting |
|
19 |
-#define nop( ) { __asm__ __volatile__ ("nop"::); } |
|
20 |
- |
|
21 |
-// bit manipulation |
|
22 |
-#define bit_set( var, bit ) ((var) |= (1 << (bit))) |
|
23 |
-#define bit_clear( var, bit ) ((var) &= ~(1 << (bit))) |
|
24 |
-#define bit_toggle( var, bit ) ((var) ^= (1 << (bit))) |
|
25 |
-#define is_bit_clear( var, bit ) (!(((var) >> (bit)) & 1)) |
|
26 |
-#define is_bit_set( var, bit ) (((var) >> (bit)) & 1) |
|
27 |
- |
|
28 |
-#endif // #ifndef INC_macros |
|
29 |
- |
... | ... |
@@ -1,91 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/interrupt.h> |
|
9 |
-#include <avr/wdt.h> |
|
10 |
- |
|
11 |
-#include "arp.h" |
|
12 |
-#include "bus.h" |
|
13 |
-#include "cf.h" |
|
14 |
-#include "dart.h" |
|
15 |
-#include "debug.h" |
|
16 |
-#include "eeprom.h" |
|
17 |
-#include "http.h" |
|
18 |
-#include "random.h" |
|
19 |
-#include "rtl8019.h" |
|
20 |
-#include "status.h" |
|
21 |
-#include "tcp.h" |
|
22 |
-#include "timing.h" |
|
23 |
-#include "uart.h" |
|
24 |
- |
|
25 |
-// main code entry point |
|
26 |
-int main( void ) |
|
27 |
-{ |
|
28 |
- wdt_reset( ); |
|
29 |
-#ifdef DEBUG |
|
30 |
- wdt_disable( ); |
|
31 |
-#else |
|
32 |
- wdt_enable( WDTO_60MS ); |
|
33 |
-#endif |
|
34 |
- wdt_reset( ); |
|
35 |
- |
|
36 |
- // initialize uart to be able to use stdio |
|
37 |
- UartInit( ); |
|
38 |
- |
|
39 |
- debug_printf( "" ); |
|
40 |
- debug_printf( "flaneth" ); |
|
41 |
- |
|
42 |
- debug_init_printf( "init" ); |
|
43 |
- |
|
44 |
- // initialize low level modules |
|
45 |
- BusInit( ); |
|
46 |
- |
|
47 |
- // initialize middle level modules |
|
48 |
- CfInit( ); |
|
49 |
- DartInit( ); |
|
50 |
- RtlInit( ); |
|
51 |
- StatusInit( ); |
|
52 |
- TimingInit( ); |
|
53 |
- |
|
54 |
- // initialize high level modules |
|
55 |
- ArpInit( ); |
|
56 |
- HttpInit( ); |
|
57 |
- TcpInit( ); |
|
58 |
- |
|
59 |
- // use entropy collected during initialization |
|
60 |
- RandomTask( ); |
|
61 |
- |
|
62 |
- debug_init_printf( "config" ); |
|
63 |
- |
|
64 |
- // get configuration from EEPROM |
|
65 |
- EepromGetConfig( ); |
|
66 |
- |
|
67 |
- // enable interrupts |
|
68 |
- sei( ); |
|
69 |
- |
|
70 |
- debug_init_printf( "start" ); |
|
71 |
- |
|
72 |
- // main loop |
|
73 |
- while( 1 ) |
|
74 |
- { |
|
75 |
- wdt_reset( ); |
|
76 |
- CfTask( ); |
|
77 |
- wdt_reset( ); |
|
78 |
- DartTask( ); |
|
79 |
- wdt_reset( ); |
|
80 |
- EepromTask( ); |
|
81 |
- wdt_reset( ); |
|
82 |
- RandomTask( ); |
|
83 |
- wdt_reset( ); |
|
84 |
- RtlTask( ); |
|
85 |
- wdt_reset( ); |
|
86 |
- TimingTask( ); |
|
87 |
- } |
|
88 |
- |
|
89 |
- return 0; |
|
90 |
-} |
|
91 |
- |
... | ... |
@@ -1,38 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_nethelp |
|
9 |
-#define INC_nethelp |
|
10 |
- |
|
11 |
-// byte order |
|
12 |
-#define ntohs( n ) ( ((unsigned short)(n) & 0xFF00) >> 8 | \ |
|
13 |
- ((unsigned short)(n) & 0x00FF) << 8 ) |
|
14 |
-#define htons( h ) ( ((unsigned short)(h) & 0xFF00) >> 8 | \ |
|
15 |
- ((unsigned short)(h) & 0x00FF) << 8 ) |
|
16 |
-#define ntohl( n ) ( ((unsigned long)(n) & 0xFF000000) >> 24 | \ |
|
17 |
- ((unsigned long)(n) & 0x00FF0000) >> 8 | \ |
|
18 |
- ((unsigned long)(n) & 0x0000FF00) << 8 | \ |
|
19 |
- ((unsigned long)(n) & 0x000000FF) << 24 ) |
|
20 |
-#define htonl( h ) ( ((unsigned long)(h) & 0xFF000000) >> 24 | \ |
|
21 |
- ((unsigned long)(h) & 0x00FF0000) >> 8 | \ |
|
22 |
- ((unsigned long)(h) & 0x0000FF00) << 8 | \ |
|
23 |
- ((unsigned long)(h) & 0x000000FF) << 24 ) |
|
24 |
- |
|
25 |
-// comparing MACs and IPs |
|
26 |
-#define mac_eq( a, b ) ( (a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && \ |
|
27 |
- (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5] ) |
|
28 |
-#define ip_eq( a, b ) ( (a)[0] == (b)[0] && (a)[1] == (b)[1] && \ |
|
29 |
- (a)[2] == (b)[2] && (a)[3] == (b)[3] ) |
|
30 |
- |
|
31 |
-// copying MACs and IPs |
|
32 |
-#define mac_cpy( dest, src ) ( (dest)[0] = (src)[0], (dest)[1] = (src)[1], (dest)[2] = (src)[2], \ |
|
33 |
- (dest)[3] = (src)[3], (dest)[4] = (src)[4], (dest)[5] = (src)[5] ) |
|
34 |
-#define ip_cpy( dest, src ) ( (dest)[0] = (src)[0], (dest)[1] = (src)[1], \ |
|
35 |
- (dest)[2] = (src)[2], (dest)[3] = (src)[3] ) |
|
36 |
- |
|
37 |
-#endif // #ifndef INC_nethelp |
|
38 |
- |
... | ... |
@@ -1,78 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <stdlib.h> |
|
9 |
- |
|
10 |
-#include "random.h" |
|
11 |
- |
|
12 |
-// number of complete bytes a call to random( ) returns |
|
13 |
-#if RANDOM_MAX < 0xFF |
|
14 |
-#error random number generator is not able to return a random byte |
|
15 |
-#elif RANDOM_MAX < 0xFFFF |
|
16 |
-#define RANDOM_BYTES 1 |
|
17 |
-#elif RANDOM_MAX < 0xFFFFFF |
|
18 |
-#define RANDOM_BYTES 2 |
|
19 |
-#elif RANDOM_MAX < 0xFFFFFFFF |
|
20 |
-#define RANDOM_BYTES 3 |
|
21 |
-#else |
|
22 |
-#define RANDOM_BYTES 4 |
|
23 |
-#endif |
|
24 |
- |
|
25 |
-// entropy collected so far |
|
26 |
-unsigned long RandomEntropy = 0; // the entropy itself |
|
27 |
-unsigned char RandomEntropyCnt // number of times entropy was collected so far |
|
28 |
- = sizeof( unsigned long ) * 8 - 5; // (use first entropy (few is better than none)) |
|
29 |
- |
|
30 |
-// provide some entropy |
|
31 |
-void RandomProvideEntropy( unsigned char Entropy ) // (extern) |
|
32 |
-{ |
|
33 |
- // collect entropy |
|
34 |
- RandomEntropy = RandomEntropy << 1 ^ (unsigned int)Entropy; |
|
35 |
- RandomEntropyCnt++; |
|
36 |
-} |
|
37 |
- |
|
38 |
-// task function to do the work - call from main loop |
|
39 |
-void RandomTask( void ) // (extern) |
|
40 |
-{ |
|
41 |
- // enough entropy was collected |
|
42 |
- if( RandomEntropyCnt >= sizeof( unsigned long ) * 8 ) // one time entropy for every bit of RandomEntropy |
|
43 |
- { |
|
44 |
- RandomEntropyCnt = 0; |
|
45 |
- // re-seed random number generator |
|
46 |
- srandom( RandomEntropy ); |
|
47 |
- } |
|
48 |
-} |
|
49 |
- |
|
50 |
-// get random data |
|
51 |
-void RandomGetData( unsigned char * pData, unsigned char Length ) // (extern) |
|
52 |
-{ |
|
53 |
- unsigned long r; |
|
54 |
- unsigned char i; |
|
55 |
- |
|
56 |
- // return random data |
|
57 |
- for( ; Length >= RANDOM_BYTES; Length -= RANDOM_BYTES ) |
|
58 |
- { |
|
59 |
- r = random( ); |
|
60 |
- for( i = 0; i < RANDOM_BYTES; i++ ) |
|
61 |
- { |
|
62 |
- *pData = (unsigned char)r; |
|
63 |
- pData++; |
|
64 |
- r >>= 8; |
|
65 |
- } |
|
66 |
- } |
|
67 |
- if( Length > 0 ) |
|
68 |
- { |
|
69 |
- r = random( ); |
|
70 |
- for( i = 0; i < Length; i++ ) |
|
71 |
- { |
|
72 |
- *pData = (unsigned char)r; |
|
73 |
- pData++; |
|
74 |
- r >>= 8; |
|
75 |
- } |
|
76 |
- } |
|
77 |
-} |
|
78 |
- |
... | ... |
@@ -1,20 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_random |
|
9 |
-#define INC_random |
|
10 |
- |
|
11 |
-// provide some entropy |
|
12 |
-extern void RandomProvideEntropy( unsigned char Entropy ); |
|
13 |
- |
|
14 |
-// task function to do the work - call from main loop |
|
15 |
-extern void RandomTask( void ); |
|
16 |
- |
|
17 |
-// get random data |
|
18 |
-extern void RandomGetData( unsigned char * pData, unsigned char Length ); |
|
19 |
- |
|
20 |
-#endif // #ifndef INC_random |
... | ... |
@@ -1,546 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/io.h> |
|
9 |
- |
|
10 |
-#include "bus.h" |
|
11 |
-#include "config.h" |
|
12 |
-#include "debug.h" |
|
13 |
-#include "ethernet.h" |
|
14 |
-#include "macros.h" |
|
15 |
-#include "random.h" |
|
16 |
-#include "rtl8019.h" |
|
17 |
-#include "timing.h" |
|
18 |
- |
|
19 |
-// maximum receive unit |
|
20 |
-#define RTL_MRU (640) |
|
21 |
- |
|
22 |
-// reinitialization timeout |
|
23 |
-// - if no reception is detected for this time, the RTL8019 is reinitialized |
|
24 |
-#define RtlReinitTimeoutTicks (50) // in 200ms steps |
|
25 |
- |
|
26 |
-// IO pins of RTL8019 |
|
27 |
-#define RTL_DDR_INT (DDRE) |
|
28 |
-#define RTL_PORT_INT (PORTE) |
|
29 |
-#define RTL_BIT_INT (5) |
|
30 |
-#define RTL_DDR_nAEN (DDRE) |
|
31 |
-#define RTL_PORT_nAEN (PORTE) |
|
32 |
-#define RTL_BIT_nAEN (4) |
|
33 |
-#define RTL_DDR_RST (DDRE) |
|
34 |
-#define RTL_PORT_RST (PORTE) |
|
35 |
-#define RTL_BIT_RST (3) |
|
36 |
-// special pin commands |
|
37 |
-#define RTL_AEN_ACT( ) (bit_clear( RTL_PORT_nAEN, RTL_BIT_nAEN )) |
|
38 |
-#define RTL_AEN_IDLE( ) (bit_set( RTL_PORT_nAEN, RTL_BIT_nAEN )) |
|
39 |
-#define RTL_RESET_ACT( ) (bit_set( RTL_PORT_RST, RTL_BIT_RST )) |
|
40 |
-#define RTL_RESET_IDLE( ) (bit_clear( RTL_PORT_RST, RTL_BIT_RST )) |
|
41 |
- |
|
42 |
-// IO pins of RTL8019 EEPROM interface |
|
43 |
-#define RTL_DDR_EECS (DDRD) |
|
44 |
-#define RTL_PORT_EECS (PORTD) |
|
45 |
-#define RTL_PIN_EECS (PIND) |
|
46 |
-#define RTL_BIT_EECS (7) |
|
47 |
-#define RTL_DDR_EESK (DDRD) |
|
48 |
-#define RTL_PORT_EESK (PORTD) |
|
49 |
-#define RTL_PIN_EESK (PIND) |
|
50 |
-#define RTL_BIT_EESK (4) |
|
51 |
-#define RTL_DDR_EEDI (DDRD) |
|
52 |
-#define RTL_PORT_EEDI (PORTD) |
|
53 |
-#define RTL_PIN_EEDI (PIND) |
|
54 |
-#define RTL_BIT_EEDI (5) |
|
55 |
-#define RTL_DDR_EEDO (DDRD) |
|
56 |
-#define RTL_PORT_EEDO (PORTD) |
|
57 |
-#define RTL_BIT_EEDO (6) |
|
58 |
- |
|
59 |
-// RTL8019 registers |
|
60 |
-#define RTL_REG_CR (0x00) |
|
61 |
-#define RTL_REG_PSTART (0x01) |
|
62 |
-#define RTL_REG_PAR0 (0x01) |
|
63 |
-#define RTL_REG_PSTOP (0x02) |
|
64 |
-#define RTL_REG_BNRY (0x03) |
|
65 |
-#define RTL_REG_TPSR (0x04) |
|
66 |
-#define RTL_REG_TBCR0 (0x05) |
|
67 |
-#define RTL_REG_TBCR1 (0x06) |
|
68 |
-#define RTL_REG_ISR (0x07) |
|
69 |
-#define RTL_REG_CURR (0x07) |
|
70 |
-#define RTL_REG_RSAR0 (0x08) |
|
71 |
-#define RTL_REG_CRDA0 (0x08) |
|
72 |
-#define RTL_REG_RSAR1 (0x09) |
|
73 |
-#define RTL_REG_CRDAl (0x09) |
|
74 |
-#define RTL_REG_RBCR0 (0x0A) |
|
75 |
-#define RTL_REG_ID0 (0x0A) |
|
76 |
-#define RTL_REG_ID1 (0x0B) |
|
77 |
-#define RTL_REG_RBCR1 (0x0B) |
|
78 |
-#define RTL_REG_RSR (0x0C) |
|
79 |
-#define RTL_REG_RCR (0x0C) |
|
80 |
-#define RTL_REG_TCR (0x0D) |
|
81 |
-#define RTL_REG_CNTR0 (0x0D) |
|
82 |
-#define RTL_REG_DCR (0x0E) |
|
83 |
-#define RTL_REG_CNTR1 (0x0E) |
|
84 |
-#define RTL_REG_IMR (0x0F) |
|
85 |
-#define RTL_REG_CNTR2 (0x0F) |
|
86 |
-#define RTL_REG_RDMAPORT (0x10) |
|
87 |
-#define RTL_REG_RSTPORT (0x18) |
|
88 |
- |
|
89 |
-// RTL8019AS CR register bits |
|
90 |
-#define RTL_CR_STP (0) |
|
91 |
-#define RTL_CR_STA (1) |
|
92 |
-#define RTL_CR_TXP (2) |
|
93 |
-#define RTL_CR_RD0 (3) |
|
94 |
-#define RTL_CR_RD1 (4) |
|
95 |
-#define RTL_CR_RD2 (5) |
|
96 |
-#define RTL_CR_PS0 (6) |
|
97 |
-#define RTL_CR_PS1 (7) |
|
98 |
- |
|
99 |
-// RTL8019 ISR register bits |
|
100 |
-#define RTL_ISR_PRX (0) |
|
101 |
-#define RTL_ISR_PTX (1) |
|
102 |
-#define RTL_ISR_RXE (2) |
|
103 |
-#define RTL_ISR_TXE (3) |
|
104 |
-#define RTL_ISR_OVW (4) |
|
105 |
-#define RTL_ISR_CNT (5) |
|
106 |
-#define RTL_ISR_RDC (6) |
|
107 |
-#define RTL_ISR_RST (7) |
|
108 |
- |
|
109 |
-// RTL8019 (initial) register values |
|
110 |
-#define RTL_VAL_RCR (0x04) |
|
111 |
-#define RTL_VAL_TCR (0x00) |
|
112 |
-#define RTL_VAL_DCR (0x58) |
|
113 |
-#define RTL_VAL_IMR (0x00) |
|
114 |
-#define RTL_VAL_TXSTART (0x40) |
|
115 |
-#define RTL_VAL_RXSTART (0x46) |
|
116 |
-#define RTL_VAL_RXSTOP (0x60) |
|
117 |
- |
|
118 |
-// write a RTL8019 register |
|
119 |
-extern inline void RtlWriteReg( unsigned char reg, unsigned char val ) // force inlining by using "extern" |
|
120 |
-{ |
|
121 |
- BUS_DATA = val; // output value |
|
122 |
- BUS_DATA_DDR = 0xFF; // data port to output |
|
123 |
- BUS_ADDR = reg; // output address |
|
124 |
- RTL_AEN_ACT( ); // set address enable |
|
125 |
- BUS_WRITE_ACT( ); // activate write signal |
|
126 |
- nop( ); |
|
127 |
- nop( ); |
|
128 |
- BUS_WRITE_IDLE( ); // take back write signal |
|
129 |
- RTL_AEN_IDLE( ); // take back address enable |
|
130 |
- BUS_DATA_DDR = 0x00; // data back port to input |
|
131 |
- BUS_DATA = 0x00; // turn off pullups |
|
132 |
-} |
|
133 |
- |
|
134 |
-// write buffer to RTL8019 register |
|
135 |
-extern inline void RtlWriteRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern" |
|
136 |
-{ |
|
137 |
- BUS_DATA = *p_buf; // output first value to initialize port status before switching to output |
|
138 |
- BUS_DATA_DDR = 0xFF; // data port to output |
|
139 |
- BUS_ADDR = reg; // output address |
|
140 |
- RTL_AEN_ACT( ); // set address enable |
|
141 |
- for( ; len > 0; p_buf++, len-- ) { |
|
142 |
- BUS_DATA = *p_buf; // output value |
|
143 |
- BUS_WRITE_ACT( ); // activate write signal |
|
144 |
- nop( ); |
|
145 |
- nop( ); |
|
146 |
- BUS_WRITE_IDLE( ); // take back write signal |
|
147 |
- } |
|
148 |
- RTL_AEN_IDLE( ); // take back address enable |
|
149 |
- BUS_DATA_DDR = 0x00; // data back port to input |
|
150 |
- BUS_DATA = 0x00; // turn off pullups |
|
151 |
-} |
|
152 |
- |
|
153 |
-// write constant to RTL8019 register multiple times |
|
154 |
-extern inline void RtlWriteRegConst( unsigned char reg, unsigned char val, unsigned short cnt ) // force inlining by using "extern" |
|
155 |
-{ |
|
156 |
- BUS_DATA = val; // output value |
|
157 |
- BUS_DATA_DDR = 0xFF; // data port to output |
|
158 |
- BUS_ADDR = reg; // output address |
|
159 |
- RTL_AEN_ACT( ); // set address enable |
|
160 |
- for( ; cnt > 0; cnt-- ) { |
|
161 |
- BUS_WRITE_ACT( ); // activate write signal |
|
162 |
- nop( ); |
|
163 |
- nop( ); |
|
164 |
- BUS_WRITE_IDLE( ); // take back write signal |
|
165 |
- } |
|
166 |
- RTL_AEN_IDLE( ); // take back address enable |
|
167 |
- BUS_DATA_DDR = 0x00; // data back port to input |
|
168 |
- BUS_DATA = 0x00; // turn off pullups |
|
169 |
-} |
|
170 |
- |
|
171 |
-// read a RTL8019 register |
|
172 |
-extern inline void RtlReadReg( unsigned char reg, unsigned char * p_var ) // force inlining by using "extern" |
|
173 |
-{ |
|
174 |
- BUS_ADDR = reg; // output address |
|
175 |
- RTL_AEN_ACT( ); // set address enable |
|
176 |
- BUS_READ_ACT( ); // activate read signal |
|
177 |
- nop( ); |
|
178 |
- nop( ); |
|
179 |
- *p_var = BUS_DATA_IN; // read data |
|
180 |
- BUS_READ_IDLE( ); // take back read signal |
|
181 |
- RTL_AEN_IDLE( ); // take back address enable |
|
182 |
-} |
|
183 |
- |
|
184 |
-// read buffer from RTL8019 register |
|
185 |
-extern inline void RtlReadRegBuf( unsigned char reg, unsigned char * p_buf, unsigned short len ) // force inlining by using "extern" |
|
186 |
-{ |
|
187 |
- BUS_ADDR = reg; // output address |
|
188 |
- RTL_AEN_ACT( ); // set address enable |
|
189 |
- for( ; len > 0; p_buf++, len-- ) { |
|
190 |
- BUS_READ_ACT( ); // activate read signal |
|
191 |
- nop( ); |
|
192 |
- nop( ); |
|
193 |
- *p_buf = BUS_DATA_IN; // read data |
|
194 |
- BUS_READ_IDLE( ); // take back read signal |
|
195 |
- } |
|
196 |
- RTL_AEN_IDLE( ); // take back address enable |
|
197 |
-} |
|
198 |
- |
|
199 |
-// read a RTL8019 register multiple times and throw away data |
|
200 |
-extern inline void RtlReadRegMulti( unsigned char reg, unsigned short cnt ) // force inlining by using "extern" |
|
201 |
-{ |
|
202 |
- BUS_ADDR = reg; // output address |
|
203 |
- RTL_AEN_ACT( ); // set address enable |
|
204 |
- for( ; cnt > 0; cnt-- ) { |
|
205 |
- BUS_READ_ACT( ); // activate read signal |
|
206 |
- nop( ); |
|
207 |
- nop( ); |
|
208 |
- BUS_READ_IDLE( ); // take back read signal |
|
209 |
- } |
|
210 |
- RTL_AEN_IDLE( ); // take back address enable |
|
211 |
-} |
|
212 |
- |
|
213 |
-// reinitialization timeout counter |
|
214 |
-unsigned char RtlReinitTimeout = 0; |
|
215 |
- |
|
216 |
-// emulate eeprom containing RTL8019AS configuration |
|
217 |
-static void RtlEmulateEeprom( void ) |
|
218 |
-{ |
|
219 |
- static const unsigned char timeout = 150; |
|
220 |
- |
|
221 |
- unsigned int addr, data, entropy; |
|
222 |
- unsigned char t, i; |
|
223 |
- |
|
224 |
- while( 1 ) { |
|
225 |
- entropy = 0; |
|
226 |
- |
|
227 |
- // wait for CS HIGH |
|
228 |
- for( t = 0; bit_is_clear( RTL_PIN_EECS, RTL_BIT_EECS ); t++ ) |
|
229 |
- if( t >= timeout ) |
|
230 |
- return; |
|
231 |
- entropy += t; |
|
232 |
- |
|
233 |
- // ignore one clock |
|
234 |
- // wait for clock HIGH |
|
235 |
- for( t = 0; bit_is_clear( RTL_PIN_EESK, RTL_BIT_EESK ); t++ ) |
|
236 |
- if( t >= timeout ) |
|
237 |
- return; |
|
238 |
- entropy += t; |
|
239 |
- // wait for clock LOW |
|
240 |
- for( t = 0; bit_is_set( RTL_PIN_EESK, RTL_BIT_EESK ); t++ ) |
|
241 |
- if( t >= timeout ) |
|
242 |
- return; |
|
243 |
- entropy += t; |
|
244 |
- |
|
245 |
- // shift in address |
|
246 |
- addr = 0; |
|
247 |
- for( i = 0; i < 9; i++ ) { |
|
248 |
- // wait for clock HIGH |
|
249 |
- for( t = 0; bit_is_clear( RTL_PIN_EESK, RTL_BIT_EESK ); t++ ) |
|
250 |
- if( t >= timeout ) |
|
251 |
- return; |
|
252 |
- entropy += t; |
|
253 |
- // read next bit |
|
254 |
- addr <<= 1; |
|
255 |
- if( bit_is_set( RTL_PIN_EEDI, RTL_BIT_EEDI ) ) |
|
256 |
- addr |= 0x01; |
|
257 |
- // wait for clock LOW |
|
258 |
- for( t = 0; bit_is_set( RTL_PIN_EESK, RTL_BIT_EESK ); t++ ) |
|
259 |
- if( t >= timeout ) |
|
260 |
- return; |
|
261 |
- entropy += t; |
|
262 |
- } |
|
263 |
- |
|
264 |
- // get data |
|
265 |
- switch( addr ) { |
|
266 |
- // CONFIG 3 = FUDUP,LEDS0; CONFIG 4 = - |
|
267 |
- case 0x181: |
|
268 |
- data = 0x0050; |
|
269 |
- break; |
|
270 |
- // output zero by default (as if no EEPROM is connected) |
|
271 |
- default: |
|
272 |
- data = 0x0000; |
|
273 |
- break; |
|
274 |
- } |
|
275 |
- |
|
276 |
- // shift out data |
|
277 |
- for( i = 0; i < 16; i++ ) { |
|
278 |
- // wait for clock HIGH |
|
279 |
- for( t = 0; bit_is_clear( RTL_PIN_EESK, RTL_BIT_EESK ); t++ ) |
|
280 |
- if( t >= timeout ) |
|
281 |
- return; |
|
282 |
- entropy += t; |
|
283 |
- // write next bit |
|
284 |
- if( data & 0x8000 ) |
|
285 |
- bit_set( RTL_PORT_EEDO, RTL_BIT_EEDO ); |
|
286 |
- else |
|
287 |
- bit_clear( RTL_PORT_EEDO, RTL_BIT_EEDO ); |
|
288 |
- data <<= 1; |
|
289 |
- // wait for clock LOW |
|
290 |
- for( t = 0; bit_is_set( RTL_PIN_EESK, RTL_BIT_EESK ); t++ ) |
|
291 |
- if( t >= timeout ) |
|
292 |
- return; |
|
293 |
- entropy += t; |
|
294 |
- } |
|
295 |
- |
|
296 |
- // wait for CS LOW |
|
297 |
- for( t = 0; bit_is_set( RTL_PIN_EECS, RTL_BIT_EECS ); t++ ) |
|
298 |
- if( t >= timeout ) |
|
299 |
- return; |
|
300 |
- entropy += t; |
|
301 |
- |
|
302 |
- // pass on entropy to randomness generator |
|
303 |
- RandomProvideEntropy( (unsigned char)entropy ); |
|
304 |
- |
|
305 |
- } // while( 1 ) |
|
306 |
-} |
|
307 |
- |
|
308 |
-// initialize |
|
309 |
-void RtlInit( void ) // (extern) |
|
310 |
-{ |
|
311 |
- unsigned char i; |
|
312 |
- unsigned short j; |
|
313 |
- |
|
314 |
- // setup ports |
|
315 |
- bit_clear( RTL_PORT_INT, RTL_BIT_INT ); // pull-up of interrupt pin off |
|
316 |
- bit_clear( RTL_DDR_INT, RTL_BIT_INT ); // interrupt pin to input |
|
317 |
- bit_set( RTL_PORT_nAEN, RTL_BIT_nAEN ); // address enable pin to HIGH |
|
318 |
- bit_set( RTL_DDR_nAEN, RTL_BIT_nAEN ); // address enable pin to output |
|
319 |
- bit_set( RTL_PORT_RST, RTL_BIT_RST ); // reset pin to HIGH |
|
320 |
- bit_set( RTL_DDR_RST, RTL_BIT_RST ); // reset pin to output |
|
321 |
- |
|
322 |
- // configuration of EEPROM emulation |
|
323 |
- bit_clear( RTL_PORT_EECS, RTL_BIT_EECS ); // EECS := input, no pull-up |
|
324 |
- bit_clear( RTL_DDR_EECS, RTL_BIT_EECS ); |
|
325 |
- bit_clear( RTL_PORT_EESK, RTL_BIT_EESK ); // EESK := input, no pull-up |
|
326 |
- bit_clear( RTL_DDR_EESK, RTL_BIT_EESK ); |
|
327 |
- bit_clear( RTL_PORT_EEDI, RTL_BIT_EEDI ); // EEDI := input, no pull-up |
|
328 |
- bit_clear( RTL_DDR_EEDI, RTL_BIT_EEDI ); |
|
329 |
- bit_clear( RTL_PORT_EEDO, RTL_BIT_EEDO ); // EEDO := output, LOW |
|
330 |
- bit_set( RTL_DDR_EEDO, RTL_BIT_EEDO ); |
|
331 |
- |
|
332 |
- // take back reset |
|
333 |
- for( i = 0; i < 10; i++ ) |
|
334 |
- nop( ); |
|
335 |
- RTL_RESET_IDLE( ); |
|
336 |
- RtlEmulateEeprom( ); |
|
337 |
- for( j = 0; j < 5000; j++ ) |
|
338 |
- nop( ); |
|
339 |
- |
|
340 |
- // clear software reset |
|
341 |
- RtlReadReg( RTL_REG_RSTPORT, &i ); |
|
342 |
- RtlWriteReg( RTL_REG_RSTPORT, 0xFF ); |
|
343 |
- for( i = 0; i < 100; i++ ) |
|
344 |
- nop( ); |
|
345 |
- |
|
346 |
- // do the same as in reinitialization |
|
347 |
- RtlReinit( ); |
|
348 |
-} |
|
349 |
- |
|
350 |
-// re-initialize RT8019 (i.e. if MAC changed) |
|
351 |
-void RtlReinit( void ) // (extern) |
|
352 |
-{ |
|
353 |
- unsigned char i, j; |
|
354 |
- |
|
355 |
- // stop RTL8019 |
|
356 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STP | 1<<RTL_CR_RD2 ); |
|
357 |
- for( i = 0; i < 100; i++ ) |
|
358 |
- nop( ); |
|
359 |
- |
|
360 |
- // output RTL8019 ID |
|
361 |
- RtlReadReg( RTL_REG_ID0, &i ); |
|
362 |
- RtlReadReg( RTL_REG_ID1, &j ); |
|
363 |
- debug_rtl8019_printf( "RTL8019AS (re)init ID=0x%02X,0x%02X", i, j ); |
|
364 |
- |
|
365 |
- // set up RTL8019 |
|
366 |
- RtlWriteReg( RTL_REG_DCR, RTL_VAL_DCR ); |
|
367 |
- RtlWriteReg( RTL_REG_RBCR0, 0x00 ); |
|
368 |
- RtlWriteReg( RTL_REG_RBCR1, 0x00 ); |
|
369 |
- RtlWriteReg( RTL_REG_RCR, 0x04 ); |
|
370 |
- RtlWriteReg( RTL_REG_TPSR, RTL_VAL_RXSTART ); |
|
371 |
- RtlWriteReg( RTL_REG_TCR, 0x02 ); |
|
372 |
- RtlWriteReg( RTL_REG_PSTART, RTL_VAL_RXSTART ); |
|
373 |
- RtlWriteReg( RTL_REG_BNRY, RTL_VAL_RXSTART ); |
|
374 |
- RtlWriteReg( RTL_REG_PSTOP, RTL_VAL_RXSTOP ); |
|
375 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STP | 1<<RTL_CR_RD2 | 1<<RTL_CR_PS0 ); |
|
376 |
- for( i = 0; i < 100; i++ ) |
|
377 |
- nop( ); |
|
378 |
- |
|
379 |
- // write MAC to chip |
|
380 |
- RtlWriteReg( RTL_REG_CURR, RTL_VAL_RXSTART ); |
|
381 |
- for( i = 0; i < 6; i++ ) |
|
382 |
- RtlWriteReg( RTL_REG_PAR0 + i, ConfigMac[i] ); |
|
383 |
- |
|
384 |
- // go on with intializing |
|
385 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STP | 1<<RTL_CR_RD2 ); |
|
386 |
- RtlWriteReg( RTL_REG_DCR, RTL_VAL_DCR ); |
|
387 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 ); |
|
388 |
- RtlWriteReg( RTL_REG_ISR, 1<<RTL_ISR_PRX | 1<<RTL_ISR_PTX | |
|
389 |
- 1<<RTL_ISR_RXE | 1<<RTL_ISR_TXE | |
|
390 |
- 1<<RTL_ISR_OVW | 1<<RTL_ISR_CNT | |
|
391 |
- 1<<RTL_ISR_RDC | 1<<RTL_ISR_RST ); |
|
392 |
- RtlWriteReg( RTL_REG_IMR, RTL_VAL_IMR ); |
|
393 |
- RtlWriteReg( RTL_REG_TCR, RTL_VAL_TCR ); |
|
394 |
- |
|
395 |
- // start RTL8019 |
|
396 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 ); |
|
397 |
- |
|
398 |
- // clear reinitialization timeout |
|
399 |
- RtlReinitTimeout = 0; |
|
400 |
-} |
|
401 |
- |
|
402 |
-// tick procedure - call every 200ms |
|
403 |
-void RtlTick200( void ) // (extern) |
|
404 |
-{ |
|
405 |
- // increment reinitialization timeout counter |
|
406 |
- RtlReinitTimeout++; |
|
407 |
- |
|
408 |
- // reinitialization timeout |
|
409 |
- if( RtlReinitTimeout >= RtlReinitTimeoutTicks ) |
|
410 |
- // reinitialize RTL8019 (resets reinitialization timeout) |
|
411 |
- RtlReinit( ); |
|
412 |
-} |
|
413 |
- |
|
414 |
-// fetch and process a received packet |
|
415 |
-static inline void RtlRecv( void ) |
|
416 |
-{ |
|
417 |
- unsigned short PacketLen; |
|
418 |
- unsigned char Packet[RTL_MRU]; |
|
419 |
- |
|
420 |
- // fetch packet from RTL8019 |
|
421 |
- PacketLen = count( Packet ); |
|
422 |
- RtlReadFrame( (unsigned char *)Packet, &PacketLen ); |
|
423 |
- |
|
424 |
- // pass packet on to ethernet |
|
425 |
- EthernetRecv( Packet, PacketLen ); |
|
426 |
-} |
|
427 |
- |
|
428 |
-// task function to do the work - call from main loop |
|
429 |
-void RtlTask( void ) // (extern) |
|
430 |
-{ |
|
431 |
- unsigned char isr, bnry, curr; |
|
432 |
- |
|
433 |
- // read interrupt register |
|
434 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 ); |
|
435 |
- RtlReadReg( RTL_REG_ISR, &isr ); |
|
436 |
- // a packet was received |
|
437 |
- if( isr & 1<<RTL_ISR_PRX ) |
|
438 |
- // use current timestamp for generating some entropy |
|
439 |
- TimingEntropy( ); |
|
440 |
- |
|
441 |
- // check if receive ring buffer is not empty |
|
442 |
- RtlReadReg( RTL_REG_BNRY, &bnry ); |
|
443 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 | 1<<RTL_CR_PS0 ); |
|
444 |
- RtlReadReg( RTL_REG_CURR, &curr ); |
|
445 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 ); |
|
446 |
- if( bnry != curr ) |
|
447 |
- // fetch and process a single received packet |
|
448 |
- RtlRecv( ); |
|
449 |
- |
|
450 |
- // reset interrupt bits of RTL8019 |
|
451 |
- RtlWriteReg( RTL_REG_ISR, 1<<RTL_ISR_PRX | 1<<RTL_ISR_PTX | |
|
452 |
- 1<<RTL_ISR_RXE | 1<<RTL_ISR_TXE | |
|
453 |
- 1<<RTL_ISR_OVW | 1<<RTL_ISR_CNT | |
|
454 |
- 1<<RTL_ISR_RDC | 1<<RTL_ISR_RST ); |
|
455 |
- |
|
456 |
- // put RTL8019 in default state (default page selected, ...) |
|
457 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 ); |
|
458 |
- |
|
459 |
- // clear reinitialization timeout |
|
460 |
- RtlReinitTimeout = 0; |
|
461 |
-} |
|
462 |
- |
|
463 |
-// write an ethernet frame to the RTL8019 |
|
464 |
-void RtlWriteFrame( unsigned char * pData, unsigned short Length ) // (extern) |
|
465 |
-{ |
|
466 |
- unsigned char val; |
|
467 |
- |
|
468 |
- debug_rtl8019_printf( "send len=%u", Length ); |
|
469 |
- |
|
470 |
- // initialize RTL8019 to transmit |
|
471 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD2 ); |
|
472 |
- RtlWriteReg( RTL_REG_TPSR, RTL_VAL_TXSTART ); |
|
473 |
- RtlWriteReg( RTL_REG_RSAR0, 0x00 ); |
|
474 |
- RtlWriteReg( RTL_REG_RSAR1, RTL_VAL_TXSTART ); |
|
475 |
- RtlWriteReg( RTL_REG_ISR, 1<<RTL_ISR_PRX | 1<<RTL_ISR_PTX | |
|
476 |
- 1<<RTL_ISR_RXE | 1<<RTL_ISR_TXE | |
|
477 |
- 1<<RTL_ISR_OVW | 1<<RTL_ISR_CNT | |
|
478 |
- 1<<RTL_ISR_RDC | 1<<RTL_ISR_RST ); |
|
479 |
- if( Length < 0x3C ) // minimal length is 60 bytes |
|
480 |
- { |
|
481 |
- RtlWriteReg( RTL_REG_RBCR0, 0x3C ); |
|
482 |
- RtlWriteReg( RTL_REG_RBCR1, 0x00 ); |
|
483 |
- } |
|
484 |
- else |
|
485 |
- { |
|
486 |
- RtlWriteReg( RTL_REG_RBCR0, (unsigned char)Length ); |
|
487 |
- RtlWriteReg( RTL_REG_RBCR1, (unsigned char)(Length >> 8) ); |
|
488 |
- } |
|
489 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD1 ); |
|
490 |
- |
|
491 |
- // write data to RTL8019 |
|
492 |
- RtlWriteRegBuf( RTL_REG_RDMAPORT, pData, Length ); |
|
493 |
- if( Length < 0x3C ) // padding |
|
494 |
- RtlWriteRegConst( RTL_REG_RDMAPORT, 0x00, 0x3C - Length ); |
|
495 |
- |
|
496 |
- // wait for RTL8019 |
|
497 |
- do |
|
498 |
- { |
|
499 |
- RtlReadReg( RTL_REG_ISR, &val ); |
|
500 |
- } |
|
501 |
- while( (val & 1<<RTL_ISR_RDC) == 0x00 ); |
|
502 |
- |
|
503 |
- // start transmission |
|
504 |
- if( Length < 0x3C ) // minimal length is 60 bytes |
|
505 |
- { |
|
506 |
- RtlWriteReg( RTL_REG_TBCR0, 0x3C ); |
|
507 |
- RtlWriteReg( RTL_REG_TBCR1, 0x00 ); |
|
508 |
- } |
|
509 |
- else |
|
510 |
- { |
|
511 |
- RtlWriteReg( RTL_REG_TBCR0, (unsigned char)Length ); |
|
512 |
- RtlWriteReg( RTL_REG_TBCR1, (unsigned char)(Length >> 8) ); |
|
513 |
- } |
|
514 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_TXP | 1<<RTL_CR_RD2 ); |
|
515 |
-} |
|
516 |
- |
|
517 |
-// read an ethernet frame from the RTL8019 |
|
518 |
-// *pLength must be initialized to the buffer size |
|
519 |
-void RtlReadFrame( unsigned char * pData, unsigned short * pLength ) // (extern) |
|
520 |
-{ |
|
521 |
- unsigned char tmp1, tmp2; |
|
522 |
- unsigned short read_len, len, cnt; |
|
523 |
- |
|
524 |
- // get size of received packet |
|
525 |
- RtlWriteReg( RTL_REG_CR, 1<<RTL_CR_STA | 1<<RTL_CR_RD0 | 1<<RTL_CR_RD1 ); |
|
526 |
- RtlReadReg( RTL_REG_RDMAPORT, &tmp1 ); |
|
527 |
- RtlReadReg( RTL_REG_RDMAPORT, &tmp1 ); |
|
528 |
- RtlReadReg( RTL_REG_RDMAPORT, &tmp1 ); |
|
529 |
- RtlReadReg( RTL_REG_RDMAPORT, &tmp2 ); |
|
530 |
- read_len = ((unsigned short)tmp2 << 8 | (unsigned short)tmp1); |
|
531 |
- |
|
532 |
- // subtract length of CRC (4 bytes) |
|
533 |
- len = read_len < 4 ? 0 : read_len - 4; |
|
534 |
- |
|
535 |
- debug_rtl8019_printf( "recv len=%u", len ); |
|
536 |
- |
|
537 |
- // read as much data as possible into buffer |
|
538 |
- cnt = min( len, *pLength ); |
|
539 |
- RtlReadRegBuf( RTL_REG_RDMAPORT, pData, cnt ); |
|
540 |
- *pLength = cnt; |
|
541 |
- |
|
542 |
- // get rest of data (rest of real data that did not fit into buffer, CRC) |
|
543 |
- if( read_len > cnt ) |
|
544 |
- RtlReadRegMulti( RTL_REG_RDMAPORT, read_len - cnt ); |
|
545 |
-} |
|
546 |
- |
... | ... |
@@ -1,31 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_rtl8019 |
|
9 |
-#define INC_rtl8019 |
|
10 |
- |
|
11 |
-// initialize |
|
12 |
-extern void RtlInit( void ); |
|
13 |
- |
|
14 |
-// re-initialize RT8019 (i.e. if MAC changed) |
|
15 |
-extern void RtlReinit( void ); |
|
16 |
- |
|
17 |
-// tick procedure - call every 200ms |
|
18 |
-extern void RtlTick200( void ); |
|
19 |
- |
|
20 |
-// task function to do the work - call from main loop |
|
21 |
-extern void RtlTask( void ); |
|
22 |
- |
|
23 |
-// write an ethernet frame to the RTL8019 |
|
24 |
-extern void RtlWriteFrame( unsigned char * pData, unsigned short Length ); |
|
25 |
- |
|
26 |
-// read an ethernet frame from the RTL8019 |
|
27 |
-// *pLength must be initialized to the buffer size |
|
28 |
-extern void RtlReadFrame( unsigned char * pData, unsigned short * pLength ); |
|
29 |
- |
|
30 |
-#endif // #ifndef INC_rtl8019 |
|
31 |
- |
... | ... |
@@ -1,59 +0,0 @@ |
1 |
-<?php |
|
2 |
-include("nb_easyxml_lite.php"); |
|
3 |
-include("nb_soapfuncs.php"); |
|
4 |
- |
|
5 |
-/********* Data structures used by this web service ********* |
|
6 |
-* |
|
7 |
-* type GetHitResult{ |
|
8 |
-* ['factor']=>{ |
|
9 |
-* } |
|
10 |
-* ['value']=>{ |
|
11 |
-* } |
|
12 |
-* } |
|
13 |
-* |
|
14 |
-*/ |
|
15 |
- |
|
16 |
-class service |
|
17 |
-{ |
|
18 |
- var $Url; |
|
19 |
- |
|
20 |
-/** |
|
21 |
-* web service consumer method GetHit |
|
22 |
-* |
|
23 |
-* @param timeout : unsigned |
|
24 |
-* @return GetHitResult |
|
25 |
-*/ |
|
26 |
- function GetHit($timeout) // returns a GetHitResult |
|
27 |
- { |
|
28 |
- $soapXML = "<soap:Body>\n"; |
|
29 |
- $soapXML .= "<GetHit xmlns=\"http://localhost:8080/dart\">\n"; |
|
30 |
- // Parameter unsigned timeout |
|
31 |
- $soapXML .= $this->soapify_unsigned($timeout, "timeout"); |
|
32 |
- $soapXML .= "</GetHit>\n"; |
|
33 |
- $soapXML .= "</soap:Body>\n"; |
|
34 |
- $soapXML = nbSOAP_Envelope($soapXML); |
|
35 |
- // Send the request (syncronous http 1.0 only at the moment) |
|
36 |
- $soapOut = nbSOAP_request10($this->Url, "http://localhost:8080/dart/GetHit", $soapXML); |
|
37 |
- // is it an error? |
|
38 |
- $soapStart = strpos($soapOut, "<?xml"); |
|
39 |
- if($soapStart==-1) |
|
40 |
- return false; |
|
41 |
- $xml = nb_easyxmldoc(substr($soapOut,$soapStart)); |
|
42 |
- $body = $xml->findElement("Body", 0, "http://schemas.xmlsoap.org/soap/envelope/"); |
|
43 |
- $cp = $xml->FindChildElement($body); |
|
44 |
- if($cp==false) // empty soap:Body |
|
45 |
- return null; |
|
46 |
- $tn = $xml->getName($cp); |
|
47 |
- if($tn=="Fault") // should really report it... |
|
48 |
- return desoap_nbSOAPFault($xml, $cp); |
|
49 |
- if($tn != "GetHitResponse") |
|
50 |
- return null; |
|
51 |
- $cp = $xml->FindChildElement($cp); |
|
52 |
- if($cp==false) // empty value |
|
53 |
- return null; |
|
54 |
- $result = $this->desoap_GetHitResult($xml, $cp, "GetHit"); |
|
55 |
- return $result; |
|
56 |
- } |
|
57 |
- |
|
58 |
-} |
|
59 |
-?> |
... | ... |
@@ -1,56 +0,0 @@ |
1 |
-<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
-<definitions name="DartService" |
|
3 |
- targetNamespace="http://stefan.blinkenarea.org/flaneth/dartboard/" |
|
4 |
- xmlns="http://schemas.xmlsoap.org/wsdl/" |
|
5 |
- xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" |
|
6 |
- xmlns:tns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap" |
|
7 |
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"> |
|
8 |
- |
|
9 |
- <message name="GetHit"> |
|
10 |
- <part name="timeout" type="xsd:nonNegativeInteger"> |
|
11 |
- <documentation>time in seconds to wait for a hit</documentation> |
|
12 |
- </part> |
|
13 |
- </message> |
|
14 |
- <message name="GetHitResponse"> |
|
15 |
- <part name="factor" type="xsd:positiveInteger"> |
|
16 |
- <documentation>factor of the hit field</documentation> |
|
17 |
- </part> |
|
18 |
- <part name="value" type="xsd:positiveInteger"> |
|
19 |
- <documentation>value of the hit field</documentation> |
|
20 |
- </part> |
|
21 |
- </message> |
|
22 |
- |
|
23 |
- <portType name="GetHitPortType"> |
|
24 |
- <operation name="GetHitOperation"> |
|
25 |
- <input message="tns:GetHit"/> |
|
26 |
- <output message="tns:GetHitResponse"/> |
|
27 |
- </operation> |
|
28 |
- </portType> |
|
29 |
- |
|
30 |
- <binding name="GetHitBinding" type="tns:GetHitPortType"> |
|
31 |
- <soap:binding style="rpc" |
|
32 |
- transport="http://schemas.xmlsoap.org/soap/http"/> |
|
33 |
- <operation name="GetHitOperation"> |
|
34 |
- <soap:operation soapAction="GetHitAction"/> |
|
35 |
- <input> |
|
36 |
- <soap:body |
|
37 |
- encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" |
|
38 |
- use="encoded"/> |
|
39 |
- </input> |
|
40 |
- <output> |
|
41 |
- <soap:body |
|
42 |
- encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" |
|
43 |
- use="encoded"/> |
|
44 |
- </output> |
|
45 |
- </operation> |
|
46 |
- </binding> |
|
47 |
- |
|
48 |
- <service name="GetHitService"> |
|
49 |
- <documentation>WSDL File for GetHitService of flaneth dartboard mod</documentation> |
|
50 |
- <port binding="tns:GetHitBinding" name="GetHitPort"> |
|
51 |
- <soap:address |
|
52 |
- location="http://flaneth-dartboard-mod:80/"/> |
|
53 |
- </port> |
|
54 |
- </service> |
|
55 |
-</definitions> |
|
56 |
- |
... | ... |
@@ -1,12 +0,0 @@ |
1 |
-POST /dart HTTP/1.0 |
|
2 |
-content-length: 304 |
|
3 |
- |
|
4 |
-<soap:Envelope |
|
5 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
6 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
7 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
8 |
- <GetHit> |
|
9 |
- <timeout>5</timeout> |
|
10 |
- </GetHit> |
|
11 |
- </soap:Body> |
|
12 |
-</soap:Envelope> |
... | ... |
@@ -1,9 +0,0 @@ |
1 |
-<soap:Envelope |
|
2 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
3 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
4 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
5 |
- <GetHit> |
|
6 |
- <timeout>5</timeout> |
|
7 |
- </GetHit> |
|
8 |
- </soap:Body> |
|
9 |
-</soap:Envelope> |
... | ... |
@@ -1,17 +0,0 @@ |
1 |
-POST / HTTP/1.0 |
|
2 |
-Host: localhost:8080 |
|
3 |
-User-agent: SOAPpy 0.11.3 (pywebsvcs.sf.net) |
|
4 |
-Content-type: text/xml; charset="UTF-8" |
|
5 |
-Content-length: 485 |
|
6 |
-SOAPAction: "GetHit" |
|
7 |
- |
|
8 |
-<?xml version="1.0" encoding="UTF-8"?> |
|
9 |
-<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> |
|
10 |
-<SOAP-ENV:Body> |
|
11 |
-<GetHit SOAP-ENC:root="1"> |
|
12 |
-<v1> |
|
13 |
-<timeout xsi:type="xsd:int">5</timeout> |
|
14 |
-</v1> |
|
15 |
-</GetHit> |
|
16 |
-</SOAP-ENV:Body> |
|
17 |
-</SOAP-ENV:Envelope> |
... | ... |
@@ -1,10 +0,0 @@ |
1 |
-<soap:Envelope |
|
2 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
3 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
4 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
5 |
- <GetHitResponse> |
|
6 |
- <factor>2</factor> |
|
7 |
- <value>25</value> |
|
8 |
- </GetHitResponse> |
|
9 |
- </soap:Body> |
|
10 |
-</soap:Envelope> |
... | ... |
@@ -1,10 +0,0 @@ |
1 |
-<soap:Envelope |
|
2 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
3 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
4 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
5 |
- <GetHitResponse> |
|
6 |
- <factor>1</factor> |
|
7 |
- <value>1</value> |
|
8 |
- </GetHitResponse> |
|
9 |
- </soap:Body> |
|
10 |
-</soap:Envelope> |
... | ... |
@@ -1,8 +0,0 @@ |
1 |
-<soap:Envelope |
|
2 |
- xmlns:soap="http://www.w3.org/2001/12/soap-envelope/" |
|
3 |
- soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> |
|
4 |
- <soap:Body xmlns="http://stefan.blinkenarea.org/flaneth/dartboard-mod/soap"> |
|
5 |
- <GetHitResponse> |
|
6 |
- </GetHitResponse> |
|
7 |
- </soap:Body> |
|
8 |
-</soap:Envelope> |
... | ... |
@@ -1,17 +0,0 @@ |
1 |
-HTTP/1.0 200 OK |
|
2 |
-Server: <a href="http://pywebsvcs.sf.net">SOAPpy 0.11.3</a> (Python 2.4.4) |
|
3 |
-Date: Sun, 09 Nov 2008 19:23:10 GMT |
|
4 |
-Content-type: text/xml; charset="UTF-8" |
|
5 |
-Content-length: 564 |
|
6 |
- |
|
7 |
-<?xml version="1.0" encoding="UTF-8"?> |
|
8 |
-<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> |
|
9 |
-<SOAP-ENV:Body> |
|
10 |
-<GetHitResponse SOAP-ENC:root="1"> |
|
11 |
-<Result SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array"> |
|
12 |
-<factor>2</factor> |
|
13 |
-<value>25</value> |
|
14 |
-</Result> |
|
15 |
-</GetHitResponse> |
|
16 |
-</SOAP-ENV:Body> |
|
17 |
-</SOAP-ENV:Envelope> |
... | ... |
@@ -1,91 +0,0 @@ |
1 |
-<?php |
|
2 |
-include("nb_easyxml_lite.php"); |
|
3 |
-include("nb_soapfuncs.php"); |
|
4 |
- |
|
5 |
-/********* Data structures used by this web service ********* |
|
6 |
-* |
|
7 |
-* type GetHitResult{ |
|
8 |
-* ['factor']=>{ |
|
9 |
-* } |
|
10 |
-* ['value']=>{ |
|
11 |
-* } |
|
12 |
-* } |
|
13 |
-* |
|
14 |
-*/ |
|
15 |
- |
|
16 |
-class service extends service_nbSOAP |
|
17 |
-{ |
|
18 |
- var $Url; |
|
19 |
- |
|
20 |
-/** |
|
21 |
-* web service provider method GetHit |
|
22 |
-* |
|
23 |
-* @param timeout : unsigned |
|
24 |
-* @return GetHitResult |
|
25 |
-*/ |
|
26 |
- function GetHit($timeout) |
|
27 |
- { |
|
28 |
- return new nbSOAPFault("unimplemented", "The GetHitservice has not been implemented yet", ""); |
|
29 |
- // Fill in web method fuctionality here. |
|
30 |
- // return a GetHitResult |
|
31 |
- } |
|
32 |
- |
|
33 |
-} |
|
34 |
- |
|
35 |
-/********************* Do not alter the generated code below ************************/ |
|
36 |
- |
|
37 |
-if($_SERVER['REQUEST_METHOD']=="GET") |
|
38 |
-{ |
|
39 |
- echo "information call, front page, WSDL or function info. "; |
|
40 |
- echo "All this functionality still has to be written..."; |
|
41 |
-} |
|
42 |
-else |
|
43 |
-{ |
|
44 |
- $in = file_get_contents("php://input"); |
|
45 |
- $action = $_SERVER['HTTP_SOAPACTION']; |
|
46 |
- $action = str_replace("\\\"","",$action); |
|
47 |
- $SoapClass = new service(); |
|
48 |
- $soapXML = $SoapClass->PerformSoapAction($in, $action); |
|
49 |
- $soapXML = nbSOAP_Envelope($soapXML); |
|
50 |
- header("Content-Type: text/xml; charset=utf-8"); |
|
51 |
- echo $soapXML; |
|
52 |
-} |
|
53 |
- |
|
54 |
-class service_nbSOAP //extends nbSOAP |
|
55 |
-{ |
|
56 |
- function PerformSoapAction($in, $action) |
|
57 |
- { |
|
58 |
- $xml = nb_easyxmldoc($in); |
|
59 |
- $body = $xml->findElement("Body", 0, "http://schemas.xmlsoap.org/soap/envelope/"); |
|
60 |
- if($body == false) |
|
61 |
- return "<soap:Fault><faultstring>SOAP body not found</faultstring></soap:Fault>"; |
|
62 |
- $params = $xml->findChildElement($body); |
|
63 |
- switch($action) |
|
64 |
- { |
|
65 |
- case "http://localhost:8080/dart/GetHit": |
|
66 |
- // deserialize parameters |
|
67 |
- $pidx = $xml->findChildElement($params, "timeout"); |
|
68 |
- if($pidx != false) |
|
69 |
- $p_timeout = $this->desoap_unsigned($xml, $pidx, "timeout"); |
|
70 |
- else |
|
71 |
- $p_timeout = null; |
|
72 |
- // call the method |
|
73 |
- $res = $this->GetHit($p_timeout); |
|
74 |
- if(is_a($res,"nbSOAPFault")) |
|
75 |
- { |
|
76 |
- return "<soap:Body>\n" . $res->soapify() . "</soap:Body>"; |
|
77 |
- } |
|
78 |
- // serialize the result |
|
79 |
- $soapXML = $this->soapify_GetHitResult($res, "GetHit"); |
|
80 |
- $soapXML = "<GetHitResponse xmlns=\"http://localhost:8080/dart\">" . $soapXML; |
|
81 |
- $soapXML .= "</GetHitResponse>"; |
|
82 |
- return "<soap:Body>\n" . $soapXML . "</soap:Body>"; |
|
83 |
- break; |
|
84 |
- default: |
|
85 |
- return "<soap:Fault><faultstring>Unrecognised SOAP action called.</faultstring></soap:Fault>"; |
|
86 |
- break; |
|
87 |
- } |
|
88 |
- } |
|
89 |
- |
|
90 |
-} |
|
91 |
-?> |
... | ... |
@@ -1,62 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/io.h> |
|
9 |
- |
|
10 |
-#include "macros.h" |
|
11 |
-#include "status.h" |
|
12 |
- |
|
13 |
-// IO pins of bus |
|
14 |
-#define STATUS_DDR (DDRE) |
|
15 |
-#define STATUS_PORT (PORTE) |
|
16 |
-#define STATUS_BIT (2) |
|
17 |
- |
|
18 |
-// status information |
|
19 |
-char StatusInfoCfPresent = 0; // presence of working compact flash card (boolean) (extern) |
|
20 |
- |
|
21 |
-// number of times to blink status LED |
|
22 |
-#define StatusBlinkCntIdle (1) |
|
23 |
-#define StatusBlinkCntIdleWithCf (2) |
|
24 |
-#define StatusBlinkCntWorking (3) |
|
25 |
-#define StatusBlinkCntMax (3) |
|
26 |
-unsigned char StatusBlinkCnt = StatusBlinkCntIdle; |
|
27 |
- |
|
28 |
-// interval counter for blinking status LED |
|
29 |
-unsigned char StatusBlinkInterval = 0; |
|
30 |
- |
|
31 |
-// initialize |
|
32 |
-void StatusInit( void ) |
|
33 |
-{ |
|
34 |
- //set up IO pin of status LED as output |
|
35 |
- bit_clear( STATUS_PORT, STATUS_BIT ); |
|
36 |
- bit_set( STATUS_DDR, STATUS_BIT ); |
|
37 |
-} |
|
38 |
- |
|
39 |
-// tick procedure - call every 200ms |
|
40 |
-void StatusTick200( void ) |
|
41 |
-{ |
|
42 |
- // turn on status LED only in even intervals and if not yet blinked StatusBlinkCnt times |
|
43 |
- if( (StatusBlinkInterval & 0x01) == 0 && StatusBlinkInterval >> 1 < StatusBlinkCnt ) |
|
44 |
- bit_set( STATUS_PORT, STATUS_BIT ); |
|
45 |
- else |
|
46 |
- bit_clear( STATUS_PORT, STATUS_BIT ); |
|
47 |
- |
|
48 |
- // next interval |
|
49 |
- StatusBlinkInterval++; |
|
50 |
- |
|
51 |
- // blink cycle finished |
|
52 |
- if( StatusBlinkInterval >> 1 > StatusBlinkCntMax ) { |
|
53 |
- StatusBlinkInterval = 0; |
|
54 |
- |
|
55 |
- // set new blink count depending on status information |
|
56 |
- if( StatusInfoCfPresent ) |
|
57 |
- StatusBlinkCnt = StatusBlinkCntIdleWithCf; |
|
58 |
- else |
|
59 |
- StatusBlinkCnt = StatusBlinkCntIdle; |
|
60 |
- } |
|
61 |
-} |
|
62 |
- |
... | ... |
@@ -1,21 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_status |
|
9 |
-#define INC_status |
|
10 |
- |
|
11 |
-// status information |
|
12 |
-extern char StatusInfoCfPresent; // presence of working compact flash card (boolean) |
|
13 |
- |
|
14 |
-// initialize |
|
15 |
-extern void StatusInit( void ); |
|
16 |
- |
|
17 |
-// tick procedure - call every 200ms |
|
18 |
-extern void StatusTick200( void ); |
|
19 |
- |
|
20 |
-#endif // #ifdef INC_status |
|
21 |
- |
... | ... |
@@ -1,1058 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <stdio.h> |
|
9 |
- |
|
10 |
-#include "config.h" |
|
11 |
-#include "checksum.h" |
|
12 |
-#include "debug.h" |
|
13 |
-#include "ethernet.h" |
|
14 |
-#include "http.h" |
|
15 |
-#include "ip.h" |
|
16 |
-#include "macros.h" |
|
17 |
-#include "nethelp.h" |
|
18 |
-#include "random.h" |
|
19 |
-#include "tcp.h" |
|
20 |
- |
|
21 |
-#define TCP_URG 0x20 |
|
22 |
-#define TCP_ACK 0x10 |
|
23 |
-#define TCP_PSH 0x08 |
|
24 |
-#define TCP_RST 0x04 |
|
25 |
-#define TCP_SYN 0x02 |
|
26 |
-#define TCP_FIN 0x01 |
|
27 |
-#define TCP_FLAGS 0x3F |
|
28 |
- |
|
29 |
-#define TcpResendTicks 5 // time after which to resend a packet not ACKed (in 200ms steps, max. 255) |
|
30 |
-#define TcpTimeWaitTicks 20 // time to wait in TIME_WAIT state (in 200ms steps, max. 255) |
|
31 |
-#define TcpTimeoutTicks 250 // maximum idle time of connection before it is reset (in 200ms steps, max. 255) |
|
32 |
-#define TcpMaxLifeTimeTicks 250 // maximum lifetime of connection before it is reset (in 200ms steps, max. 255) |
|
33 |
- |
|
34 |
-// TCP connections |
|
35 |
-struct TcpConnection TcpConns[8]; |
|
36 |
- |
|
37 |
-// initialize |
|
38 |
-void TcpInit( void ) // (extern) |
|
39 |
-{ |
|
40 |
- unsigned char i; |
|
41 |
- |
|
42 |
- // set all connections to closed |
|
43 |
- for( i = 0; i < count( TcpConns ); i++ ) |
|
44 |
- TcpConns[i].State = TCP_CLOSED; |
|
45 |
-} |
|
46 |
- |
|
47 |
-// send a TCP packet |
|
48 |
-// pData must point to a struct TcpPacket with TcpHdr.SrcPort, TcpHdr.DestPort, |
|
49 |
-// TcpHdr.SeqNo, TcpHdr.AckNo, TcpHdr.WndSz and IpHdr.Dest already initialized |
|
50 |
-static void TcpSendPacket( unsigned char * pData, unsigned short Length, unsigned char optLen, unsigned char flags ) |
|
51 |
-{ |
|
52 |
- struct TcpPacket * pTcpPack; |
|
53 |
- unsigned int chk; |
|
54 |
- |
|
55 |
- // packet too short |
|
56 |
- if( Length < sizeof( struct TcpPacket ) + optLen ) |
|
57 |
- return; |
|
58 |
- |
|
59 |
- // convert pointer to UDP packet |
|
60 |
- // (this saves us from always casting pData) |
|
61 |
- pTcpPack = (struct TcpPacket *)pData; |
|
62 |
- |
|
63 |
- debug_tcp_printf( "send src=%u dest=%u flags=%s%s%s%s%s%s len=%u", |
|
64 |
- ntohs( pTcpPack->TcpHdr.SrcPort ), |
|
65 |
- ntohs( pTcpPack->TcpHdr.DestPort ), |
|
66 |
- flags & TCP_URG ? "U" : "", |
|
67 |
- flags & TCP_ACK ? "A" : "", |
|
68 |
- flags & TCP_PSH ? "P" : "", |
|
69 |
- flags & TCP_RST ? "R" : "", |
|
70 |
- flags & TCP_SYN ? "S" : "", |
|
71 |
- flags & TCP_FIN ? "F" : "", |
|
72 |
- Length ); |
|
73 |
- |
|
74 |
- // fill in header values |
|
75 |
- pTcpPack->TcpHdr.Ofs_Flags = htons( (unsigned short)((optLen + 23) & 0x3C) << 10 | (unsigned short)(flags & TCP_FLAGS) ); |
|
76 |
- pTcpPack->TcpHdr.Chk = 0x0000; |
|
77 |
- pTcpPack->TcpHdr.UrgentPtr = 0x0000; |
|
78 |
- ip_cpy( pTcpPack->IpHdr.Src, ConfigIp ); // put IP already here into IP header |
|
79 |
- // because it is needed for calculation of UDP checksum |
|
80 |
- |
|
81 |
- // generate checksum |
|
82 |
- chk = Checksum( (unsigned char *)&pTcpPack->IpHdr.Src, |
|
83 |
- Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8, |
|
84 |
- 0x0006, |
|
85 |
- Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) ); |
|
86 |
- pTcpPack->TcpHdr.Chk = htons( chk ); |
|
87 |
- |
|
88 |
- // send TCP packet |
|
89 |
- pTcpPack->IpHdr.Proto = 0x06; // TCP |
|
90 |
- IpSend( pData, Length ); |
|
91 |
-} |
|
92 |
- |
|
93 |
-// send an empty segment |
|
94 |
-static void TcpEmptySegment( struct TcpConnection * pConn, unsigned long seq, unsigned long ack, unsigned char flags ) |
|
95 |
-{ |
|
96 |
- struct TcpPacket EsPack; |
|
97 |
- |
|
98 |
- // send empty TCP segment |
|
99 |
- EsPack.TcpHdr.SrcPort = htons( pConn->LocalPort ); |
|
100 |
- EsPack.TcpHdr.DestPort = htons( pConn->RemotePort ); |
|
101 |
- EsPack.TcpHdr.SeqNo = htonl( seq ); |
|
102 |
- EsPack.TcpHdr.AckNo = htonl( ack ); |
|
103 |
- EsPack.TcpHdr.WndSz = htons( pConn->RcvWnd ); |
|
104 |
- ip_cpy( EsPack.IpHdr.Dest, pConn->RemoteIp ); |
|
105 |
- TcpSendPacket( (unsigned char *)&EsPack, sizeof( EsPack ), 0, flags ); |
|
106 |
- return; |
|
107 |
-} |
|
108 |
- |
|
109 |
-// send a SYN segment (empty with MSS option set) |
|
110 |
-static void TcpSynSegment( struct TcpConnection * pConn, unsigned long seq, unsigned long ack, unsigned char flags ) |
|
111 |
-{ |
|
112 |
- struct |
|
113 |
- { |
|
114 |
- struct TcpPacket Tcp; |
|
115 |
- struct |
|
116 |
- { |
|
117 |
- unsigned char Kind, Len; |
|
118 |
- unsigned short Mss; |
|
119 |
- } MssOpt; |
|
120 |
- } Pack; |
|
121 |
- |
|
122 |
- // send empty TCP segment with MSS |
|
123 |
- Pack.Tcp.TcpHdr.SrcPort = htons( pConn->LocalPort ); |
|
124 |
- Pack.Tcp.TcpHdr.DestPort = htons( pConn->RemotePort ); |
|
125 |
- Pack.Tcp.TcpHdr.SeqNo = htonl( seq ); |
|
126 |
- Pack.Tcp.TcpHdr.AckNo = htonl( ack ); |
|
127 |
- Pack.Tcp.TcpHdr.WndSz = htons( pConn->RcvWnd ); |
|
128 |
- ip_cpy( Pack.Tcp.IpHdr.Dest, pConn->RemoteIp ); |
|
129 |
- Pack.MssOpt.Kind = 2; |
|
130 |
- Pack.MssOpt.Len = 4; |
|
131 |
- Pack.MssOpt.Mss = htons( 256 ); |
|
132 |
- TcpSendPacket( (unsigned char *)&Pack, sizeof( Pack ), sizeof( Pack.MssOpt ), flags ); |
|
133 |
- return; |
|
134 |
-} |
|
135 |
- |
|
136 |
-// send a data segment |
|
137 |
-static void TcpSendDataSegment( unsigned char connNo, struct TcpConnection * pConn, char needSendAck ) |
|
138 |
-{ |
|
139 |
- unsigned long sendDataLenL; |
|
140 |
- unsigned short sendDataLen, len; |
|
141 |
- struct |
|
142 |
- { |
|
143 |
- struct TcpPacket Tcp; |
|
144 |
- unsigned char Data[256]; // do not use larger segments to save stack memory |
|
145 |
- } Packet; |
|
146 |
- |
|
147 |
- // if outbound connection is not closed yet |
|
148 |
- if( pConn->State == TCP_ESTAB || pConn->State == TCP_CLOSE_WAIT ) |
|
149 |
- { |
|
150 |
- // get maximum number of bytes that might be sent in this segment |
|
151 |
- sendDataLenL = (unsigned long)pConn->SndWnd - (pConn->SndNxt - pConn->SndUna); |
|
152 |
- if( (signed long)sendDataLenL < 0 ) // just to be on the safe side - this should never happen |
|
153 |
- sendDataLen = 0; |
|
154 |
- sendDataLen = (unsigned short)min( sendDataLenL, (unsigned long)pConn->Mss ); |
|
155 |
- sendDataLen = min( sendDataLen, sizeof( Packet.Data ) ); |
|
156 |
- // get data to send from user |
|
157 |
- if( sendDataLen > 0 ) |
|
158 |
- { |
|
159 |
- debug_tcp_printf( "notify send no=%u pos=%lu max_len=%u", |
|
160 |
- connNo, pConn->SndNxt - (pConn->Iss + 1), sendDataLen ); |
|
161 |
- len = pConn->Notify->Send( connNo, pConn->SndNxt - (pConn->Iss + 1), Packet.Data, sendDataLen ); |
|
162 |
- if( len > sendDataLen ) // returned 0xFFFF (or any number too large) to close connection |
|
163 |
- { |
|
164 |
- debug_tcp_printf( "notify send no=%u close", connNo ); |
|
165 |
- TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // send TCP FIN |
|
166 |
- pConn->SndNxt++; |
|
167 |
- pConn->State = TCP_FIN_WAIT_1; // go to state FIN-WAIT-1 |
|
168 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
169 |
- pConn->Notify->Close( connNo ); // signal "connection closed" to user |
|
170 |
- return; |
|
171 |
- } |
|
172 |
- debug_tcp_printf( "notify send no=%u len=%u", connNo, len ); |
|
173 |
- sendDataLen = len; |
|
174 |
- } |
|
175 |
- } |
|
176 |
- // if outbound connection is already closed |
|
177 |
- else |
|
178 |
- // do not send data |
|
179 |
- sendDataLen = 0; |
|
180 |
- |
|
181 |
- // send a segment if data is available or an ACK needs to be sent |
|
182 |
- if( sendDataLen > 0 || needSendAck ) |
|
183 |
- { |
|
184 |
- // send TCP segment |
|
185 |
- Packet.Tcp.TcpHdr.SrcPort = htons( pConn->LocalPort ); |
|
186 |
- Packet.Tcp.TcpHdr.DestPort = htons( pConn->RemotePort ); |
|
187 |
- Packet.Tcp.TcpHdr.SeqNo = htonl( pConn->SndNxt ); |
|
188 |
- Packet.Tcp.TcpHdr.AckNo = htonl( pConn->RcvNxt ); |
|
189 |
- Packet.Tcp.TcpHdr.WndSz = htons( pConn->RcvWnd ); |
|
190 |
- ip_cpy( Packet.Tcp.IpHdr.Dest, pConn->RemoteIp ); |
|
191 |
- TcpSendPacket( (unsigned char *)&Packet, sizeof( struct TcpPacket ) + sendDataLen, 0, |
|
192 |
- sendDataLen > 0 ? TCP_ACK | TCP_PSH : TCP_ACK ); |
|
193 |
- pConn->SndNxt += sendDataLen; |
|
194 |
- } |
|
195 |
-} |
|
196 |
- |
|
197 |
-// tick procedure - call every 200ms |
|
198 |
-void TcpTick200( void ) // (extern) |
|
199 |
-{ |
|
200 |
- unsigned char i, MaxTicks; |
|
201 |
- |
|
202 |
- // for all active connections |
|
203 |
- for( i = 0; i < count( TcpConns ); i++ ) |
|
204 |
- { |
|
205 |
- |
|
206 |
- if( TcpConns[i].State != TCP_CLOSED ) |
|
207 |
- { |
|
208 |
- // increase normal timer |
|
209 |
- TcpConns[i].Ticks++; |
|
210 |
- |
|
211 |
- // get maximum value for normal timer |
|
212 |
- MaxTicks = TcpConns[i].State == TCP_TIME_WAIT ? TcpTimeWaitTicks : TcpResendTicks; |
|
213 |
- // normal timer elapsed |
|
214 |
- if( TcpConns[i].Ticks >= MaxTicks ) |
|
215 |
- { |
|
216 |
- // reset normal timer |
|
217 |
- TcpConns[i].Ticks = 0; |
|
218 |
- |
|
219 |
- // different behaviour in different states |
|
220 |
- switch( TcpConns[i].State ) |
|
221 |
- { |
|
222 |
- |
|
223 |
- case TCP_SYN_RCVD: |
|
224 |
- // resend SYN,ACK segment |
|
225 |
- TcpSynSegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_SYN | TCP_ACK ); |
|
226 |
- TcpConns[i].SndNxt = TcpConns[i].SndUna + 1; |
|
227 |
- break; |
|
228 |
- |
|
229 |
- case TCP_SYN_SENT: |
|
230 |
- // resend SYN segment |
|
231 |
- TcpSynSegment( &TcpConns[i], TcpConns[i].SndUna, 0, TCP_SYN ); |
|
232 |
- TcpConns[i].SndNxt = TcpConns[i].SndUna + 1; |
|
233 |
- break; |
|
234 |
- |
|
235 |
- case TCP_ESTAB: |
|
236 |
- case TCP_CLOSE_WAIT: |
|
237 |
- // if something is not yet ACKed |
|
238 |
- if( (long)(TcpConns[i].SndUna - TcpConns[i].SndNxt) < 0 ) { |
|
239 |
- // resend data segment |
|
240 |
- TcpConns[i].SndNxt = TcpConns[i].SndUna; // some kind of "go back N" |
|
241 |
- // BUG: this is not really "go back N" |
|
242 |
- // according to RFC793, every segment sent and not acknowledged has to be stored |
|
243 |
- // in the resend queue until is is acknowledged |
|
244 |
- // but this is not possible on a microcontroller with 4kB of RAM |
|
245 |
- TcpSendDataSegment( i, &TcpConns[i], 0 ); |
|
246 |
- } |
|
247 |
- break; |
|
248 |
- |
|
249 |
- case TCP_FIN_WAIT_1: |
|
250 |
- case TCP_CLOSING: |
|
251 |
- case TCP_LAST_ACK: |
|
252 |
- // resend FIN segment |
|
253 |
- TcpEmptySegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_FIN | TCP_ACK ); |
|
254 |
- TcpConns[i].SndNxt = TcpConns[i].SndUna + 1; |
|
255 |
- break; |
|
256 |
- |
|
257 |
- case TCP_TIME_WAIT: |
|
258 |
- // close connection, free TCB |
|
259 |
- TcpConns[i].State = TCP_CLOSED; |
|
260 |
- break; |
|
261 |
- |
|
262 |
- } // switch( TcpConns[i].State ) |
|
263 |
- |
|
264 |
- } // if( TcpConns[i].Ticks >= ... |
|
265 |
- |
|
266 |
- } // if( TcpConns[i].State != ... |
|
267 |
- |
|
268 |
- if( TcpConns[i].State != TCP_CLOSED ) |
|
269 |
- { |
|
270 |
- // increase timeout timer |
|
271 |
- TcpConns[i].Timeout++; |
|
272 |
- |
|
273 |
- // timeout timer elapsed |
|
274 |
- if( TcpConns[i].Timeout >= TcpTimeoutTicks ) |
|
275 |
- { |
|
276 |
- // send a RST segment |
|
277 |
- TcpEmptySegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_RST ); |
|
278 |
- // depending on state ... |
|
279 |
- switch( TcpConns[i].State ) |
|
280 |
- { |
|
281 |
- case TCP_SYN_RCVD: |
|
282 |
- case TCP_ESTAB: |
|
283 |
- case TCP_CLOSE_WAIT: |
|
284 |
- TcpConns[i].State = TCP_CLOSED; // close connection |
|
285 |
- debug_tcp_printf( "notify close no=%u", i ); |
|
286 |
- TcpConns[i].Notify->Close( i ); // tell user that connection was closed |
|
287 |
- break; |
|
288 |
- default: |
|
289 |
- TcpConns[i].State = TCP_CLOSED; // close connection |
|
290 |
- } |
|
291 |
- |
|
292 |
- } // if( TcpConns[i].Timeout >= ... |
|
293 |
- |
|
294 |
- } // if( TcpConns[i].State != ... |
|
295 |
- |
|
296 |
- if( TcpConns[i].State != TCP_CLOSED ) |
|
297 |
- { |
|
298 |
- // increase lifetime timer |
|
299 |
- TcpConns[i].LifeTime++; |
|
300 |
- |
|
301 |
- // lifetime timer elapsed |
|
302 |
- // - connections may not last forever - even not with traffic on them |
|
303 |
- if( TcpConns[i].LifeTime >= TcpMaxLifeTimeTicks ) |
|
304 |
- { |
|
305 |
- // send a RST segment |
|
306 |
- TcpEmptySegment( &TcpConns[i], TcpConns[i].SndUna, TcpConns[i].RcvNxt, TCP_RST ); |
|
307 |
- // depending on state ... |
|
308 |
- switch( TcpConns[i].State ) |
|
309 |
- { |
|
310 |
- case TCP_SYN_RCVD: |
|
311 |
- case TCP_ESTAB: |
|
312 |
- case TCP_CLOSE_WAIT: |
|
313 |
- TcpConns[i].State = TCP_CLOSED; // close connection |
|
314 |
- debug_tcp_printf( "notify close no=%u", i ); |
|
315 |
- TcpConns[i].Notify->Close( i ); // tell user that connection was closed |
|
316 |
- break; |
|
317 |
- default: |
|
318 |
- TcpConns[i].State = TCP_CLOSED; // close connection |
|
319 |
- } |
|
320 |
- } // if( TcpConns[i].LifeTime >= ... |
|
321 |
- |
|
322 |
- } // if( TcpConns[i].State != ... |
|
323 |
- |
|
324 |
- } // for( i ... |
|
325 |
-} |
|
326 |
- |
|
327 |
-// process a received TCP packet |
|
328 |
-void TcpRecv( unsigned char * pData, unsigned short Length ) // (extern) |
|
329 |
-{ |
|
330 |
- struct TcpPacket * pTcpPack; |
|
331 |
- unsigned long seq, ack, seqEnd; |
|
332 |
- unsigned short localPort, remotePort, wnd, mss, ofs, len, tmp, rcvWnd; |
|
333 |
- unsigned char i, flags, * optPtr, optLen, connNo; |
|
334 |
- struct TcpConnection * pConn; |
|
335 |
- char accept, sendAck; |
|
336 |
- struct TcpNotify * pNotify; |
|
337 |
- |
|
338 |
- // packet too short |
|
339 |
- if( Length < sizeof( struct TcpPacket ) ) |
|
340 |
- return; |
|
341 |
- |
|
342 |
- // convert pointer to TCP packet |
|
343 |
- // (this saves us from always casting pData) |
|
344 |
- pTcpPack = (struct TcpPacket *)pData; |
|
345 |
- |
|
346 |
- // test checksum |
|
347 |
- if( Checksum( (unsigned char*)&pTcpPack->IpHdr.Src, |
|
348 |
- Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8, |
|
349 |
- 0x0006, |
|
350 |
- Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) ) != 0 ) |
|
351 |
- return; |
|
352 |
- |
|
353 |
- // get local and remote port |
|
354 |
- localPort = ntohs( pTcpPack->TcpHdr.DestPort ); |
|
355 |
- remotePort = ntohs( pTcpPack->TcpHdr.SrcPort ); |
|
356 |
- |
|
357 |
- // ignore packets sent from or to port 0 |
|
358 |
- // - this might be some attack |
|
359 |
- if( localPort == 0 || remotePort == 0 ) |
|
360 |
- return; |
|
361 |
- |
|
362 |
- // get sequence number, acknowledge number and window size |
|
363 |
- seq = ntohl( pTcpPack->TcpHdr.SeqNo ); |
|
364 |
- ack = ntohl( pTcpPack->TcpHdr.AckNo ); |
|
365 |
- wnd = ntohs( pTcpPack->TcpHdr.WndSz ); |
|
366 |
- // maximum segment size: liberal default according to RFC879 |
|
367 |
- mss = 536; |
|
368 |
- |
|
369 |
- // get flags |
|
370 |
- flags = ntohs( pTcpPack->TcpHdr.Ofs_Flags ) & 0x003F; |
|
371 |
- |
|
372 |
- // get data offset and segment length in bytes |
|
373 |
- ofs = (ntohs( pTcpPack->TcpHdr.Ofs_Flags ) & 0xF000) >> 10; |
|
374 |
- if( ofs < 20 || ofs > Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) ) // invalid offset |
|
375 |
- return; // remote side is unable to build valid TCP packets - ignore |
|
376 |
- |
|
377 |
- // get segment length (length of data in segment) |
|
378 |
- len = Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) - ofs; |
|
379 |
- |
|
380 |
- debug_tcp_printf( "recv src=%u dest=%u flags=%s%s%s%s%s%s len=%u", |
|
381 |
- ntohs( pTcpPack->TcpHdr.SrcPort ), |
|
382 |
- ntohs( pTcpPack->TcpHdr.DestPort ), |
|
383 |
- flags & TCP_URG ? "U" : "", |
|
384 |
- flags & TCP_ACK ? "A" : "", |
|
385 |
- flags & TCP_PSH ? "P" : "", |
|
386 |
- flags & TCP_RST ? "R" : "", |
|
387 |
- flags & TCP_SYN ? "S" : "", |
|
388 |
- flags & TCP_FIN ? "F" : "", |
|
389 |
- Length ); |
|
390 |
- |
|
391 |
- // process options |
|
392 |
- optLen = (unsigned char)(ofs - 20); |
|
393 |
- optPtr = (unsigned char *)&pTcpPack->TcpHdr + sizeof( struct TcpHeader ); |
|
394 |
- while( optLen > 0 ) |
|
395 |
- { |
|
396 |
- switch( *optPtr ) |
|
397 |
- { |
|
398 |
- // end of options |
|
399 |
- case 0: |
|
400 |
- optLen = 0; |
|
401 |
- break; |
|
402 |
- // no operation |
|
403 |
- case 1: |
|
404 |
- optLen--; |
|
405 |
- optPtr++; |
|
406 |
- break; |
|
407 |
- // maximum segment size |
|
408 |
- case 2: |
|
409 |
- if( optLen < 4 || optPtr[1] != 4 ) |
|
410 |
- { |
|
411 |
- optPtr = NULL; // error |
|
412 |
- optLen = 0; |
|
413 |
- break; |
|
414 |
- } |
|
415 |
- mss = ntohs( *(unsigned short *)(optPtr+2) ); |
|
416 |
- optLen -= 4; |
|
417 |
- optPtr += 4; |
|
418 |
- break; |
|
419 |
- // unknown option |
|
420 |
- default: |
|
421 |
- if( optLen < 2 || optPtr[1] > optLen ) |
|
422 |
- { |
|
423 |
- optPtr = NULL; // error |
|
424 |
- optLen = 0; |
|
425 |
- } |
|
426 |
- optLen -= optPtr[1]; // ignore this option |
|
427 |
- optPtr += optPtr[1]; |
|
428 |
- } // switch( *optPtr ) |
|
429 |
- } // while( optLen > 0 ) |
|
430 |
- if( optPtr == NULL ) // some error during option parsing |
|
431 |
- return; // remote side is unable to build valid TCP packets - ignore |
|
432 |
- |
|
433 |
- // get sequence number at end of this segment |
|
434 |
- seqEnd = seq + len; |
|
435 |
- if( flags & TCP_SYN ) // TCP SYN counts as 1 in sequence number space |
|
436 |
- seqEnd++; |
|
437 |
- if( flags & TCP_FIN ) // TCP FIN counts as 1 in sequence number space |
|
438 |
- seqEnd++; |
|
439 |
- |
|
440 |
- // search connection |
|
441 |
- for( i = 0; i < count( TcpConns ); i++ ) |
|
442 |
- if( TcpConns[i].State != TCP_CLOSED && |
|
443 |
- ip_eq( TcpConns[i].RemoteIp, pTcpPack->IpHdr.Src ) && |
|
444 |
- TcpConns[i].LocalPort == localPort && |
|
445 |
- TcpConns[i].RemotePort == remotePort ) |
|
446 |
- break; |
|
447 |
- |
|
448 |
- // connection not found, only SYN flag set, no data |
|
449 |
- if( i >= count( TcpConns ) && flags == TCP_SYN && len == 0 ) |
|
450 |
- { |
|
451 |
- // accept connections on some ports (note: localPort cannot be 0 because of check above) |
|
452 |
- rcvWnd = 0; |
|
453 |
- pNotify = NULL; |
|
454 |
- // HTTP |
|
455 |
- if( localPort == ConfigHttpPort ) |
|
456 |
- { |
|
457 |
- rcvWnd = 256; // connection shall be accepted |
|
458 |
- pNotify = &HttpNotify; |
|
459 |
- } |
|
460 |
- // connection shall be accepted |
|
461 |
- if( pNotify != NULL ) |
|
462 |
- { |
|
463 |
- // search empty connection slot |
|
464 |
- for( i = 0; i < count( TcpConns ); i++ ) |
|
465 |
- if( TcpConns[i].State == TCP_CLOSED ) |
|
466 |
- break; |
|
467 |
- // free connection slot found |
|
468 |
- if( i < count( TcpConns ) ) |
|
469 |
- { |
|
470 |
- // create new connection (passive) in this slot |
|
471 |
- ip_cpy( TcpConns[i].RemoteIp, pTcpPack->IpHdr.Src ); |
|
472 |
- TcpConns[i].LocalPort = localPort; |
|
473 |
- TcpConns[i].RemotePort = remotePort; |
|
474 |
- TcpConns[i].State = TCP_LISTEN; |
|
475 |
- TcpConns[i].Ticks = 0; |
|
476 |
- TcpConns[i].Timeout = 0; |
|
477 |
- TcpConns[i].LifeTime = 0; |
|
478 |
- TcpConns[i].RcvWnd = rcvWnd; |
|
479 |
- TcpConns[i].Notify = pNotify; |
|
480 |
- } |
|
481 |
- } |
|
482 |
- } |
|
483 |
- |
|
484 |
- // connection still not found |
|
485 |
- if( i >= count( TcpConns ) ) |
|
486 |
- { |
|
487 |
- struct TcpPacket EsPack; |
|
488 |
- unsigned char EsFlags; |
|
489 |
- |
|
490 |
- // do nothing if RST flag is set |
|
491 |
- if( flags & TCP_RST ) |
|
492 |
- return; |
|
493 |
- |
|
494 |
- // send TCP RST |
|
495 |
- EsPack.TcpHdr.SrcPort = htons( localPort ); |
|
496 |
- EsPack.TcpHdr.DestPort = htons( remotePort ); |
|
497 |
- EsPack.TcpHdr.WndSz = htons( 0 ); |
|
498 |
- ip_cpy( EsPack.IpHdr.Dest, pTcpPack->IpHdr.Src ); |
|
499 |
- if( flags & TCP_ACK ) |
|
500 |
- { |
|
501 |
- EsPack.TcpHdr.SeqNo = htonl( ack ); |
|
502 |
- EsPack.TcpHdr.AckNo = htonl( 0 ); |
|
503 |
- EsFlags = TCP_RST; |
|
504 |
- } |
|
505 |
- else |
|
506 |
- { |
|
507 |
- EsPack.TcpHdr.SeqNo = htonl( 0 ); |
|
508 |
- EsPack.TcpHdr.AckNo = htonl( seqEnd ); |
|
509 |
- EsFlags = TCP_RST | TCP_ACK; |
|
510 |
- } |
|
511 |
- TcpSendPacket( (unsigned char *)&EsPack, sizeof( EsPack ), 0, EsFlags ); |
|
512 |
- return; |
|
513 |
- } |
|
514 |
- |
|
515 |
- // a connection was found - save number and pointer to it |
|
516 |
- connNo = i; |
|
517 |
- pConn = &TcpConns[i]; |
|
518 |
- |
|
519 |
- // reset connection on reception of urgent data (URG flag set) |
|
520 |
- // BUG: urgent data must be supported according to RFC793 |
|
521 |
- // but urgent data is not used in protocols we use, so leave this out here to save time and memory |
|
522 |
- if( flags & TCP_URG ) |
|
523 |
- { |
|
524 |
- // send TCP RST |
|
525 |
- if( flags & TCP_ACK ) |
|
526 |
- TcpEmptySegment( pConn, ack, 0, TCP_RST ); |
|
527 |
- else |
|
528 |
- TcpEmptySegment( pConn, 0, seqEnd, TCP_RST | TCP_ACK ); |
|
529 |
- return; |
|
530 |
- } |
|
531 |
- |
|
532 |
- // different behaviour in different states according to RFC793 |
|
533 |
- switch( pConn->State ) |
|
534 |
- { |
|
535 |
- |
|
536 |
- case TCP_LISTEN: |
|
537 |
- if( flags & TCP_RST ) // An incoming RST should be ignored. |
|
538 |
- return; |
|
539 |
- if( flags & TCP_ACK ) // Any acknowledgment is bad if it arrives on a connection still in the LISTEN state. |
|
540 |
- { |
|
541 |
- TcpEmptySegment( pConn, ack, 0, TCP_RST ); // An acceptable reset segment should be formed for any arriving ACK-bearing segment. |
|
542 |
- pConn->Ticks = 0; // restart timer |
|
543 |
- return; |
|
544 |
- } |
|
545 |
- if( flags & TCP_SYN ) // third check for a SYN |
|
546 |
- { |
|
547 |
- pConn->RcvNxt = seq + 1; // Set RCV.NXT to SEG.SEQ+1, |
|
548 |
- pConn->Irs = seq; // IRS is set to SEG.SEQ |
|
549 |
- RandomGetData( (unsigned char *)&pConn->Iss, sizeof( pConn->Iss ) ); // ISS should be selected (randomly!!!) |
|
550 |
- TcpSynSegment( pConn, pConn->Iss, pConn->RcvNxt, TCP_SYN | TCP_ACK ); // and a SYN segment sent |
|
551 |
- pConn->SndNxt = pConn->Iss + 1; // SND.NXT is set to ISS+1 |
|
552 |
- pConn->SndUna = pConn->Iss; // and SND.UNA to ISS |
|
553 |
- pConn->State = TCP_SYN_RCVD; // The connection state should be changed to SYN-RECEIVED. |
|
554 |
- pConn->SndWnd = wnd; // initialize send window from packet |
|
555 |
- pConn->SndWl1 = seq; |
|
556 |
- pConn->SndWl2 = ack; |
|
557 |
- pConn->Mss = mss; // save maximum segment size |
|
558 |
- pConn->Ticks = 0; // restart timer |
|
559 |
- return; |
|
560 |
- } |
|
561 |
- // fourth other text or control |
|
562 |
- // So you are unlikely to get here, but if you do, drop the segment, and return. |
|
563 |
- return; |
|
564 |
- |
|
565 |
- case TCP_SYN_SENT: |
|
566 |
- accept = 0; |
|
567 |
- if( flags & TCP_ACK ) // If the ACK bit is set |
|
568 |
- { |
|
569 |
- if( (long)(ack - pConn->Iss) <= 0 || (long)(ack - pConn->SndNxt) > 0 ) // If SEG.ACK =< ISS, or SEG.ACK > SND.NXT, |
|
570 |
- { |
|
571 |
- if( ! (flags & TCP_RST) ) // (unless the RST bit is set) |
|
572 |
- TcpEmptySegment( pConn, ack, 0, TCP_RST ); // send a reset |
|
573 |
- return; // and discard the segment. Return. |
|
574 |
- } |
|
575 |
- accept = (long)(pConn->SndUna - ack) <= 0 && (long)(ack - pConn->SndNxt) <= 0; // If SND.UNA =< SEG.ACK =< SND.NXT then the ACK is acceptable. |
|
576 |
- } |
|
577 |
- if( flags & TCP_RST ) // If the RST bit is set |
|
578 |
- { |
|
579 |
- if( accept ) // If the ACK was acceptable |
|
580 |
- pConn->State = TCP_CLOSED; // enter CLOSED state, delete TCB, |
|
581 |
- return; // drop the segment and return. |
|
582 |
- } |
|
583 |
- if( (accept || ! (flags & TCP_ACK)) && // This step should be reached only if the ACK is ok, or there is no ACK, |
|
584 |
- flags & TCP_SYN ) // If the SYN bit is on |
|
585 |
- { |
|
586 |
- pConn->RcvNxt = seq + 1; // RCV.NXT is set to SEG.SEQ+1, |
|
587 |
- pConn->Irs = seq; // IRS is set to SEG.SEQ. |
|
588 |
- pConn->SndWl2 = pConn->RcvNxt; // last acknowledge number when updating the window size is first acknowledge number at all |
|
589 |
- if( accept ) // (if there is an ACK) |
|
590 |
- pConn->SndUna = ack; // SND.UNA should be advanced to equal SEG.ACK |
|
591 |
- pConn->SndWnd = wnd; // initialize send window from packet |
|
592 |
- pConn->SndWl1 = seq; |
|
593 |
- pConn->SndWl2 = ack; |
|
594 |
- pConn->Mss = mss; // save maximum segment size |
|
595 |
- if( (long)(pConn->SndUna - pConn->Iss) > 0 ) // If SND.UNA > ISS (our SYN has been ACKed), |
|
596 |
- { |
|
597 |
- pConn->State = TCP_ESTAB; // change the connection state to ESTABLISHED, |
|
598 |
- debug_tcp_printf( "notify connect no=%u", connNo ); |
|
599 |
- pConn->Notify->Connect( connNo ); // signal "connected" |
|
600 |
- TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK ); // form an ACK segment and send it. |
|
601 |
- } |
|
602 |
- else // Otherwise |
|
603 |
- { |
|
604 |
- pConn->State = TCP_SYN_RCVD; // enter SYN-RECEIVED, |
|
605 |
- TcpSynSegment( pConn, pConn->Iss, pConn->RcvNxt, TCP_SYN | TCP_ACK ); // form a SYN,ACK segment and send it. |
|
606 |
- } |
|
607 |
- pConn->Ticks = 0; // restart timer |
|
608 |
- } |
|
609 |
- return; |
|
610 |
- |
|
611 |
- } // switch( pConn->State ) |
|
612 |
- |
|
613 |
- // Otherwise, |
|
614 |
- |
|
615 |
- // first check sequence number |
|
616 |
- if( len == 0 ) |
|
617 |
- if( pConn->RcvWnd == 0 ) |
|
618 |
- accept = seq == pConn->RcvNxt; // SEG.SEQ = RCV.NXT |
|
619 |
- else |
|
620 |
- accept = (long)(pConn->RcvNxt - seq) <= 0 && // RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND |
|
621 |
- (long)(seq - (pConn->RcvNxt + pConn->RcvWnd)) < 0; |
|
622 |
- else |
|
623 |
- if( pConn->RcvWnd == 0 ) |
|
624 |
- accept = 0; // not acceptable |
|
625 |
- else |
|
626 |
- accept = ((long)(pConn->RcvNxt - seq) <= 0 && // RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND |
|
627 |
- (long)(seq - (pConn->RcvNxt + pConn->RcvWnd)) < 0) || |
|
628 |
- ((long)(pConn->RcvNxt - (seq + len - 1) <= 0) && // or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND |
|
629 |
- (long)((seq + len - 1) - (pConn->RcvNxt + pConn->RcvWnd)) < 0); |
|
630 |
- |
|
631 |
- // because there is not enough memory to store segments needed later, |
|
632 |
- // we only accept segments with SEG.SEQ <= RCV.NXT |
|
633 |
- // thus, we reject the segment if SEG.SEQ > RCV.NXT |
|
634 |
- // BAD PERFORMANCE: this is _not_ a bug, but a major impact on performace when packets arrive out of order |
|
635 |
- // - however, we cannot do something against it, |
|
636 |
- // because there is not enough memory available on the controller |
|
637 |
- // to store segements for later processing |
|
638 |
- if( accept && (long)(seq - pConn->RcvNxt) > 0 ) |
|
639 |
- accept = 0; |
|
640 |
- |
|
641 |
- // If an incoming segment is not acceptable |
|
642 |
- if( ! accept ) |
|
643 |
- { |
|
644 |
- /* disabled this - sometimes it ssems to generates endless ACKs being exchanged with remote host) |
|
645 |
- if( ! (flags & TCP_RST) ) // (unless the RST bit is set) |
|
646 |
- TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK ); // an acknowledgment should be sent in reply */ |
|
647 |
- return; // drop the unacceptable segment and return. |
|
648 |
- } |
|
649 |
- |
|
650 |
- // if segment contains duplicate data |
|
651 |
- tmp = pConn->RcvNxt - seq; // cannot be negative because of checks above |
|
652 |
- if( tmp > 0 ) |
|
653 |
- { |
|
654 |
- // remove duplicate SYN flag from segment |
|
655 |
- if( flags & TCP_SYN ) |
|
656 |
- { |
|
657 |
- flags &= ~TCP_SYN; |
|
658 |
- tmp--; |
|
659 |
- } |
|
660 |
- // remove duplicate data from segment |
|
661 |
- ofs += tmp; |
|
662 |
- len -= tmp; // length cannot become negative here because of checks above |
|
663 |
- // now this segments starts with the expected sequence number |
|
664 |
- seq = pConn->RcvNxt; |
|
665 |
- } |
|
666 |
- |
|
667 |
- // if segment extends beyond end of receive window |
|
668 |
- if( len > pConn->RcvWnd ) |
|
669 |
- { |
|
670 |
- // remove data behind receive window |
|
671 |
- seqEnd -= len - pConn->RcvWnd; |
|
672 |
- len = pConn->RcvWnd; |
|
673 |
- } |
|
674 |
- |
|
675 |
- // restart timer, because this was an acceptable segment |
|
676 |
- pConn->Ticks = 0; |
|
677 |
- |
|
678 |
- // second check the RST bit, |
|
679 |
- if( flags & TCP_RST ) |
|
680 |
- { |
|
681 |
- switch( pConn->State ) |
|
682 |
- { |
|
683 |
- |
|
684 |
- case TCP_SYN_RCVD: |
|
685 |
- pConn->State = TCP_CLOSED; // enter the CLOSED state and delete the TCB, an return. |
|
686 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
687 |
- pConn->Notify->Close( connNo ); // signal "connection refused" |
|
688 |
- return; |
|
689 |
- |
|
690 |
- case TCP_ESTAB: |
|
691 |
- case TCP_FIN_WAIT_1: |
|
692 |
- case TCP_FIN_WAIT_2: |
|
693 |
- case TCP_CLOSE_WAIT: |
|
694 |
- pConn->State = TCP_CLOSED; // Enter the CLOSED state, delete the TCB, and return. |
|
695 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
696 |
- pConn->Notify->Close( connNo ); // signal "connection reset" |
|
697 |
- return; |
|
698 |
- |
|
699 |
- case TCP_CLOSING: |
|
700 |
- case TCP_LAST_ACK: |
|
701 |
- case TCP_TIME_WAIT: |
|
702 |
- pConn->State = TCP_CLOSED; // enter the CLOSED state, delete the TCB, and return. |
|
703 |
- return; |
|
704 |
- |
|
705 |
- } // switch( pConn->State ) |
|
706 |
- } // if( flags & TCP_RST ) |
|
707 |
- |
|
708 |
- // third check security and precedence |
|
709 |
- // - this does not apply to our implementation because we do not support security and precedence on TCP layer |
|
710 |
- |
|
711 |
- // fourth, check the SYN bit |
|
712 |
- if( flags & TCP_SYN ) |
|
713 |
- { |
|
714 |
- switch( pConn->State ) |
|
715 |
- { |
|
716 |
- |
|
717 |
- case TCP_SYN_RCVD: |
|
718 |
- case TCP_ESTAB: |
|
719 |
- case TCP_FIN_WAIT_1: |
|
720 |
- case TCP_FIN_WAIT_2: |
|
721 |
- case TCP_CLOSE_WAIT: |
|
722 |
- // If the SYN is in the window it is an error, |
|
723 |
- // - this is always the case here, because SYN not in window would habe been removed above |
|
724 |
- TcpEmptySegment( pConn, ack, 0, TCP_RST ); // send a reset, |
|
725 |
- pConn->State = TCP_CLOSED; // enter the CLOSED state, delete the TCB, and return. |
|
726 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
727 |
- pConn->Notify->Close( connNo ); // signal "connection reset" |
|
728 |
- return; |
|
729 |
- |
|
730 |
- case TCP_CLOSING: |
|
731 |
- case TCP_LAST_ACK: |
|
732 |
- case TCP_TIME_WAIT: |
|
733 |
- // If the SYN is in the window it is an error, |
|
734 |
- // - this is always the case here, because SYN not in window would habe been removed above |
|
735 |
- TcpEmptySegment( pConn, ack, 0, TCP_RST ); // send a reset, |
|
736 |
- pConn->State = TCP_CLOSED; // enter the CLOSED state, delete the TCB, and return. |
|
737 |
- return; |
|
738 |
- |
|
739 |
- } // switch( pConn->State ) |
|
740 |
- } // if( flags & TCP_SYN ) |
|
741 |
- |
|
742 |
- // fifth check the ACK field, |
|
743 |
- if( ! (flags & TCP_ACK) ) // if the ACK bit is off |
|
744 |
- return; // drop the segment and return |
|
745 |
- switch( pConn->State ) |
|
746 |
- { |
|
747 |
- |
|
748 |
- case TCP_SYN_RCVD: |
|
749 |
- if( (long)(pConn->SndUna - ack) <= 0 && // If SND.UNA =< SEG.ACK =< SND.NXT |
|
750 |
- (long)(ack - pConn->SndNxt) <= 0 ) |
|
751 |
- { |
|
752 |
- pConn->State = TCP_ESTAB; // then enter ESTABLISHED state |
|
753 |
- debug_tcp_printf( "notify connect no=%u", connNo ); |
|
754 |
- pConn->Notify->Connect( connNo ); // signal "connected" |
|
755 |
- // and continue processing. |
|
756 |
- } |
|
757 |
- else // If the segment acknowledgment is not acceptable, |
|
758 |
- { |
|
759 |
- TcpEmptySegment( pConn, ack, 0, TCP_RST ); // form a reset segment, and send it. |
|
760 |
- return; // drop this segment |
|
761 |
- } |
|
762 |
- // no break here |
|
763 |
- |
|
764 |
- case TCP_ESTAB: |
|
765 |
- case TCP_FIN_WAIT_1: |
|
766 |
- case TCP_FIN_WAIT_2: |
|
767 |
- case TCP_CLOSE_WAIT: |
|
768 |
- case TCP_CLOSING: |
|
769 |
- if( (long)(ack - pConn->SndUna) <= 0 ) // If the ACK is a duplicate (SEG.ACK <= SND.UNA), |
|
770 |
- break; // it can be ignored. |
|
771 |
- if( (long)(ack - pConn->SndNxt) > 0 ) // If the ACK acks something not yet sent (SEG.ACK > SND.NXT) |
|
772 |
- { |
|
773 |
- TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_ACK ); // then send an ACK, |
|
774 |
- return; // drop the segment, and return. |
|
775 |
- } |
|
776 |
- // here: SND.UNA < SEG.ACK =< SND.NXT |
|
777 |
- pConn->SndUna = ack; // set SND.UNA <- SEG.ACK. |
|
778 |
- if( (long)(pConn->SndWl1 - seq) < 0 || // If SND.WL1 < SEG.SEQ |
|
779 |
- (pConn->SndWl1 == seq && (long)(pConn->SndWl2 - ack) <= 0) ) // or (SND.WL1 = SEG.SEQ and SND.WL2 =< SEG.ACK), |
|
780 |
- { |
|
781 |
- pConn->SndWnd = wnd; // set SND.WND <- SEG.WND, |
|
782 |
- pConn->SndWl1 = seq; // set SND.WL1 <- SEG.SEQ, |
|
783 |
- pConn->SndWl2 = ack; // and set SND.WL2 <- SEG.ACK. |
|
784 |
- } |
|
785 |
- pConn->Timeout = 0; // restart timeout timer |
|
786 |
- debug_tcp_printf( "notify sent no=%u pos=%lu", |
|
787 |
- connNo, pConn->SndNxt - (pConn->Iss + 1) ); |
|
788 |
- pConn->Notify->Sent( connNo, pConn->SndUna - (pConn->Iss + 1) ); // signal "send completed" (up to ack) |
|
789 |
- // additional processing |
|
790 |
- switch( pConn->State ) |
|
791 |
- { |
|
792 |
- case TCP_FIN_WAIT_1: |
|
793 |
- if( pConn->SndUna == pConn->SndNxt ) // if our FIN is now acknowledged |
|
794 |
- pConn->State = TCP_FIN_WAIT_2; // then enter FIN-WAIT-2 and continue processing in that state. |
|
795 |
- // no break here |
|
796 |
- case TCP_FIN_WAIT_2: |
|
797 |
- if( pConn->SndUna == pConn->SndNxt ) // if the retransmission queue is empty, |
|
798 |
- { |
|
799 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
800 |
- pConn->Notify->Close( connNo ); // the user's CLOSE can be acknowledged |
|
801 |
- } |
|
802 |
- break; |
|
803 |
- case TCP_CLOSING: |
|
804 |
- if( pConn->SndUna == pConn->SndNxt ) // if the ACK acknowledges our FIN |
|
805 |
- pConn->State = TCP_TIME_WAIT; // then enter the TIME-WAIT state, |
|
806 |
- else |
|
807 |
- return; // otherwise ignore the segment. |
|
808 |
- break; |
|
809 |
- } |
|
810 |
- break; |
|
811 |
- |
|
812 |
- case TCP_LAST_ACK: |
|
813 |
- // The only thing that can arrive in this state is an acknowledgment of our FIN. |
|
814 |
- if( pConn->SndUna == pConn->SndNxt ) // If our FIN is now acknowledged, |
|
815 |
- { |
|
816 |
- pConn->State = TCP_CLOSED; // delete the TCB, enter the CLOSED state, |
|
817 |
- return; // and return. |
|
818 |
- } |
|
819 |
- break; |
|
820 |
- |
|
821 |
- case TCP_TIME_WAIT: |
|
822 |
- // The only thing that can arrive in this state is a retransmission of the remote FIN. |
|
823 |
- TcpEmptySegment( pConn, ack, seqEnd, TCP_ACK ); // Acknowledge it, |
|
824 |
- break; |
|
825 |
- |
|
826 |
- } // switch( pConn->State ) |
|
827 |
- |
|
828 |
- // sixth, check the URG bit, |
|
829 |
- // - this cannot occur, because we have alredy reset the connection if URG was set |
|
830 |
- |
|
831 |
- // no ACK needs to be sent yet |
|
832 |
- sendAck = 0; |
|
833 |
- |
|
834 |
- // seventh, process the segment text, |
|
835 |
- if( len > 0 ) |
|
836 |
- { |
|
837 |
- switch( pConn->State ) |
|
838 |
- { |
|
839 |
- |
|
840 |
- case TCP_ESTAB: |
|
841 |
- case TCP_FIN_WAIT_1: |
|
842 |
- case TCP_FIN_WAIT_2: |
|
843 |
- pConn->RcvWnd -= len; // make receive window smaller (len <= pConn->RcvWnd) |
|
844 |
- pConn->RcvNxt += len; // advance sequence number of next data to receive |
|
845 |
- pConn->Timeout = 0; // restart timeout timer |
|
846 |
- debug_tcp_printf( "notify recv no=%u pos=%lu len=%u, min_wnd=%u", |
|
847 |
- connNo, pConn->RcvNxt - (pConn->Irs + 1) - len, len, pConn->RcvWnd ); |
|
848 |
- pConn->RcvWnd = pConn->Notify->Received( connNo, pConn->RcvNxt - (pConn->Irs + 1) - len, // give received data to user |
|
849 |
- (unsigned char *)&pTcpPack->TcpHdr + ofs, len, // (update receive window size) |
|
850 |
- pConn->RcvWnd ); |
|
851 |
- debug_tcp_printf( "notify recv no=%u wnd=%u", connNo, pConn->RcvWnd ); |
|
852 |
- sendAck = 1; // remember to send an ACK |
|
853 |
- break; |
|
854 |
- |
|
855 |
- } // switch( pConn->State ) |
|
856 |
- } // if( len > 0 ) |
|
857 |
- |
|
858 |
- // eighth, check the FIN bit, |
|
859 |
- if( flags & TCP_FIN ) |
|
860 |
- { |
|
861 |
- switch( pConn->State ) |
|
862 |
- { |
|
863 |
- |
|
864 |
- case TCP_SYN_RCVD: |
|
865 |
- case TCP_ESTAB: |
|
866 |
- sendAck = 1; // remember to send an ACK |
|
867 |
- pConn->RcvNxt++; // FIN counts as one in sequence number space |
|
868 |
- pConn->State = TCP_CLOSE_WAIT; // Enter the CLOSE-WAIT state. |
|
869 |
- // close outbound part of the connection |
|
870 |
- // i.e. do an automatic call to close |
|
871 |
- TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // send a FIN |
|
872 |
- pConn->SndNxt++; |
|
873 |
- pConn->State = TCP_CLOSING; |
|
874 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
875 |
- pConn->Notify->Close( connNo ); // signal "connection closed" to user |
|
876 |
- return; // we do not need to send an ack, becaue we already sent it with our FIN |
|
877 |
- |
|
878 |
- case TCP_FIN_WAIT_1: |
|
879 |
- sendAck = 1; // remember to send an ACK |
|
880 |
- pConn->RcvNxt++; // FIN counts as one in sequence number space |
|
881 |
- pConn->State = TCP_CLOSING; // Enter the CLOSING state. |
|
882 |
- break; |
|
883 |
- |
|
884 |
- case TCP_FIN_WAIT_2: |
|
885 |
- sendAck = 1; // remember to send an ACK |
|
886 |
- pConn->RcvNxt++; // FIN counts as one in sequence number space |
|
887 |
- pConn->State = TCP_TIME_WAIT; // Enter the TIME-WAIT state. |
|
888 |
- break; |
|
889 |
- |
|
890 |
- case TCP_CLOSING: |
|
891 |
- case TCP_CLOSE_WAIT: |
|
892 |
- case TCP_LAST_ACK: |
|
893 |
- case TCP_TIME_WAIT: |
|
894 |
- sendAck = 1; // remember to send an ACK |
|
895 |
- break; |
|
896 |
- |
|
897 |
- } // switch( pConn->State ) |
|
898 |
- } |
|
899 |
- |
|
900 |
- // send data / ACK segment |
|
901 |
- TcpSendDataSegment( connNo, pConn, sendAck ); |
|
902 |
-} |
|
903 |
- |
|
904 |
-// open a TCP connection |
|
905 |
-// must not be called from a TCP notification function |
|
906 |
-// returns the connection number of the new connection of 0xFF in case of error |
|
907 |
-unsigned char TcpOpen( unsigned char * remoteIp, unsigned short remotePort, // (extern) |
|
908 |
- unsigned short initialWnd, struct TcpNotify * Notify ) |
|
909 |
-#define TcpOpenLocalPortMin 32768 |
|
910 |
-#define TcpOpenLocalPortRange 16384 |
|
911 |
-{ |
|
912 |
- static unsigned short nextLocalPort = TcpOpenLocalPortMin; // local port to use for next TCP connection |
|
913 |
- unsigned short localPort; |
|
914 |
- unsigned char i; |
|
915 |
- |
|
916 |
- debug_tcp_printf( "open ip=%u.%u.%u.%u port=%u", |
|
917 |
- remoteIp[0], remoteIp[1], remoteIp[2], remoteIp[3], |
|
918 |
- remotePort ); |
|
919 |
- |
|
920 |
- // search an unused local port |
|
921 |
- for( localPort = nextLocalPort; ; localPort++ ) |
|
922 |
- { |
|
923 |
- for( i = 0; i < count( TcpConns ); i++ ) |
|
924 |
- if( TcpConns[i].State != TCP_CLOSED && |
|
925 |
- TcpConns[i].LocalPort == localPort ) |
|
926 |
- break; |
|
927 |
- if( i >= count( TcpConns ) ) |
|
928 |
- break; |
|
929 |
- } |
|
930 |
- // save next local port to use |
|
931 |
- nextLocalPort = localPort + 1; |
|
932 |
- if( nextLocalPort >= TcpOpenLocalPortMin + TcpOpenLocalPortRange ) |
|
933 |
- nextLocalPort = TcpOpenLocalPortMin; |
|
934 |
- |
|
935 |
- // search empty connection slot |
|
936 |
- for( i = 0; i < count( TcpConns ); i++ ) |
|
937 |
- if( TcpConns[i].State == TCP_CLOSED ) |
|
938 |
- break; |
|
939 |
- // no free connection slot found |
|
940 |
- if( i >= count( TcpConns ) ) |
|
941 |
- return 0xFF; |
|
942 |
- |
|
943 |
- // create new connection in this slot |
|
944 |
- ip_cpy( TcpConns[i].RemoteIp, remoteIp ); |
|
945 |
- TcpConns[i].LocalPort = localPort; |
|
946 |
- TcpConns[i].RemotePort = remotePort; |
|
947 |
- TcpConns[i].RcvNxt = 0; |
|
948 |
- TcpConns[i].Irs = 0; |
|
949 |
- RandomGetData( (unsigned char *)&TcpConns[i].Iss, sizeof( TcpConns[i].Iss ) ); // An initial send sequence number (ISS) is selected. |
|
950 |
- TcpSynSegment( &TcpConns[i], TcpConns[i].Iss, 0, TCP_SYN ); // A SYN segment of the form <SEQ=ISS><CTL=SYN> is sent. |
|
951 |
- TcpConns[i].SndUna = TcpConns[i].Iss; // Set SND.UNA to ISS, |
|
952 |
- TcpConns[i].SndNxt = TcpConns[i].Iss + 1; // SND.NXT to ISS+1, |
|
953 |
- TcpConns[i].State = TCP_SYN_SENT; // enter SYN-SENT state, |
|
954 |
- TcpConns[i].SndWnd = 0; // not allowed to send data for now |
|
955 |
- TcpConns[i].SndWl1 = 0; // window size was never updated |
|
956 |
- TcpConns[i].SndWl2 = 0; |
|
957 |
- TcpConns[i].Ticks = 0; // restart timers |
|
958 |
- TcpConns[i].Timeout = 0; |
|
959 |
- TcpConns[i].LifeTime = 0; |
|
960 |
- TcpConns[i].RcvWnd = initialWnd; |
|
961 |
- TcpConns[i].Notify = Notify; |
|
962 |
- |
|
963 |
- debug_tcp_printf( "open no=%u", i ); |
|
964 |
- |
|
965 |
- // return connection number |
|
966 |
- return i; |
|
967 |
-} |
|
968 |
- |
|
969 |
-// close a TCP connection |
|
970 |
-// must not be called from a TCP notification function |
|
971 |
-void TcpClose( unsigned char connNo ) // (extern) |
|
972 |
-{ |
|
973 |
- struct TcpConnection * pConn; |
|
974 |
- |
|
975 |
- debug_tcp_printf( "close no=%u", connNo ); |
|
976 |
- |
|
977 |
- // connection does not exist |
|
978 |
- if( connNo >= count( TcpConns ) || TcpConns[connNo].State == TCP_CLOSED ) |
|
979 |
- return; |
|
980 |
- |
|
981 |
- // get connection |
|
982 |
- pConn = &TcpConns[connNo]; |
|
983 |
- |
|
984 |
- // different actions in different states accroding to RFC793 |
|
985 |
- switch( pConn->State ) |
|
986 |
- { |
|
987 |
- |
|
988 |
- case TCP_LISTEN: |
|
989 |
- case TCP_SYN_SENT: |
|
990 |
- pConn->State = TCP_CLOSED; // Delete TCB, enter CLOSED state, |
|
991 |
- break; // and return. |
|
992 |
- |
|
993 |
- case TCP_SYN_RCVD: |
|
994 |
- case TCP_ESTAB: |
|
995 |
- TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // form a FIN segment and send it, |
|
996 |
- pConn->SndNxt++; |
|
997 |
- pConn->State = TCP_FIN_WAIT_1; // and enter FIN-WAIT-1 state; |
|
998 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
999 |
- pConn->Notify->Close( connNo ); // signal "connection closed" to user |
|
1000 |
- break; |
|
1001 |
- |
|
1002 |
- case TCP_CLOSE_WAIT: |
|
1003 |
- TcpEmptySegment( pConn, pConn->SndNxt, pConn->RcvNxt, TCP_FIN | TCP_ACK ); // send a FIN segment, |
|
1004 |
- pConn->SndNxt++; |
|
1005 |
- pConn->State = TCP_CLOSING; // enter CLOSING state. |
|
1006 |
- debug_tcp_printf( "notify close no=%u", connNo ); |
|
1007 |
- pConn->Notify->Close( connNo ); // signal "connection closed" to user |
|
1008 |
- break; |
|
1009 |
- |
|
1010 |
- } // switch( pConn->State ) |
|
1011 |
-} |
|
1012 |
- |
|
1013 |
-// request sending on a TCP connection |
|
1014 |
-// must not be called from a TCP notification function |
|
1015 |
-// this makes the send notification to be called if possible |
|
1016 |
-void TcpSend( unsigned char connNo ) // (extern) |
|
1017 |
-{ |
|
1018 |
- struct TcpConnection * pConn; |
|
1019 |
- |
|
1020 |
- debug_tcp_printf( "send no=%u", connNo ); |
|
1021 |
- |
|
1022 |
- // connection does not exist |
|
1023 |
- if( connNo >= count( TcpConns ) || TcpConns[connNo].State == TCP_CLOSED ) |
|
1024 |
- return; |
|
1025 |
- |
|
1026 |
- // get connection |
|
1027 |
- pConn = &TcpConns[connNo]; |
|
1028 |
- |
|
1029 |
- // different behaviour in different states |
|
1030 |
- switch( pConn->State ) |
|
1031 |
- { |
|
1032 |
- |
|
1033 |
- case TCP_ESTAB: |
|
1034 |
- case TCP_CLOSE_WAIT: |
|
1035 |
- // if nothing is sent and not yet ACKed |
|
1036 |
- if( pConn->SndUna == pConn->SndNxt ) |
|
1037 |
- // send a data segment |
|
1038 |
- TcpSendDataSegment( connNo, pConn, 0 ); |
|
1039 |
- break; |
|
1040 |
- |
|
1041 |
- } // switch( TcpConns[i].State ) |
|
1042 |
-} |
|
1043 |
- |
|
1044 |
-// dummy notification functions |
|
1045 |
-void TcpDummyConnect( unsigned char ConnNo ) { } |
|
1046 |
-void TcpDummyClose( unsigned char ConnNo ) { } |
|
1047 |
-unsigned short TcpDummySend( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short MaxLen ) { return 0; } |
|
1048 |
-void TcpDummySent( unsigned char ConnNo, unsigned long Pos ) { } |
|
1049 |
-unsigned short TcpDummyReceived( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short Len, unsigned short curWnd ) { return max( curWnd, 128 ); } |
|
1050 |
-struct TcpNotify TcpDummyNotify = // (extern) |
|
1051 |
-{ |
|
1052 |
- .Connect = TcpDummyConnect, |
|
1053 |
- .Close = TcpDummyClose, |
|
1054 |
- .Send = TcpDummySend, |
|
1055 |
- .Sent = TcpDummySent, |
|
1056 |
- .Received = TcpDummyReceived, |
|
1057 |
-}; |
|
1058 |
- |
... | ... |
@@ -1,112 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_tcp |
|
9 |
-#define INC_tcp |
|
10 |
- |
|
11 |
-#include "ethernet.h" |
|
12 |
-#include "ip.h" |
|
13 |
- |
|
14 |
-// header of a TCP packet |
|
15 |
-struct TcpHeader |
|
16 |
-{ |
|
17 |
- unsigned int SrcPort; |
|
18 |
- unsigned int DestPort; |
|
19 |
- unsigned long SeqNo; |
|
20 |
- unsigned long AckNo; |
|
21 |
- unsigned int Ofs_Flags; |
|
22 |
- unsigned int WndSz; |
|
23 |
- unsigned int Chk; |
|
24 |
- unsigned int UrgentPtr; |
|
25 |
-}; |
|
26 |
- |
|
27 |
-// a TCP packet |
|
28 |
-struct TcpPacket |
|
29 |
-{ |
|
30 |
- struct EthernetHeader EthHdr; |
|
31 |
- struct IpHeader IpHdr; |
|
32 |
- struct TcpHeader TcpHdr; |
|
33 |
-}; |
|
34 |
- |
|
35 |
-// TCP notify functions |
|
36 |
-struct TcpNotify |
|
37 |
-{ |
|
38 |
- // called when connection is established |
|
39 |
- void (*Connect)( unsigned char ConnNo ); |
|
40 |
- // called when connection is closed / reset |
|
41 |
- // (after this, the connection number may not be used any more) |
|
42 |
- void (*Close)( unsigned char ConnNo ); |
|
43 |
- // called when sending data is possible |
|
44 |
- // (return length of available data, 0xFFFF to close connection) |
|
45 |
- unsigned short (*Send)( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short MaxLen ); |
|
46 |
- // called when data was sent and ACKed |
|
47 |
- void (*Sent)( unsigned char ConnNo, unsigned long Pos ); |
|
48 |
- // called when data was received, must return new window size (not smaller than curWnd) |
|
49 |
- unsigned short (*Received)( unsigned char ConnNo, unsigned long Pos, unsigned char * pBuffer, unsigned short Len, unsigned short curWnd ); |
|
50 |
-}; |
|
51 |
- |
|
52 |
-// a TCP connection (member names according to RFC793) |
|
53 |
-// BUG: missing urgent pointers, which must be supported according to RFC793 |
|
54 |
-// but urgent data is not used in protocols we use, so leave this out here to save time and memory |
|
55 |
-#define TCP_CLOSED 0 |
|
56 |
-#define TCP_LISTEN 1 |
|
57 |
-#define TCP_SYN_SENT 2 |
|
58 |
-#define TCP_SYN_RCVD 3 |
|
59 |
-#define TCP_ESTAB 4 |
|
60 |
-#define TCP_FIN_WAIT_1 5 |
|
61 |
-#define TCP_FIN_WAIT_2 6 |
|
62 |
-#define TCP_CLOSE_WAIT 7 |
|
63 |
-#define TCP_LAST_ACK 8 |
|
64 |
-#define TCP_CLOSING 9 |
|
65 |
-#define TCP_TIME_WAIT 10 |
|
66 |
-struct TcpConnection |
|
67 |
-{ |
|
68 |
- unsigned char RemoteIp[4]; |
|
69 |
- unsigned short LocalPort, RemotePort; |
|
70 |
- unsigned char State; // one of TCP_* |
|
71 |
- unsigned long SndUna; // send unacknowledged |
|
72 |
- unsigned long SndNxt; // send next |
|
73 |
- unsigned short SndWnd; // send window |
|
74 |
- unsigned long SndWl1; // segment sequence number used for last window update |
|
75 |
- unsigned long SndWl2; // segment acknowledgment number used for last window update |
|
76 |
- unsigned long Iss; // initial send sequence number |
|
77 |
- unsigned long RcvNxt; // receive next |
|
78 |
- unsigned short RcvWnd; // receive window |
|
79 |
- unsigned long Irs; // initial receive sequence number |
|
80 |
- unsigned short Mss; // maximum segment size |
|
81 |
- unsigned char Ticks; // retransmission and time-wait timer (time since last packet sent or received in 200ms steps) |
|
82 |
- unsigned char Timeout; // timeout timer (time since last data was sent or received) |
|
83 |
- unsigned char LifeTime; // lifetime timer (time since begin of connection) |
|
84 |
- struct TcpNotify * Notify; // notification functions |
|
85 |
-}; |
|
86 |
- |
|
87 |
-// initialize |
|
88 |
-extern void TcpInit( void ); |
|
89 |
- |
|
90 |
-// tick procedure - call every 200ms |
|
91 |
-extern void TcpTick200( void ); |
|
92 |
- |
|
93 |
-// process a received TCP packet |
|
94 |
-extern void TcpRecv( unsigned char * pData, unsigned short Length ); |
|
95 |
- |
|
96 |
-// open a TCP connection |
|
97 |
-// must not be called from a TCP notification function |
|
98 |
-// returns the connection number of the new connection of 0xFF in case of error |
|
99 |
-extern unsigned char TcpOpen( unsigned char * remoteIp, unsigned short remotePort, |
|
100 |
- unsigned short initialWnd, struct TcpNotify * Notify ); |
|
101 |
- |
|
102 |
-// close a TCP connection |
|
103 |
-// must not be called from a TCP notification function |
|
104 |
-extern void TcpClose( unsigned char connNo ); |
|
105 |
- |
|
106 |
-// request sending on a TCP connection |
|
107 |
-// must not be called from a TCP notification function |
|
108 |
-// this makes the send notification to be called if possible |
|
109 |
-extern void TcpSend( unsigned char connNo ); |
|
110 |
- |
|
111 |
-#endif // #ifdef INC_tcp |
|
112 |
- |
... | ... |
@@ -1,108 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <avr/io.h> |
|
9 |
-#include <avr/interrupt.h> |
|
10 |
- |
|
11 |
-#include "arp.h" |
|
12 |
-#include "cf.h" |
|
13 |
-#include "dart.h" |
|
14 |
-#include "dhcp.h" |
|
15 |
-#include "ip.h" |
|
16 |
-#include "http.h" |
|
17 |
-#include "random.h" |
|
18 |
-#include "rtl8019.h" |
|
19 |
-#include "status.h" |
|
20 |
-#include "tcp.h" |
|
21 |
-#include "timing.h" |
|
22 |
-#include "udp.h" |
|
23 |
- |
|
24 |
-// 2ms tick counter to generate 20ms ticks |
|
25 |
-volatile unsigned char Timing2_10 = 0; |
|
26 |
- |
|
27 |
-// flag set every 20ms to indicate execution of 20ms ticks |
|
28 |
-volatile unsigned char Timing20Flag = 0; |
|
29 |
- |
|
30 |
-// wrapping around 20ms tick counter |
|
31 |
-unsigned char Timing20 = 0; |
|
32 |
- |
|
33 |
-// 20ms tick counter to generate 200ms ticks |
|
34 |
-unsigned char Timing20_10 = 0; |
|
35 |
- |
|
36 |
-// 2ms interrupt (timer 0 compare match) |
|
37 |
-SIGNAL( SIG_OUTPUT_COMPARE0 ) |
|
38 |
-{ |
|
39 |
- // set flag every 20ms |
|
40 |
- Timing2_10++; |
|
41 |
- if( Timing2_10 >= 10 ) |
|
42 |
- { |
|
43 |
- Timing2_10 = 0; |
|
44 |
- Timing20Flag = 1; |
|
45 |
- } |
|
46 |
-} |
|
47 |
- |
|
48 |
-// initialize |
|
49 |
-void TimingInit( void ) // (extern) |
|
50 |
-{ |
|
51 |
- // configure timer 0 to 2ms interval |
|
52 |
- TCCR0 = 0<<FOC0 | 1<<WGM01 | 0<<WGM00 | // count to OCR0 |
|
53 |
- 0<<COM01 | 0<<COM00 | // no waveform generation |
|
54 |
- 1<<CS02 | 1<<CS01 | 0<<CS00; // 1/256 of sysclock (16MHz) -> increment every 16us |
|
55 |
- OCR0 = 124; // count to 124 -> 2ms interval |
|
56 |
- |
|
57 |
- // enable timer 0 compare match interrupt |
|
58 |
- TIMSK |= 1<<OCIE0; |
|
59 |
- |
|
60 |
- // configure timer 1 to count cycles |
|
61 |
- TCCR1A = 0<<WGM11 | 0<<WGM10; // normal mode |
|
62 |
- TCCR1B = 0<<WGM13 | 0<<WGM12 | 0<<CS12 | 0<<CS11 | 1<<CS10; // normal mode, no prescaler |
|
63 |
-} |
|
64 |
- |
|
65 |
-// provide curent time stamp as entropy to random number generator |
|
66 |
-void TimingEntropy( void ) // (extern) |
|
67 |
-{ |
|
68 |
- unsigned short timestamp = TCNT1; |
|
69 |
- RandomProvideEntropy( (unsigned char)timestamp ); |
|
70 |
- RandomProvideEntropy( (unsigned char)(timestamp >> 8) ); |
|
71 |
-} |
|
72 |
- |
|
73 |
-// provide curent 20ms tick counter as entropy to random number generator |
|
74 |
-void Timing20Entropy( void ) // (extern) |
|
75 |
-{ |
|
76 |
- RandomProvideEntropy( Timing20 ); |
|
77 |
-} |
|
78 |
- |
|
79 |
-// task function to do the work - call from main loop |
|
80 |
-void TimingTask( void ) // (extern) |
|
81 |
-{ |
|
82 |
- // 20ms not elapsed |
|
83 |
- if( ! Timing20Flag ) |
|
84 |
- return; |
|
85 |
- Timing20Flag = 0; |
|
86 |
- |
|
87 |
- // call 20ms tick functions |
|
88 |
- |
|
89 |
- // generate 200ms steps |
|
90 |
- Timing20_10++; |
|
91 |
- if( Timing20_10 >= 10 ) |
|
92 |
- Timing20_10 = 0; |
|
93 |
- |
|
94 |
- // call 200ms tick functions at different times |
|
95 |
- switch( Timing20_10 ) |
|
96 |
- { |
|
97 |
- case 1: ArpTick200( ); break; |
|
98 |
- case 2: DartTick200( ); break; |
|
99 |
- case 3: IpTick200( ); break; |
|
100 |
- case 4: HttpTick200( ); break; |
|
101 |
- case 5: RtlTick200( ); break; |
|
102 |
- case 6: StatusTick200( ); break; |
|
103 |
- case 7: TcpTick200( ); break; |
|
104 |
- case 8: UdpTick200( ); break; |
|
105 |
- case 9: DhcpTick200( ); break; |
|
106 |
- } |
|
107 |
-} |
|
108 |
- |
... | ... |
@@ -1,23 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_timing |
|
9 |
-#define INC_timing |
|
10 |
- |
|
11 |
-// initialize |
|
12 |
-extern void TimingInit( void ); |
|
13 |
- |
|
14 |
-// provide curent time stamp as entropy to random number generator |
|
15 |
-extern void TimingEntropy( void ); |
|
16 |
- |
|
17 |
-// provide curent 20ms tick counter as entropy to random number generator |
|
18 |
-extern void Timing20Entropy( void ); |
|
19 |
- |
|
20 |
-// task function to do the work - call from main loop |
|
21 |
-extern void TimingTask( void ); |
|
22 |
- |
|
23 |
-#endif // #ifndef INC_timing |
... | ... |
@@ -1,43 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <stdio.h> |
|
9 |
-#include <avr/io.h> |
|
10 |
-#include <avr/wdt.h> |
|
11 |
- |
|
12 |
-#include "macros.h" |
|
13 |
-#include "uart.h" |
|
14 |
- |
|
15 |
-#define BAUD_RATE 38400 |
|
16 |
- |
|
17 |
-// initialize |
|
18 |
-void UartInit( void ) // (extern) |
|
19 |
-{ |
|
20 |
- // enable transmission |
|
21 |
- UCSR0B = 1<<TXEN; |
|
22 |
- // set baudrate (16MHz crystal) |
|
23 |
- UBRR0L = 16000000 / (BAUD_RATE * 16L) - 1; |
|
24 |
- |
|
25 |
- // set STDOUT to use UartPutchar |
|
26 |
- fdevopen( UartPutchar, NULL ); |
|
27 |
-} |
|
28 |
- |
|
29 |
-// write a character |
|
30 |
-int UartPutchar( char c, FILE * file ) // (extern) |
|
31 |
-{ |
|
32 |
- // wait until last character was sent |
|
33 |
- while( bit_is_clear( UCSR0A, UDRE ) ) |
|
34 |
- wdt_reset( ); |
|
35 |
- |
|
36 |
- // send character |
|
37 |
- UDR0 = c; |
|
38 |
- |
|
39 |
- return 0; |
|
40 |
- |
|
41 |
- file = NULL; // keep compiler happy |
|
42 |
-} |
|
43 |
- |
... | ... |
@@ -1,18 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_uart |
|
9 |
-#define INC_uart |
|
10 |
- |
|
11 |
-// initialize |
|
12 |
-extern void UartInit( void ); |
|
13 |
- |
|
14 |
-// write a character |
|
15 |
-extern int UartPutchar( char c, FILE * file ); |
|
16 |
- |
|
17 |
-#endif // #ifndef INC_uart |
|
18 |
- |
... | ... |
@@ -1,171 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include "config.h" |
|
9 |
-#include "checksum.h" |
|
10 |
-#include "dart.h" |
|
11 |
-#include "debug.h" |
|
12 |
-#include "dhcp.h" |
|
13 |
-#include "ethernet.h" |
|
14 |
-#include "ip.h" |
|
15 |
-#include "macros.h" |
|
16 |
-#include "nethelp.h" |
|
17 |
-#include "udp.h" |
|
18 |
- |
|
19 |
-// some kind of "token bucket" for UDP echo |
|
20 |
-#define UdpEchoTicks 10 // allowed rate of UDP echo replies (in 200ms steps) |
|
21 |
-unsigned char UdpEchoTickCnt = 0; // tick counter |
|
22 |
-#define UdpEchoReliesMax 3 // maximum value for UdpEchoReplies |
|
23 |
-unsigned char UdpEchoReplies = 0; // number of UDP echo replies that may be sent at the moment |
|
24 |
- |
|
25 |
-// tick procedure - call every 200ms |
|
26 |
-void UdpTick200( void ) // (extern) |
|
27 |
-{ |
|
28 |
- // count ticks |
|
29 |
- UdpEchoTickCnt++; |
|
30 |
- // time to allow one reply more |
|
31 |
- if( UdpEchoTickCnt >= UdpEchoTicks ) |
|
32 |
- { |
|
33 |
- UdpEchoTickCnt = 0; |
|
34 |
- |
|
35 |
- // increase reply count if not at maximum |
|
36 |
- if( UdpEchoReplies < UdpEchoReliesMax ) |
|
37 |
- UdpEchoReplies++; |
|
38 |
- } |
|
39 |
-} |
|
40 |
- |
|
41 |
-// process a received UDP echo packet |
|
42 |
-static void UdpEchoRecv( unsigned char * pData, unsigned short Length ) |
|
43 |
-{ |
|
44 |
- struct UdpPacket * pUdpPack; |
|
45 |
- |
|
46 |
- // convert pointer to UDP packet |
|
47 |
- // (this saves us from always casting pData) |
|
48 |
- pUdpPack = (struct UdpPacket *)pData; |
|
49 |
- |
|
50 |
- // source port is UDP echo port |
|
51 |
- if( pUdpPack->UdpHdr.SrcPort == htons( 7 ) ) |
|
52 |
- // ignore this packet |
|
53 |
- // - UDP echo answer to another UDP echo port will result in endless echoing |
|
54 |
- return; |
|
55 |
- |
|
56 |
- // only reply with allowed packet rate |
|
57 |
- if( UdpEchoReplies == 0 ) |
|
58 |
- { |
|
59 |
- debug_udp_printf( "echo len=%u (dropped)", Length ); |
|
60 |
- return; |
|
61 |
- } |
|
62 |
- UdpEchoReplies--; |
|
63 |
- |
|
64 |
- debug_udp_printf( "echo len=%u", Length ); |
|
65 |
- |
|
66 |
- // send an UDP echo |
|
67 |
- // - use same buffer to send reply |
|
68 |
- // - this saves us from allocating a new buffer |
|
69 |
- // - this saves us from copying the data |
|
70 |
- pUdpPack->UdpHdr.DestPort = pUdpPack->UdpHdr.SrcPort; // back to originationg port |
|
71 |
- pUdpPack->UdpHdr.SrcPort = htons( 7 ); // UDP echo port |
|
72 |
- ip_cpy( pUdpPack->IpHdr.Dest, pUdpPack->IpHdr.Src ); // back to originating IP |
|
73 |
- UdpSend( pData, Length ); |
|
74 |
-} |
|
75 |
- |
|
76 |
-// process a received UDP packet |
|
77 |
-void UdpRecv( unsigned char * pData, unsigned short Length ) // (extern) |
|
78 |
-{ |
|
79 |
- struct UdpPacket * pUdpPack; |
|
80 |
- unsigned int len; |
|
81 |
- |
|
82 |
- // packet too short |
|
83 |
- if( Length < sizeof( struct UdpPacket ) ) |
|
84 |
- return; |
|
85 |
- |
|
86 |
- // convert pointer to UDP packet |
|
87 |
- // (this saves us from always casting pData) |
|
88 |
- pUdpPack = (struct UdpPacket *)pData; |
|
89 |
- |
|
90 |
- // ignore packets sent from or to port 0 |
|
91 |
- // - this might be some attack |
|
92 |
- if( pUdpPack->UdpHdr.SrcPort == htons( 0 ) || |
|
93 |
- pUdpPack->UdpHdr.DestPort == htons( 0 ) ) |
|
94 |
- return; |
|
95 |
- |
|
96 |
- // check total length |
|
97 |
- len = sizeof( struct EthernetHeader ) + sizeof( struct IpHeader ) + ntohs( pUdpPack->UdpHdr.Length ); // length according to UDP header |
|
98 |
- if( Length < len ) // packet is truncated |
|
99 |
- return; |
|
100 |
- Length = len; // remove IP padding from packet (maybe Length > len) |
|
101 |
- |
|
102 |
- // test checksum |
|
103 |
- if( Checksum( (unsigned char*)&pUdpPack->IpHdr.Src, |
|
104 |
- Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8, |
|
105 |
- 0x0011, |
|
106 |
- ntohs( pUdpPack->UdpHdr.Length ) ) != 0 ) |
|
107 |
- return; |
|
108 |
- |
|
109 |
- debug_udp_printf( "recv src=%u dest=%u len=%u", |
|
110 |
- ntohs( pUdpPack->UdpHdr.SrcPort ), |
|
111 |
- ntohs( pUdpPack->UdpHdr.DestPort ), |
|
112 |
- Length ); |
|
113 |
- |
|
114 |
- // branch according to destination port |
|
115 |
- switch( ntohs( pUdpPack->UdpHdr.DestPort ) ) |
|
116 |
- { |
|
117 |
- // UDP echo |
|
118 |
- case 7: |
|
119 |
- UdpEchoRecv( pData, Length ); |
|
120 |
- break; |
|
121 |
- // DHCP |
|
122 |
- case 68: |
|
123 |
- DhcpRecv( pData, Length ); |
|
124 |
- break; |
|
125 |
- // dart board |
|
126 |
- case 501: |
|
127 |
- DartRequest( pUdpPack->IpHdr.Src, |
|
128 |
- ntohs( pUdpPack->UdpHdr.SrcPort ) ); |
|
129 |
- break; |
|
130 |
- } |
|
131 |
-} |
|
132 |
- |
|
133 |
-// send an UDP packet |
|
134 |
-// pData must point to a struct UdpPacket with UdpHdr.SrcPort, UdpHdr.DestPort and IpHdr.Dest already initialized |
|
135 |
-void UdpSend( unsigned char * pData, unsigned short Length ) // (extern) |
|
136 |
-{ |
|
137 |
- struct UdpPacket * pUdpPack; |
|
138 |
- unsigned int chk; |
|
139 |
- |
|
140 |
- // packet too short |
|
141 |
- if( Length < sizeof( struct UdpPacket ) ) |
|
142 |
- return; |
|
143 |
- |
|
144 |
- // convert pointer to UDP packet |
|
145 |
- // (this saves us from always casting pData) |
|
146 |
- pUdpPack = (struct UdpPacket *)pData; |
|
147 |
- |
|
148 |
- debug_udp_printf( "send src=%u dest=%u len=%u", |
|
149 |
- ntohs( pUdpPack->UdpHdr.SrcPort ), |
|
150 |
- ntohs( pUdpPack->UdpHdr.DestPort ), |
|
151 |
- Length ); |
|
152 |
- |
|
153 |
- // fill in header values |
|
154 |
- pUdpPack->UdpHdr.Length = htons( Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) ); |
|
155 |
- pUdpPack->UdpHdr.Chk = 0x0000; |
|
156 |
- ip_cpy( pUdpPack->IpHdr.Src, ConfigIp ); // put IP already here into IP header |
|
157 |
- // because it is needed for calculation of UDP checksum |
|
158 |
- |
|
159 |
- // generate checksum |
|
160 |
- chk = Checksum( (unsigned char *)&pUdpPack->IpHdr.Src, |
|
161 |
- Length - sizeof( struct EthernetHeader ) - sizeof( struct IpHeader ) + 8, |
|
162 |
- 0x0011, |
|
163 |
- ntohs( pUdpPack->UdpHdr.Length ) ); |
|
164 |
- pUdpPack->UdpHdr.Chk = htons( chk ); |
|
165 |
- |
|
166 |
- // send UDP packet |
|
167 |
- pUdpPack->IpHdr.Proto = 0x11; // UDP |
|
168 |
- IpSend( pData, Length ); |
|
169 |
-} |
|
170 |
- |
|
171 |
- |
... | ... |
@@ -1,42 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_udp |
|
9 |
-#define INC_udp |
|
10 |
- |
|
11 |
-#include "ethernet.h" |
|
12 |
-#include "ip.h" |
|
13 |
- |
|
14 |
-// header of an UDP packet |
|
15 |
-struct UdpHeader |
|
16 |
-{ |
|
17 |
- unsigned int SrcPort; |
|
18 |
- unsigned int DestPort; |
|
19 |
- unsigned int Length; |
|
20 |
- unsigned int Chk; |
|
21 |
-}; |
|
22 |
- |
|
23 |
-// an UDP packet |
|
24 |
-struct UdpPacket |
|
25 |
-{ |
|
26 |
- struct EthernetHeader EthHdr; |
|
27 |
- struct IpHeader IpHdr; |
|
28 |
- struct UdpHeader UdpHdr; |
|
29 |
-}; |
|
30 |
- |
|
31 |
-// tick procedure - call every 200ms |
|
32 |
-extern void UdpTick200( void ); |
|
33 |
- |
|
34 |
-// process a received UDP packet |
|
35 |
-extern void UdpRecv( unsigned char * pData, unsigned short Length ); |
|
36 |
- |
|
37 |
-// send an UDP packet |
|
38 |
-// pData must point to a struct UdpPacket with UdpHdr.SrcPort, UdpHdr.DestPort and IpHdr.Dest already initialized |
|
39 |
-extern void UdpSend( unsigned char * pData, unsigned short Length ); |
|
40 |
- |
|
41 |
-#endif // #ifdef INC_udp |
|
42 |
- |
... | ... |
@@ -1,86 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#include <stdint.h> |
|
9 |
- |
|
10 |
-#include "xtea.h" |
|
11 |
- |
|
12 |
-#define delta 0x9E3779B9 |
|
13 |
- |
|
14 |
-// XTEA encrypt a block of 64 bits |
|
15 |
-// - this is not block XTEA, it's the basic XTEA algorithm |
|
16 |
-static void xtea_enc_block( uint32_t key[4], uint8_t rounds, uint32_t in[2], uint32_t out[2] ) |
|
17 |
-{ |
|
18 |
- uint32_t y, z, sum; |
|
19 |
- |
|
20 |
- y = in[0]; |
|
21 |
- z = in[1]; |
|
22 |
- sum = 0; |
|
23 |
- for( ; rounds > 0; rounds-- ) |
|
24 |
- { |
|
25 |
- y += ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); |
|
26 |
- sum += delta; |
|
27 |
- z += ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); |
|
28 |
- } |
|
29 |
- out[0] = y; |
|
30 |
- out[1] = z; |
|
31 |
-} |
|
32 |
- |
|
33 |
-// XTEA decrypt a block of 64 bits |
|
34 |
-// - this is not block XTEA, it's the basic XTEA algorithm |
|
35 |
-static void xtea_dec_block( uint32_t key[4], uint8_t rounds, uint32_t in[2], uint32_t out[2] ) |
|
36 |
-{ |
|
37 |
- uint32_t y, z, sum; |
|
38 |
- |
|
39 |
- y = in[0]; |
|
40 |
- z = in[1]; |
|
41 |
- sum = (uint32_t)delta * rounds; |
|
42 |
- for( ; rounds > 0; rounds-- ) |
|
43 |
- { |
|
44 |
- z -= ((y << 4 ^ y >> 5) + y) ^ (sum + key[sum >> 11 & 3]); |
|
45 |
- sum -= delta; |
|
46 |
- y -= ((z << 4 ^ z >> 5) + z) ^ (sum + key[sum & 3]); |
|
47 |
- } |
|
48 |
- out[0] = y; |
|
49 |
- out[1] = z; |
|
50 |
-} |
|
51 |
- |
|
52 |
-// XTEA encryption |
|
53 |
-// rounds should be at least 32 |
|
54 |
-// p_in == p_out is allowed |
|
55 |
-// p_prev must be initialized to zero before first call to this function |
|
56 |
-void xtea_enc( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev ) // extern |
|
57 |
-{ |
|
58 |
- uint64_t in, out; |
|
59 |
- unsigned int i; |
|
60 |
- |
|
61 |
- for( i = 0; i < block_cnt; i++ ) |
|
62 |
- { |
|
63 |
- in = p_in[i] ^ *p_prev; |
|
64 |
- xtea_enc_block( key, rounds, (uint32_t *)&in, (uint32_t *)&out ); |
|
65 |
- p_out[i] = out; |
|
66 |
- *p_prev = out; |
|
67 |
- } |
|
68 |
-} |
|
69 |
- |
|
70 |
-// XTEA decryption |
|
71 |
-// rounds should be at least 32 |
|
72 |
-// p_in == p_out is allowed |
|
73 |
-// p_prev must be initialized to zero before first call to this function |
|
74 |
-void xtea_dec( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev ) // extern |
|
75 |
-{ |
|
76 |
- uint64_t in, out; |
|
77 |
- unsigned int i; |
|
78 |
- |
|
79 |
- for( i = 0; i < block_cnt; i++ ) |
|
80 |
- { |
|
81 |
- in = p_in[i]; |
|
82 |
- xtea_dec_block( key, rounds, (uint32_t *)&in, (uint32_t *)&out ); |
|
83 |
- p_out[i] = out ^ *p_prev; |
|
84 |
- *p_prev = in; |
|
85 |
- } |
|
86 |
-} |
... | ... |
@@ -1,25 +0,0 @@ |
1 |
-/* flaneth - flash and ethernet - dartboard mod |
|
2 |
- * version 0.1 date 2008-11-09 |
|
3 |
- * Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info> |
|
4 |
- * Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html |
|
5 |
- * a BlinkenArea project - http://www.blinkenarea.org/ |
|
6 |
- */ |
|
7 |
- |
|
8 |
-#ifndef INC_xtea |
|
9 |
-#define INC_xtea |
|
10 |
- |
|
11 |
-#include <stdint.h> |
|
12 |
- |
|
13 |
-// XTEA encryption |
|
14 |
-// rounds should be at least 32 |
|
15 |
-// p_in == p_out is allowed |
|
16 |
-// p_prev must be initialized to zero before first call to this function |
|
17 |
-extern void xtea_enc( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev ); |
|
18 |
- |
|
19 |
-// XTEA decryption |
|
20 |
-// rounds should be at least 32 |
|
21 |
-// p_in == p_out is allowed |
|
22 |
-// p_prev must be initialized to zero before first call to this function |
|
23 |
-extern void xtea_dec( uint32_t key[4], uint8_t rounds, uint64_t * p_in, uint64_t * p_out, unsigned int block_cnt, uint64_t * p_prev ); |
|
24 |
- |
|
25 |
-#endif // #ifndef INC_xtea |
|
26 | 0 |