arm/nds: Remove

updates #2450.
This commit is contained in:
Aun-Ali Zaidi
2015-12-11 09:20:34 -05:00
committed by Gedare Bloom
parent df55d07f2e
commit 32c2cd2be1
254 changed files with 0 additions and 42975 deletions
-2
View File
@@ -28,8 +28,6 @@ AC_DEFUN([RTEMS_CHECK_BSPDIR],
AC_CONFIG_SUBDIRS([lpc24xx]);;
lpc32xx )
AC_CONFIG_SUBDIRS([lpc32xx]);;
nds )
AC_CONFIG_SUBDIRS([nds]);;
raspberrypi )
AC_CONFIG_SUBDIRS([raspberrypi]);;
realview-pbx-a9 )
-236
View File
@@ -1,236 +0,0 @@
ACLOCAL_AMFLAGS = -I ../../../../aclocal
SUBDIRS = . tools
include $(top_srcdir)/../../../../automake/compile.am
include_bspdir = $(includedir)/bsp
dist_project_lib_DATA = bsp_specs
include_HEADERS = include/bsp.h
include_HEADERS += ../../shared/include/tm27.h
nodist_include_HEADERS = include/bspopts.h
nodist_include_HEADERS += ../../shared/include/coverhd.h
nodist_include_bsp_HEADERS = ../../shared/include/bootcard.h
nodist_include_bsp_HEADERS += irq/irq.h
DISTCLEANFILES = include/bspopts.h
noinst_PROGRAMS =
noinst_LIBRARIES = libbspstart.a
libbspstart_a_SOURCES = start/start.S
project_lib_DATA = start.$(OBJEXT)
dist_project_lib_DATA += startup/linkcmds
noinst_LIBRARIES += libbsp.a
libbsp_a_SOURCES =
include_ndsdir = $(includedir)/nds
include_nds_HEADERS = touchscreen/touchscreen.h sound/sound.h
libbsp_a_CPPFLAGS = -DARM9
libbsp_a_CPPFLAGS += -I$(srcdir)/../../shared/include
libbsp_a_CPPFLAGS += -I$(srcdir)/include
libbsp_a_CPPFLAGS += -I$(srcdir)/libnds/include
libbsp_a_CPPFLAGS += -I$(srcdir)/libfat/source/disc_io
libbsp_a_SOURCES += ../../shared/bsplibc.c
libbsp_a_SOURCES += ../../shared/bsppost.c
libbsp_a_SOURCES += startup/bspstart.c
libbsp_a_SOURCES += ../../shared/bspclean.c
libbsp_a_SOURCES += startup/bspreset.c
libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
libbsp_a_SOURCES += ../../shared/bsppredriverhook.c
libbsp_a_SOURCES += ../../shared/bootcard.c
libbsp_a_SOURCES += ../../shared/cpucounterread.c
libbsp_a_SOURCES += ../../shared/cpucounterdiff.c
libbsp_a_SOURCES += ../../shared/gnatinstallhandler.c
libbsp_a_SOURCES += clock/clock.c
libbsp_a_SOURCES += ../../shared/clockdrv_shell.h
libbsp_a_SOURCES += rtc/rtc.c
libbsp_a_SOURCES += ../../shared/tod.c
libbsp_a_SOURCES += console/console.c
libbsp_a_SOURCES += fb/fb.c
libbsp_a_SOURCES += touchscreen/touchscreen.c
libbsp_a_SOURCES += touchscreen/parser.c
libbsp_a_SOURCES += touchscreen/reco.c
libbsp_a_SOURCES += timer/timer.c
libbsp_a_SOURCES += sound/sound.c
libbsp_a_SOURCES += block/block.c
libbsp_a_SOURCES += irq/irq.c
# Cache
libbsp_a_SOURCES += ../../../libcpu/shared/src/cache_manager.c
libbsp_a_SOURCES += ../../shared/include/cache_.h
if HAS_NETWORKING
noinst_PROGRAMS += wifi.rel
wifi_rel_SOURCES = wifi/wifi.c wifi/compat.c
wifi_rel_CPPFLAGS = $(AM_CPPFLAGS) -DARM9 -I$(srcdir)/dswifi/include -I$(srcdir)/libnds/include -I$(srcdir)/dswifi/include -D_KERNEL -D__BSD_VISIBLE
wifi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
# libnds, ARM9 side
noinst_PROGRAMS += libnds9.rel
bin2s: $(srcdir)/tools/bin2s.c
cc -o $(srcdir)/tools/bin2s $(srcdir)/tools/bin2s.c
SUFFIXES = .bin
%.s: %.bin bin2s
$(srcdir)/tools/bin2s $< > $(srcdir)/$@
libnds9_rel_SOURCES = libnds/source/common/biosCalls.S \
libnds/source/common/card.c \
libnds/source/common/gbfs.c \
libnds/source/common/interruptDispatcher.S \
libnds/source/common/interrupts.c \
libnds/source/arm9/boxtest.c \
libnds/source/arm9/default_font.S \
libnds/source/arm9/console.c \
libnds/source/arm9/COS.S \
libnds/source/arm9/dcache.S \
libnds/source/arm9/exceptionHandler.S \
libnds/source/arm9/exceptions.c \
libnds/source/arm9/gurumeditation.c \
libnds/source/arm9/icache.S \
libnds/source/arm9/image.c \
libnds/source/arm9/initSystem.c \
libnds/source/arm9/keys.c \
libnds/source/arm9/ndsmotion.c \
libnds/source/arm9/pcx.c \
libnds/source/arm9/rumble.c \
libnds/source/arm9/SIN.S \
libnds/source/arm9/sound.c \
libnds/source/arm9/system.c \
libnds/source/arm9/TAN.S \
libnds/source/arm9/touch.c \
libnds/source/arm9/video.c \
libnds/source/arm9/videoGL.c
libnds9_rel_CPPFLAGS = $(AM_CPPFLAGS) -DARM9 -I$(srcdir)/libnds/include -I$(srcdir)/include
libnds9_rel_CCASFLAGS = $(AM_CCASFLAGS) -DARM9 -I$(srcdir)/libnds/include
libnds9_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
if HAS_NETWORKING
# dswifi, ARM9 side
noinst_PROGRAMS += dswifi9.rel
dswifi9_rel_SOURCES = dswifi/arm9/source/wifi_arm9.c
dswifi9_rel_SOURCES += dswifi/common/source/spinlock.S
dswifi9_rel_CPPFLAGS = $(AM_CPPFLAGS) -DARM9 -I$(srcdir)/dswifi/include -I$(srcdir)/libnds/include -I$(srcdir)/dswifi/common/source -I$(srcdir)/wifi -D_KERNEL
dswifi9_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
# dldi
noinst_PROGRAMS += libdldi.rel
libdldi_rel_SOURCES = libfat/source/disc_io/disc.c \
libfat/source/disc_io/io_cf_common.c \
libfat/source/disc_io/io_efa2.c \
libfat/source/disc_io/io_fcsr.c \
libfat/source/disc_io/io_m3cf.c \
libfat/source/disc_io/io_m3_common.c \
libfat/source/disc_io/io_m3sd.c \
libfat/source/disc_io/io_mpcf.c \
libfat/source/disc_io/io_njsd.c \
libfat/source/disc_io/io_nmmc.c \
libfat/source/disc_io/io_sccf.c \
libfat/source/disc_io/io_sc_common.c \
libfat/source/disc_io/io_scsd.c \
libfat/source/disc_io/io_sd_common.c \
libfat/source/disc_io/io_dldi.S \
libfat/source/disc_io/io_scsd_s.S
libdldi_rel_CPPFLAGS = $(AM_CPPFLAGS) -DARM9 -I$(srcdir)/libnds/include -I$(srcdir)/libfat/source/disc_io
libdldi_rel_CCASFLAGS = $(AM_CCASFLAGS) -DARM9 -I$(srcdir)/libnds/include -I$(srcdir)/libfat/source/disc_io
libdldi_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
# libnds, ARM7 side
noinst_PROGRAMS += libnds7.rel
libnds7_rel_SOURCES = libnds/source/common/biosCalls.S \
libnds/source/common/card.c \
libnds/source/common/gbfs.c \
libnds/source/common/interruptDispatcher.S \
libnds/source/common/interrupts.c \
libnds/source/arm7/audio.c \
libnds/source/arm7/clock.c \
libnds/source/arm7/microphone.c \
libnds/source/arm7/spi.c \
libnds/source/arm7/touch.c \
libnds/source/arm7/userSettings.c
libnds7_rel_CPPFLAGS = $(AM_CPPFLAGS) -DARM7 -I$(srcdir)/libnds/include
libnds7_rel_CFLAGS = -mcpu=arm7tdmi -mfpu=vfp -mfloat-abi=soft
libnds7_rel_CCASFLAGS = -mcpu=arm7tdmi -mfpu=vfp -mfloat-abi=soft
libnds7_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
if HAS_NETWORKING
# dswifi, ARM7 side
noinst_PROGRAMS += dswifi7.rel
dswifi7_rel_SOURCES = dswifi/arm7/source/wifi_arm7.c \
dswifi/common/source/spinlock.S
dswifi7_rel_CPPFLAGS = $(AM_CPPFLAGS) -DARM7 -I$(srcdir)/dswifi/include -I$(srcdir)/libnds/include -I$(srcdir)/dswifi/common/source
dswifi7_rel_CFLAGS = -mcpu=arm7tdmi -mfpu=vfp -mfloat-abi=soft
dswifi7_rel_CCASFLAGS = -mcpu=arm7tdmi -mfpu=vfp -mfloat-abi=soft
dswifi7_rel_LDFLAGS = $(RTEMS_RELLDFLAGS)
endif
# include libnds to dist so the user program can include it
include_libndsdir = $(includedir)/libnds
include_libnds_HEADERS = libnds/include/gbfs.h \
libnds/include/nds.h
include_libndsndsdir = $(includedir)/libnds/nds
include_libndsnds_HEADERS = libnds/include/nds/memory.h \
libnds/include/nds/system.h \
libnds/include/nds/bios.h \
libnds/include/nds/registers_alt.h \
libnds/include/nds/interrupts.h \
libnds/include/nds/card.h \
libnds/include/nds/ipc.h \
libnds/include/nds/timers.h \
libnds/include/nds/dma.h \
libnds/include/nds/reload.h \
libnds/include/nds/jtypes.h
include_libndsnds9dir = $(includedir)/libnds/nds/arm9
include_libndsnds9_HEADERS = libnds/include/nds/arm9/ndsmotion.h \
libnds/include/nds/arm9/pcx.h \
libnds/include/nds/arm9/input.h \
libnds/include/nds/arm9/math.h \
libnds/include/nds/arm9/console.h \
libnds/include/nds/arm9/sprite.h \
libnds/include/nds/arm9/videoGL.h \
libnds/include/nds/arm9/cache.h \
libnds/include/nds/arm9/image.h \
libnds/include/nds/arm9/trig_lut.h \
libnds/include/nds/arm9/video.h \
libnds/include/nds/arm9/exceptions.h \
libnds/include/nds/arm9/rumble.h \
libnds/include/nds/arm9/background.h \
libnds/include/nds/arm9/boxtest.h \
libnds/include/nds/arm9/postest.h \
libnds/include/nds/arm9/sound.h
include_libndsnds7dir = $(includedir)/libnds/nds/arm7
include_libndsnds7_HEADERS = libnds/include/nds/arm7/serial.h \
libnds/include/nds/arm7/audio.h \
libnds/include/nds/arm7/clock.h \
libnds/include/nds/arm7/touch.h
EXTRA_DIST = coproc/coproc.S coproc/coproc.c
if HAS_NETWORKING
coproc.bin: coproc/coproc.S coproc/coproc.c libnds7.rel dswifi7.rel
@CC@ -o coproc.elf -mcpu=arm7tdmi -mfpu=vfp -mfloat-abi=soft -O2 -DARM7 -I$(srcdir)/libnds/include -I$(srcdir)/dswifi/include -DENABLE_WIFI -T $(srcdir)/coproc/coproc.ld $^ -lc
$(OBJCOPY) -O binary coproc.elf coproc.bin
else
coproc.bin: coproc/coproc.S coproc/coproc.c libnds7.rel
@CC@ -o coproc.elf -mcpu=arm7tdmi -mfpu=vfp -mfloat-abi=soft -O2 -DARM7 -I$(srcdir)/libnds/include -T $(srcdir)/coproc/coproc.ld $^ -lc
$(OBJCOPY) -O binary coproc.elf coproc.bin
endif
project_lib_DATA += coproc.bin
libbsp_a_LIBADD = libnds9.rel libdldi.rel
if HAS_NETWORKING
libbsp_a_LIBADD += wifi.rel dswifi9.rel
endif
include $(srcdir)/preinstall.am
include $(top_srcdir)/../../../../automake/local.am
-8
View File
@@ -1,8 +0,0 @@
This is the BSP for Nintendo DS.
Original authors:
* Matthieu Bucchianeri <mbucchia@gmail.com>
* Benjamin Ratier
* Renaud Voltz
* Cedric Gestes
-115
View File
@@ -1,115 +0,0 @@
/*
* RTEMS for Nintendo DS flash driver.
*/
/*
* Copyright (c) 2008 by Matthieu Bucchianeri <mbucchia@gmail.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE
*/
#include <rtems.h>
#include <bsp.h>
#include <libchip/ide_ctrl.h>
#include <libchip/ide_ctrl_cfg.h>
#include <libchip/ide_ctrl_io.h>
#include <disc.h>
static bool
nds_flash_probe (int minor)
{
return true;
}
static void
nds_flash_initialize (int minor)
{
const IO_INTERFACE *flash;
printk ("[+] flash started\n");
flash = _FAT_disc_dsSlotFindInterface ();
if (flash == NULL) {
printk ("[!] error getting device\n");
rtems_fatal_error_occurred (0);
}
if (_FAT_disc_isInserted (flash)) {
printk ("[#] flash inserted\n");
} else {
printk ("[!] flash not inserted\n");
}
}
static void
nds_flash_read_reg (int minor, int reg, uint16_t * value)
{
printk ("nds_flash_read_reg\n");
}
static void
nds_flash_write_reg (int minor, int reg, uint16_t value)
{
printk ("nds_flash_write_reg\n");
}
static void
nds_flash_read_block (int minor, uint32_t block_size,
rtems_blkdev_sg_buffer * bufs,
uint32_t * cbuf, uint32_t * pos)
{
printk ("nds_flash_read_block\n");
}
static void
nds_flash_write_block (int minor, uint32_t block_size,
rtems_blkdev_sg_buffer * bufs,
uint32_t * cbuf, uint32_t * pos)
{
printk ("nds_flash_write_block\n");
}
static int
nds_flash_control (int minor, uint32_t cmd, void *arg)
{
printk ("nds_flash_control\n");
return 0;
}
static rtems_status_code
nds_flash_io_speed (int minor, uint16_t mode)
{
return RTEMS_SUCCESSFUL;
}
ide_ctrl_fns_t nds_flash_ctrl_fns = {
nds_flash_probe,
nds_flash_initialize,
nds_flash_control,
nds_flash_read_reg,
nds_flash_write_reg,
nds_flash_read_block,
nds_flash_write_block,
nds_flash_io_speed
};
/* IDE controllers Table */
ide_controller_bsp_table_t IDE_Controller_Table[] = {
{
"/dev/flash",
IDE_CUSTOM, /* standard IDE controller */
&nds_flash_ctrl_fns,
NULL, /* probe for IDE standard registers */
FALSE, /* not (yet) initialized */
0x0, /* base I/O address for first IDE controller */
FALSE, 0, /* not (yet) interrupt driven */
NULL
}
};
/* Number of rows in IDE_Controller_Table */
unsigned long IDE_Controller_Count = 1;
-13
View File
@@ -1,13 +0,0 @@
%rename endfile old_endfile
%rename startfile old_startfile
%rename link old_link
*startfile:
%{!qrtems: %(old_startfile)} \
%{!nostdlib: %{qrtems: start.o%s crti.o%s crtbegin.o%s -e _start}}
*link:
%{!qrtems: %(old_link)} %{qrtems: -dc -dp -N}
*endfile:
%{!qrtems: %(old_endfiles)} %{qrtems: crtend.o%s crtn.o%s }
-86
View File
@@ -1,86 +0,0 @@
/**
* @file
*
* RTEMS for Nintendo DS clock driver.
*/
/*
* Copyright (c) 2008 by Matthieu Bucchianeri <mbucchia@gmail.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.org/license/LICENSE
*/
#include <rtems.h>
#include <bsp.h>
#include <rtems/irq.h>
#include <nds.h>
/*
* forward declaration for clock isr in clockdrv_shell.h
*/
void Clock_isr(rtems_irq_hdl_param arg);
/*
* forward declarations for methods in this file
*/
void Clock_driver_support_shutdown_hardware (void);
void Clock_driver_support_initialize_hardware (void);
/*
* isr registration variables.
*/
static rtems_irq_connect_data clock_isr_data = {
.name = IRQ_TIMER0,
.hdl = Clock_isr,
.handle = NULL,
.on = NULL,
.off = NULL,
.isOn = NULL,
};
void update_touchscreen (void);
/*
* function called on every ticks.
* NOTE: replaced by macro to avoid empty function call.
*/
#define Clock_driver_support_at_tick() \
update_touchscreen();
/*
* install isr for clock driver.
*/
#define Clock_driver_support_install_isr( _new, _old ) \
do { \
_old = NULL; \
BSP_install_rtems_irq_handler(&clock_isr_data); \
} while (0)
/*
* disable clock.
*/
void Clock_driver_support_shutdown_hardware (void)
{
BSP_remove_rtems_irq_handler (&clock_isr_data);
TIMER_CR (0) &= ~(TIMER_ENABLE);
}
/*
* initialize clock on timer 0.
*/
void Clock_driver_support_initialize_hardware (void)
{
uint32_t freq =
1000 / (rtems_configuration_get_microseconds_per_tick () / 1000);
printk ("[+] clock started\n");
TIMER_CR (0) = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_64;
printk ("[#] setting clock to %u hz\n", freq);
TIMER_DATA (0) = TIMER_FREQ_64 ((uint16_t) freq);
}
#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
#include "../../../shared/clockdrv_shell.h"
-26
View File
@@ -1,26 +0,0 @@
AC_PREREQ([2.69])
AC_INIT([rtems-c-src-lib-libbsp-arm-nds],[_RTEMS_VERSION],[https://devel.rtems.org/newticket])
AC_CONFIG_SRCDIR([bsp_specs])
RTEMS_TOP(../../../../../..)
RTEMS_CANONICAL_TARGET_CPU
AM_INIT_AUTOMAKE([no-define nostdinc foreign 1.12.2])
RTEMS_BSP_CONFIGURE
RTEMS_PROG_CC_FOR_TARGET
RTEMS_CANONICALIZE_TOOLS
RTEMS_CHECK_TOOL(OBJCOPY,objcopy,:)
RTEMS_PROG_CCAS
RTEMS_CONFIG_BUILD_SUBDIRS(tools)
## $srcdir/mk_libnds.sh $srcdir
RTEMS_CHECK_NETWORKING
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
RTEMS_BSP_CLEANUP_OPTIONS(1, 1)
# Explicitly list all Makefiles here
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
-191
View File
@@ -1,191 +0,0 @@
/*
* RTEMS for Nintendo DS console driver.
*
* Copyright (c) 2008 by Renaud Voltz <renaud.voltz@gmail.com>
* Matthieu Bucchianeri <mbucchia@gmail.com>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
*
* http://www.rtems.org/license/LICENSE
*/
#include <bsp.h>
#include <nds.h>
#include <rtems/libio.h>
#include <nds/arm9/console.h>
#include <sys/iosupport.h>
#include <rtems/mw_uid.h>
/*
* enables testsuite output to desmume. this is used to pass the rtems
* testsuite.
* comment the following line to disable (recommended).
*/
//#define TESTSUITE
/*
* printk support.
*/
/* from NDS support library */
extern void consolePrintChar(char c);
static void
nds_putch (char c)
{
#ifdef TESTSUITE
__asm__ volatile ("swi $0x1");
#endif
consolePrintChar (c);
}
static volatile char ch = 0;
void console_push (char c); /* used in touchscreen.c */
void
console_push (char c)
{
ch = c;
}
static int
nds_getch (void)
{
char c;
while (ch == 0);
c = ch;
ch = 0;
return c;
}
BSP_output_char_function_type BSP_output_char = nds_putch;
BSP_polling_getchar_function_type BSP_poll_char = nds_getch;
/*
* console write operation.
*/
static ssize_t
nds_write (int minor, const char *buf, size_t len)
{
int count;
for (count = 0; count < len; count++) {
nds_putch (buf[count]);
}
return 0;
}
/*
* console read operation.
*/
static int
nds_read (int minor)
{
return nds_getch ();
}
/*
* from touchscreen/parser.c
*/
void register_kbd_msg_queue (char *q_name);
void unregister_kbd_msg_queue (void);
/*
* Console driver
*/
rtems_device_driver
console_initialize (rtems_device_major_number major,
rtems_device_minor_number minor, void *arg)
{
rtems_status_code status;
printk ("[+] console started\n");
rtems_termios_initialize ();
status = rtems_io_register_name ("/dev/console", major, 0);
if (status != RTEMS_SUCCESSFUL) {
printk ("[!] error registering console\n");
rtems_fatal_error_occurred (status);
}
return (RTEMS_SUCCESSFUL);
}
rtems_device_driver
console_open (rtems_device_major_number major,
rtems_device_minor_number minor, void *arg)
{
rtems_status_code status;
static rtems_termios_callbacks cb = {
NULL, /* firstOpen */
NULL, /* lastClose */
nds_read, /* pollRead */
nds_write, /* write */
NULL, /* setAttributes */
NULL, /* stopRemoteTx */
NULL, /* startRemoteTx */
0 /* 1 = outputUsesInterrupts */
};
status = rtems_termios_open (major, minor, arg, &cb);
if (status != RTEMS_SUCCESSFUL)
printk ("[!] error opening console\n");
return (status);
}
rtems_device_driver
console_close (rtems_device_major_number major,
rtems_device_minor_number minor, void *arg)
{
rtems_device_driver res = RTEMS_SUCCESSFUL;
res = rtems_termios_close (arg);
return res;
}
rtems_device_driver
console_read (rtems_device_major_number major,
rtems_device_minor_number minor, void *arg)
{
return rtems_termios_read (arg);
}
rtems_device_driver
console_write (rtems_device_major_number major,
rtems_device_minor_number minor, void *arg)
{
return rtems_termios_write (arg);
}
rtems_device_driver
console_control (rtems_device_major_number major,
rtems_device_minor_number minor, void *arg)
{
rtems_libio_ioctl_args_t *args = arg;
switch (args->command) {
case MW_UID_REGISTER_DEVICE:
register_kbd_msg_queue (args->buffer);
break;
case MW_UID_UNREGISTER_DEVICE:
unregister_kbd_msg_queue ();
break;
default:
return rtems_termios_ioctl (arg);
}
args->ioctl_return = 0;
return RTEMS_SUCCESSFUL;
}
-112
View File
@@ -1,112 +0,0 @@
@---------------------------------------------------------------------------------
.section ".init"
.global _start
.global _init
@---------------------------------------------------------------------------------
.align 4
.arm
@---------------------------------------------------------------------------------
_start:
@---------------------------------------------------------------------------------
mov r0, #0x04000000 @ IME = 0;
str r0, [r0, #0x208]
mov r0, #0x12 @ Switch to IRQ Mode
msr cpsr, r0
ldr sp, =__sp_irq @ Set IRQ stack
mov r0, #0x13 @ Switch to SVC Mode
msr cpsr, r0
ldr sp, =__sp_svc @ Set SVC stack
mov r0, #0x1F @ Switch to System Mode
msr cpsr, r0
ldr sp, =__sp_usr @ Set user stack
ldr r0, =__bss_start @ Clear BSS section to 0x00
ldr r1, =__bss_end
sub r1, r1, r0
bl ClearMem
ldr r3, =__libc_init_array @ global constructors
bl _call_via_r3
mov r0, #0 @ int argc
mov r1, #0 @ char *argv[]
ldr r3, =main
bl _call_via_r3 @ jump to user code
@ If the user ever returns, return to flash cartridge
mov r0, #0x08000000
bx r0
@---------------------------------------------------------------------------------
@ Clear memory to 0x00 if length != 0
@ r0 = Start Address
@ r1 = Length
@---------------------------------------------------------------------------------
ClearMem:
@---------------------------------------------------------------------------------
mov r2, #3 @ Round down to nearest word boundary
add r1, r1, r2 @ Shouldn't be needed
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
bxeq lr @ Quit if copy size is 0
mov r2, #0
ClrLoop:
stmia r0!, {r2}
subs r1, r1, #4
bne ClrLoop
bx lr
@---------------------------------------------------------------------------------
@ Copy memory if length != 0
@ r1 = Source Address
@ r2 = Dest Address
@ r4 = Dest Address + Length
@---------------------------------------------------------------------------------
CopyMemCheck:
@---------------------------------------------------------------------------------
sub r3, r4, r2 @ Is there any data to copy?
@---------------------------------------------------------------------------------
@ Copy memory
@ r1 = Source Address
@ r2 = Dest Address
@ r3 = Length
@---------------------------------------------------------------------------------
CopyMem:
@---------------------------------------------------------------------------------
mov r0, #3 @ These commands are used in cases where
add r3, r3, r0 @ the length is not a multiple of 4,
bics r3, r3, r0 @ even though it should be.
bxeq lr @ Length is zero, so exit
CIDLoop:
ldmia r1!, {r0}
stmia r2!, {r0}
subs r3, r3, #4
bne CIDLoop
bx lr
_init:
bx lr
@---------------------------------------------------------------------------------
.align
@ .pool
@ .end
@---------------------------------------------------------------------------------
@---------------------------------------------------------------------------------
.section ".fini"
.global _fini
@---------------------------------------------------------------------------------
.align 4
.arm
@---------------------------------------------------------------------------------
_fini:
bx lr
@---------------------------------------------------------------------------------
.align
.pool
.end
@---------------------------------------------------------------------------------
-207
View File
@@ -1,207 +0,0 @@
/*---------------------------------------------------------------------------------
default ARM7 core
Copyright (C) 2005
Michael Noland (joat)
Jason Rogers (dovoto)
Dave Murphy (WinterMute)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
---------------------------------------------------------------------------------*/
#include <nds.h>
#include "../include/my_ipc.h"
#ifdef ENABLE_WIFI
#include <dswifi7.h>
#endif
//---------------------------------------------------------------------------------
void startSound(int sampleRate, const void* data, u32 bytes, u8 channel, u8 vol, u8 pan, u8 format) {
//---------------------------------------------------------------------------------
SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate);
SCHANNEL_SOURCE(channel) = (u32)data;
SCHANNEL_LENGTH(channel) = bytes >> 2 ;
SCHANNEL_CR(channel) = SCHANNEL_ENABLE | SOUND_ONE_SHOT | SOUND_VOL(vol) | SOUND_PAN(pan) | (format==1?SOUND_8BIT:SOUND_16BIT);
}
//---------------------------------------------------------------------------------
s32 getFreeSoundChannel() {
//---------------------------------------------------------------------------------
int i;
for (i=0; i<16; i++) {
if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 ) return i;
}
return -1;
}
touchPosition first,tempPos;
//---------------------------------------------------------------------------------
void VcountHandler() {
//---------------------------------------------------------------------------------
static int lastbut = -1;
uint16 but=0, x=0, y=0, xpx=0, ypx=0, z1=0, z2=0;
but = REG_KEYXY;
if (!( (but ^ lastbut) & (1<<6))) {
tempPos = touchReadXY();
if ( tempPos.x == 0 || tempPos.y == 0 ) {
but |= (1 <<6);
lastbut = but;
} else {
x = tempPos.x;
y = tempPos.y;
xpx = tempPos.px;
ypx = tempPos.py;
z1 = tempPos.z1;
z2 = tempPos.z2;
}
} else {
lastbut = but;
but |= (1 <<6);
}
IPC->touchX = x;
IPC->touchY = y;
IPC->touchXpx = xpx;
IPC->touchYpx = ypx;
IPC->touchZ1 = z1;
IPC->touchZ2 = z2;
IPC->buttons = but;
}
//---------------------------------------------------------------------------------
void VblankHandler(void) {
//---------------------------------------------------------------------------------
static u8 is_recording = 0;
u32 i;
//sound code :)
TransferSound *snd = IPC->soundData;
IPC->soundData = 0;
if (0 != snd) {
for (i=0; i<snd->count; i++) {
s32 chan = getFreeSoundChannel();
if (chan >= 0) {
startSound(snd->data[i].rate, snd->data[i].data, snd->data[i].len, chan, snd->data[i].vol, snd->data[i].pan, snd->data[i].format);
}
}
}
// microphone code
if (!is_recording && my_IPC->record)
{
StartRecording((u8 *)my_IPC->record_buffer, my_IPC->record_length_max);
is_recording = 1;
}
if (is_recording && !my_IPC->record)
{
my_IPC->recorded_length = 1 + StopRecording();
is_recording = 0;
}
#ifdef ENABLE_WIFI
Wifi_Update(); // update wireless in vblank
#endif
}
#ifdef ENABLE_WIFI
// callback to allow wifi library to notify arm9
void arm7_synctoarm9() { // send fifo message
REG_IPC_FIFO_TX = 0x87654321;
}
// interrupt handler to allow incoming notifications from arm9
void arm7_fifo() { // check incoming fifo messages
u32 msg = REG_IPC_FIFO_RX;
if(msg==0x87654321) Wifi_Sync();
}
#endif
//---------------------------------------------------------------------------------
int main(int argc, char ** argv) {
//---------------------------------------------------------------------------------
#ifdef ENABLE_WIFI
REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; // enable & prepare
// fifo asap
#endif
// read User Settings from firmware
readUserSettings();
//enable sound
powerON(POWER_SOUND);
writePowerManagement(PM_CONTROL_REG, ( readPowerManagement(PM_CONTROL_REG) & ~PM_SOUND_MUTE ) | PM_SOUND_AMP );
SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F);
irqInit();
// Start the RTC tracking IRQ
initClockIRQ();
SetYtrigger(80);
irqSet(IRQ_VCOUNT, VcountHandler);
irqSet(IRQ_VBLANK, VblankHandler);
irqSet(IRQ_TIMER0, ProcessMicrophoneTimerIRQ);
irqEnable(IRQ_VBLANK | IRQ_VCOUNT | IRQ_TIMER0);
#ifdef ENABLE_WIFI
irqSet(IRQ_WIFI, Wifi_Interrupt); // set up wifi interrupt
irqEnable(IRQ_WIFI);
// sync with arm9 and init wifi
u32 fifo_temp;
while (1)
{ // wait for magic number
while (REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY)
swiWaitForVBlank();
fifo_temp = REG_IPC_FIFO_RX;
if (fifo_temp == 0x12345678)
break;
}
while (REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY)
swiWaitForVBlank();
fifo_temp = REG_IPC_FIFO_RX;
Wifi_Init(fifo_temp);
irqSet(IRQ_FIFO_NOT_EMPTY,arm7_fifo); // set up fifo irq
irqEnable(IRQ_FIFO_NOT_EMPTY);
REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ;
Wifi_SetSyncHandler(arm7_synctoarm9); // allow wifi lib to notify arm9
#endif
// Keep the ARM7 mostly idle
while (1) {
swiWaitForVBlank();
}
}
-195
View File
@@ -1,195 +0,0 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
MEMORY {
rom : ORIGIN = 0x08000000, LENGTH = 32M
iwram : ORIGIN = 0x037f8000, LENGTH = 96K
}
__iwram_start = ORIGIN(iwram);
__iwram_top = ORIGIN(iwram)+ LENGTH(iwram);
__sp_irq = __iwram_top - 0x60;
__sp_svc = __sp_irq - 0x100;
__sp_usr = __sp_svc - 0x100;
__irq_flags = __iwram_top - 8;
__irq_vector = __iwram_top - 4;
SECTIONS
{
.init :
{
__text_start = . ;
KEEP (*(.init))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram = 0xff
.plt : { *(.plt) } >iwram = 0xff
.text : /* ALIGN (4): */
{
*(.text*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram = 0xff
.fini :
{
KEEP (*(.fini))
} >iwram =0xff
__text_end = . ;
.rodata :
{
*(.rodata)
*all.rodata*(*)
*(.roda)
*(.rodata.*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram = 0xff
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >iwram
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >iwram
__exidx_end = .;
/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { KEEP (*(.preinit_array)) } >iwram = 0xff
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { KEEP (*(.init_array)) } >iwram = 0xff
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { KEEP (*(.fini_array)) } >iwram = 0xff
PROVIDE (__fini_array_end = .);
.ctors :
{
/* gcc uses crtbegin.o to find the start of the constructors, so
we make sure it is first. Because this is a wildcard, it
doesn't matter if the user does not actually link against
crtbegin.o; the linker won't look for a file to match a
wildcard. The wildcard also means that it doesn't matter which
directory crtbegin.o is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram = 0xff
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram = 0xff
.eh_frame :
{
KEEP (*(.eh_frame))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram = 0xff
.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram = 0xff
.jcr : { KEEP (*(.jcr)) } >iwram = 0
.got : { *(.got.plt) *(.got) } >iwram = 0
.iwram ALIGN(4) :
{
__iwram_start = ABSOLUTE(.) ;
*(.iwram)
*iwram.*(.text)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
__iwram_end = ABSOLUTE(.) ;
} >iwram = 0xff
.data ALIGN(4) : {
__data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
. = ALIGN(4);
__data_end = ABSOLUTE(.) ;
} >iwram = 0xff
.bss ALIGN(4) :
{
__bss_start = ABSOLUTE(.);
__bss_start__ = ABSOLUTE(.);
*(.dynbss)
*(.gnu.linkonce.b*)
*(.bss*)
*(COMMON)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >iwram
__bss_end = . ;
__bss_end__ = . ;
_end = . ;
__end__ = . ;
PROVIDE (end = _end);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.stack 0x80000 : { _stack = .; *(.stack) }
/* These must appear regardless of . */
}
@@ -1,145 +0,0 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
endif
include $(DEVKITARM)/ds_rules
TOPDIR ?= $(CURDIR)/..
#---------------------------------------------------------------------------------
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files
# all directories are relative to this makefile
#---------------------------------------------------------------------------------
BUILD ?= release
SOURCES := source ../common/source
INCLUDES := include build ../common/source ../include
DATA :=
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -mthumb-interwork
CFLAGS := -g -Wall -O2\
-mcpu=arm7tdmi -mtune=arm7tdmi -mfpu=vfp -mfloat-abi=soft -fomit-frame-pointer\
-ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM7
CXXFLAGS := $(CFLAGS)
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm7.specs -g $(ARCH) -mno-fpu -Wl,-Map,$(notdir $*).map
ifneq ($(BUILD),debug)
export ARM7BIN := $(TOPDIR)/lib/libdswifi7.a
else
export ARM7BIN := $(TOPDIR)/lib/libdswifi7d.a
CFLAGS += -DSGIP_DEBUG
endif
LIBS :=
#-lnds7
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir))
export CC := $(PREFIX)gcc
export CXX := $(PREFIX)g++
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr debug release
@rm -f $(TOPDIR)/lib/libdswifi7*
all: $(ARM7BIN)
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(ARM7BIN) : $(OFILES)
@rm -f "$(ARM7BIN)"
@$(AR) rcs "$(ARM7BIN)" $(OFILES)
@echo built ... $(notdir $@)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
File diff suppressed because it is too large Load Diff
@@ -1,136 +0,0 @@
// DS Wifi interface code
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
// wifi_arm7.h - arm7 wifi interface header
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef WIFI_ARM7_H
#define WIFI_ARM7_H
#ifndef ARM7
#error Wifi is only accessible from the ARM7
#endif
// keepalive updated in the update handler, which should be called in vblank
// keepalive set for 2 minutes.
#define WIFI_KEEPALIVE_COUNT (60*60*2)
#define WIFI_REG(ofs) (*((volatile u16 *)(0x04800000+(ofs))))
// Wifi regs
#define W_WEPKEY0 (((volatile u16 *)(0x04805F80)))
#define W_WEPKEY1 (((volatile u16 *)(0x04805FA0)))
#define W_WEPKEY2 (((volatile u16 *)(0x04805FC0)))
#define W_WEPKEY3 (((volatile u16 *)(0x04805FE0)))
#define W_MODE_RST (*((volatile u16 *)(0x04800004)))
#define W_MODE_WEP (*((volatile u16 *)(0x04800006)))
#define W_IF (*((volatile u16 *)(0x04800010)))
#define W_IE (*((volatile u16 *)(0x04800012)))
#define W_MACADDR (((volatile u16 *)(0x04800018)))
#define W_BSSID (((volatile u16 *)(0x04800020)))
#define W_AIDS (*((volatile u16 *)(0x04800028)))
#define W_RETRLIMIT (*((volatile u16 *)(0x0480002C)))
#define W_POWERSTATE (*((volatile u16 *)(0x0480003C)))
#define W_RANDOM (*((volatile u16 *)(0x04800044)))
#define W_BBSIOCNT (*((volatile u16 *)(0x04800158)))
#define W_BBSIOWRITE (*((volatile u16 *)(0x0480015A)))
#define W_BBSIOREAD (*((volatile u16 *)(0x0480015C)))
#define W_BBSIOBUSY (*((volatile u16 *)(0x0480015E)))
#define W_RFSIODATA2 (*((volatile u16 *)(0x0480017C)))
#define W_RFSIODATA1 (*((volatile u16 *)(0x0480017E)))
#define W_RFSIOBUSY (*((volatile u16 *)(0x04800180)))
#include "wifi_shared.h"
extern volatile Wifi_MainStruct * WifiData;
// Wifi Sync Handler function: Callback function that is called when the arm9 needs to be told to synchronize with new fifo data.
// If this callback is used (see Wifi_SetSyncHandler()), it should send a message via the fifo to the arm9, which will call Wifi_Sync() on arm9.
typedef void (*WifiSyncHandler)(void);
#ifdef __cplusplus
extern "C" {
#endif
extern void Read_Flash(int address, char * destination, int length);
extern void InitFlashData(void);
extern int ReadFlashByte(int address);
extern int ReadFlashHWord(int address);
extern int ReadFlashBytes(int address, int numbytes);
extern int Wifi_BBRead(int a);
extern int Wifi_BBWrite(int a, int b);
extern void Wifi_RFWrite(int writedata);
extern void Wifi_RFInit(void);
extern void Wifi_BBInit(void);
extern void Wifi_WakeUp(void);
extern void Wifi_Shutdown(void);
extern void Wifi_MacInit(void);
extern void Wifi_Interrupt(void);
extern void Wifi_Update(void);
extern void Wifi_CopyMacAddr(volatile void * dest, volatile void * src);
extern int Wifi_CmpMacAddr(volatile void * mac1, volatile void * mac2);
extern void Wifi_Init(u32 WifiData);
extern void Wifi_Deinit(void);
extern void Wifi_Start(void);
extern void Wifi_Stop(void);
extern void Wifi_SetChannel(int channel);
extern void Wifi_SetWepKey(void * wepkey);
extern void Wifi_SetWepMode(int wepmode);
extern void Wifi_SetBeaconPeriod(int beacon_period);
extern void Wifi_SetMode(int wifimode);
extern void Wifi_SetPreambleType(int preamble_type);
extern void Wifi_TxSetup(void);
extern void Wifi_RxSetup(void);
extern void Wifi_DisableTempPowerSave(void);
extern int Wifi_SendOpenSystemAuthPacket(void);
extern int Wifi_SendAssocPacket(void);
extern int Wifi_SendNullFrame(void);
extern int Wifi_SendPSPollFrame(void);
extern int Wifi_ProcessReceivedFrame(int macbase, int framelen);
extern void Wifi_Sync(void);
extern void Wifi_SetSyncHandler(WifiSyncHandler sh);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,150 +0,0 @@
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
endif
include $(DEVKITARM)/ds_rules
TOPDIR ?= $(CURDIR)/..
#---------------------------------------------------------------------------------
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# DATA is a list of directories containing binary files
# all directories are relative to this makefile
#---------------------------------------------------------------------------------
BUILD ?= release
SOURCES := source ../common/source
INCLUDES := include ../common/source ../include
DATA := data
#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH := -mthumb -mthumb-interwork -fno-schedule-insns2
# note: arm9tdmi isn't the correct CPU arch, but anything newer and LD
# *insists* it has a FPU or VFP, and it won't take no for an answer!
CFLAGS := -g -Wall -O2\
-mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer\
-ffast-math \
$(ARCH)
CFLAGS += $(INCLUDE) -DARM9
CXXFLAGS := $(CFLAGS)
ASFLAGS := -g $(ARCH)
LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -mno-fpu -Wl,-Map,$(notdir $*.map)
ifneq ($(BUILD),debug)
export ARM9BIN := $(TOPDIR)/lib/libdswifi9.a
else
export ARM9BIN := $(TOPDIR)/lib/libdswifi9d.a
CFLAGS += -DSGIP_DEBUG
endif
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS :=
#-lnds9
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS := $(LIBNDS)
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export DEPSDIR := $(CURDIR)/$(BUILD)
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
export CC := $(PREFIX)gcc
export CXX := $(PREFIX)g++
export AR := $(PREFIX)ar
export OBJCOPY := $(PREFIX)objcopy
CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
export LD := $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
export LD := $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------
export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
-I$(CURDIR)/$(BUILD)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
.PHONY: $(BUILD) clean
#---------------------------------------------------------------------------------
$(BUILD):
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/makefile
#---------------------------------------------------------------------------------
clean:
@echo clean ...
@rm -fr debug release
@rm -f $(TOPDIR)/lib/libdswifi9*
all: $(ARM9BIN)
#---------------------------------------------------------------------------------
else
DEPENDS := $(OFILES:.o=.d)
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(ARM9BIN) : $(OFILES)
@rm -f "$(ARM9BIN)"
@$(AR) rcs "$(ARM9BIN)" $(OFILES)
@echo built ... $(notdir $@)
#---------------------------------------------------------------------------------
# you need a rule like this for each extension you use as binary data
#---------------------------------------------------------------------------------
%.bin.o : %.bin
#---------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------
@@ -1,63 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP.h"
unsigned long volatile sgIP_timems;
int sgIP_errno;
// sgIP_Init(): Initializes sgIP hub and sets up a default surrounding interface (ARP and IP)
void sgIP_Init() {
sgIP_timems = 0;
sgIP_memblock_Init();
sgIP_Hub_Init();
sgIP_ARP_Init();
sgIP_TCP_Init();
sgIP_UDP_Init();
sgIP_DNS_Init();
sgIP_DHCP_Init();
sgIP_Hub_AddProtocolInterface(PROTOCOL_ETHER_IP,&sgIP_IP_ReceivePacket,0);
}
unsigned long count_100ms;
unsigned long count_1000ms;
void sgIP_Timer(int num_ms) {
sgIP_timems+=num_ms;
count_100ms+=num_ms;
if(count_100ms>=100) {
count_100ms-=100;
if(count_100ms>=100) count_100ms=0;
sgIP_ARP_Timer100ms();
}
count_1000ms+=num_ms;
if(count_1000ms>=1000) {
count_1000ms-=1000;
if(count_1000ms>=1000) count_1000ms=0;
sgIP_DNS_Timer1000ms();
}
sgIP_TCP_Timer();
}
@@ -1,56 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_H
#define SGIP_H
#include "sgIP_Config.h"
#include "sgIP_memblock.h"
#include "sgIP_Hub.h"
#include "sgIP_IP.h"
#include "sgIP_ARP.h"
#include "sgIP_ICMP.h"
#include "sgIP_TCP.h"
#include "sgIP_UDP.h"
#include "sgIP_DNS.h"
#include "sgIP_DHCP.h"
extern unsigned long volatile sgIP_timems;
#ifdef __cplusplus
extern "C" {
#endif
void sgIP_Init(void);
void sgIP_Timer(int num_ms);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,304 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_ARP.h"
sgIP_ARP_Record ArpRecords[SGIP_ARP_MAXENTRIES];
int sgIP_FindArpSlot(sgIP_Hub_HWInterface * hw, unsigned long destip) {
int i;
for(i=0;i<SGIP_ARP_MAXENTRIES;i++) {
if(ArpRecords[i].flags&SGIP_ARP_FLAG_ACTIVE) {
if(ArpRecords[i].linked_interface==hw && ArpRecords[i].protocol_address==destip) return i;
}
}
return -1;
}
int sgIP_GetArpSlot() {
int i,m,midle;
m=0;
midle=0;
for(i=0;i<SGIP_ARP_MAXENTRIES;i++) {
if(ArpRecords[i].flags&SGIP_ARP_FLAG_ACTIVE) {
if(ArpRecords[i].idletime>=midle) {
midle=ArpRecords[i].idletime; m=i;
}
} else {
return i;
}
}
// this slot *was* in use, so let's fix that situation.
if(ArpRecords[m].queued_packet) sgIP_memblock_free(ArpRecords[m].queued_packet);
ArpRecords[m].flags=0;
ArpRecords[m].retrycount=0;
ArpRecords[m].idletime=0;
ArpRecords[m].queued_packet=0;
return m;
}
int sgIP_is_broadcast_address(sgIP_Hub_HWInterface * hw, unsigned long ipaddr) {
if((hw->snmask | ipaddr) == 0xFFFFFFFF) return 1;
return 0;
}
// this function will protect against malformed packets that could cause internal problems.
int sgIP_ARP_Check_isok(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb, sgIP_Header_ARP * arp) {
return 1; // doesn't do anything yet ;)
}
void sgIP_ARP_Init() {
int i;
for(i=0;i<SGIP_ARP_MAXENTRIES;i++) {
ArpRecords[i].flags=0;
ArpRecords[i].idletime=0;
ArpRecords[i].queued_packet=0;
}
}
void sgIP_ARP_Timer100ms() {
int i;
for(i=0;i<SGIP_ARP_MAXENTRIES;i++) {
if(ArpRecords[i].flags & SGIP_ARP_FLAG_ACTIVE) {
ArpRecords[i].idletime++;
if(!(ArpRecords[i].flags&SGIP_ARP_FLAG_HAVEHWADDR)) {
ArpRecords[i].retrycount++;
if(ArpRecords[i].retrycount>125) { // it's a lost cause.
if(ArpRecords[i].queued_packet) { // if there is already a queued packet, kill it.
sgIP_memblock_free(ArpRecords[i].queued_packet);
}
ArpRecords[i].flags=0;
continue;
}
if((ArpRecords[i].retrycount&7)==7) { // attempt retransmit of ARP frame.
sgIP_ARP_SendARPRequest(ArpRecords[i].linked_interface, ArpRecords[i].linked_protocol, ArpRecords[i].protocol_address);
}
}
}
}
}
void sgIP_ARP_FlushInterface(sgIP_Hub_HWInterface * hw) {
int i;
for(i=0;i<SGIP_ARP_MAXENTRIES;i++) {
if(ArpRecords[i].linked_interface==hw) ArpRecords[i].flags=0;
if(hw==0) ArpRecords[i].flags=0; // flush all interfaces
}
}
// don't *really* need to process this, but it helps.
int sgIP_ARP_ProcessIPFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb) {
return 0;
}
int sgIP_ARP_ProcessARPFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb) {
int i, j, ip;
if(!hw || !mb) return 0;
sgIP_memblock_exposeheader(mb,-14); // hide 14 bytes at the start temporarily...
// look at arp frame...
sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart;
if(!sgIP_ARP_Check_isok(hw,mb,arp)) {
sgIP_memblock_free(mb);
return 0; // error - arp header incorrect somehow.
}
sgIP_memblock_exposeheader(mb,14); // re-expose 14 bytes at the start...
if(htons(arp->opcode)==1) { // request
// requested IP
ip = arp->addresses[arp->hw_addr_len*2+4+0]+(arp->addresses[arp->hw_addr_len*2+4+1]<<8)+(arp->addresses[arp->hw_addr_len*2+4+2]<<16)+(arp->addresses[arp->hw_addr_len*2+4+3]<<24);
SGIP_DEBUG_MESSAGE(("ARP: request IP %08X",ip));
if(ip==hw->ipaddr) {// someone's asking for our info, toss them a reply.
sgIP_ARP_SendARPResponse(hw,mb);
return 0;
}
}
if(htons(arp->opcode)==2) { // response
// sender IP
ip = arp->addresses[arp->hw_addr_len+0]+(arp->addresses[arp->hw_addr_len+1]<<8)+(arp->addresses[arp->hw_addr_len+2]<<16)+(arp->addresses[arp->hw_addr_len+3]<<24);
i=sgIP_FindArpSlot(hw,ip);
if(i!=-1) { // we've been waiting for you...
for(j=0;j<arp->hw_addr_len;j++) ArpRecords[i].hw_address[j]=arp->addresses[j];
ArpRecords[i].flags|=SGIP_ARP_FLAG_HAVEHWADDR;
sgIP_memblock * mb2;
mb2=ArpRecords[i].queued_packet;
ArpRecords[i].queued_packet=0;
if(mb2) sgIP_ARP_SendProtocolFrame(hw,mb2,ArpRecords[i].linked_protocol,ip);
}
}
sgIP_memblock_free(mb);
return 0;
}
int sgIP_ARP_SendProtocolFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb, unsigned short protocol, unsigned long destaddr) {
int i,j;
int m;
sgIP_Header_Ethernet * ether;
if(!hw || !mb) return 0;
sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header
if(sgIP_is_broadcast_address(hw,destaddr)) {
// construct ethernet header
ether = (sgIP_Header_Ethernet *) mb->datastart;
for(j=0;j<6;j++) {
ether->src_mac[j] = hw->hwaddr[j];
ether->dest_mac[j]= 0xFF; // broadcast destination
}
ether->protocol=protocol;
return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
}
i=sgIP_FindArpSlot(hw,destaddr);
if(i!=-1) {
if(ArpRecords[i].flags & SGIP_ARP_FLAG_HAVEHWADDR) { // we have the adddress
ArpRecords[i].idletime=0;
// construct ethernet header
ether = (sgIP_Header_Ethernet *) mb->datastart;
for(j=0;j<6;j++) {
ether->src_mac[j] = hw->hwaddr[j];
ether->dest_mac[j]= ArpRecords[i].hw_address[j];
}
ether->protocol=protocol;
return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
} else { // we don't have the address, but are looking for it.
if(ArpRecords[i].queued_packet) { // if there is already a queued packet, reject the new one.
sgIP_memblock_free(mb);
return 0; // couldn't send.
} else {
sgIP_memblock_exposeheader(mb,-14); // re-hide ethernet header.
ArpRecords[i].queued_packet=mb; // queue packet.
ArpRecords[i].linked_protocol=protocol; // queue packet.
return 0;
}
}
}
m=sgIP_GetArpSlot(); // gets and cleans out an arp slot for us
// build new record
ArpRecords[m].flags=SGIP_ARP_FLAG_ACTIVE;
ArpRecords[m].idletime=0;
ArpRecords[m].retrycount=0;
ArpRecords[m].linked_interface=hw;
ArpRecords[m].protocol_address=destaddr;
sgIP_memblock_exposeheader(mb,-14); // re-hide ethernet header.
ArpRecords[m].queued_packet=mb;
ArpRecords[m].linked_protocol=protocol;
sgIP_ARP_SendARPRequest(hw,protocol,destaddr);
return 0; // queued, but not sent yet.
}
int sgIP_ARP_SendARPResponse(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb) {
int i;
if(!hw || !mb) return 0;
sgIP_memblock_exposeheader(mb,-14); // hide 14 bytes at the start temporarily...
// Repurpose existing ARP packet
sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart;
if(!sgIP_ARP_Check_isok(hw,mb,arp)) {
sgIP_memblock_free(mb);
return 0; // error - arp header incorrect somehow.
}
if(arp->hw_addr_len!=hw->hwaddrlen || arp->protocol_addr_len!=4) {
// eek! can't send it back in this sorry state!
sgIP_memblock_free(mb);
return 0;
}
arp->opcode=htons(2); // response
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i+4+hw->hwaddrlen]=arp->addresses[i]; // copy src hw addr
for(i=0;i<4;i++) arp->addresses[i+(hw->hwaddrlen)*2+4]=arp->addresses[i+hw->hwaddrlen];
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i]=hw->hwaddr[i];
for(i=0;i<4;i++) arp->addresses[i+(hw->hwaddrlen)]=(hw->ipaddr>>(i*8))&255;
// construct ethernet header
sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header
sgIP_Header_Ethernet * ether = (sgIP_Header_Ethernet *) mb->datastart;
for(i=0;i<6;i++) {
ether->src_mac[i] = hw->hwaddr[i];
ether->dest_mac[i]= arp->addresses[i+4+hw->hwaddrlen]; // requesting party
}
ether->protocol=htons(0x0806); // ARP protocol
// Send ethernet packet
return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
}
int sgIP_ARP_SendGratARP(sgIP_Hub_HWInterface * hw) {
int i;
if(!hw) return 0;
sgIP_memblock * mb = sgIP_memblock_alloc(SGIP_HEADER_ARP_BASESIZE+2*4 + 2*hw->hwaddrlen);
if(!mb) return 0;
// Construct ARP packet
sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart;
arp->hwspace=htons(1); // ethernet
arp->protocol=htons(0x0800);
arp->opcode=htons(2); // response
arp->hw_addr_len=hw->hwaddrlen;
arp->protocol_addr_len= 4;
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i]=hw->hwaddr[i];
for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen]=(hw->ipaddr>>(i*8))&255;
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i+4+hw->hwaddrlen]=hw->hwaddr[i];
for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen*2+4]=(hw->ipaddr>>(i*8))&255;
// construct ethernet header
sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header
sgIP_Header_Ethernet * ether = (sgIP_Header_Ethernet *) mb->datastart;
for(i=0;i<6;i++) {
ether->src_mac[i] = hw->hwaddr[i];
ether->dest_mac[i]= 0xFF; // broadcast packet
}
ether->protocol=htons(0x0806); // ARP protocol
// Send ethernet packet
return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
}
int sgIP_ARP_SendARPRequest(sgIP_Hub_HWInterface * hw, int protocol, unsigned long protocol_addr) {
int i;
if(!hw) return 0;
sgIP_memblock * mb = sgIP_memblock_alloc(SGIP_HEADER_ARP_BASESIZE+2*4 + 2*hw->hwaddrlen);
if(!mb) return 0;
// Construct ARP packet
sgIP_Header_ARP * arp = (sgIP_Header_ARP *) mb->datastart;
arp->hwspace=htons(1); // 1=ethernet
arp->protocol=(protocol);
arp->opcode=htons(1); // 1=request
arp->hw_addr_len=hw->hwaddrlen;
arp->protocol_addr_len= 4;
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i]=hw->hwaddr[i];
for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen]=(hw->ipaddr>>(i*8))&255;
for(i=0;i<hw->hwaddrlen;i++) arp->addresses[i+4+hw->hwaddrlen]=0;
for(i=0;i<4;i++) arp->addresses[i+hw->hwaddrlen*2+4]=(protocol_addr>>(i*8))&255;
// construct ethernet header
sgIP_memblock_exposeheader(mb,14); // add 14 bytes at the start for the header
sgIP_Header_Ethernet * ether = (sgIP_Header_Ethernet *) mb->datastart;
for(i=0;i<6;i++) {
ether->src_mac[i] = hw->hwaddr[i];
ether->dest_mac[i]= 0xFF; // broadcast packet
}
ether->protocol=htons(0x0806); // ARP protocol
// Send ethernet packet
return sgIP_Hub_SendRawPacket(hw,mb); // this function will free the memory block when it's done.
}
@@ -1,80 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_ARP_H
#define SGIP_ARP_H
#include "sgIP_Config.h"
#include "sgIP_memblock.h"
#include "sgIP_Hub.h"
#define SGIP_ARP_FLAG_ACTIVE 0x0001
#define SGIP_ARP_FLAG_HAVEHWADDR 0x0002
typedef struct SGIP_ARP_RECORD {
unsigned short flags, retrycount;
unsigned long idletime;
sgIP_Hub_HWInterface * linked_interface;
sgIP_memblock * queued_packet;
int linked_protocol;
unsigned long protocol_address;
char hw_address[SGIP_MAXHWADDRLEN];
} sgIP_ARP_Record;
typedef struct SGIP_HEADER_ARP {
unsigned short hwspace; // ethernet=1;
unsigned short protocol;
unsigned char hw_addr_len;
unsigned char protocol_addr_len;
unsigned short opcode; // request=1, reply=2
unsigned char addresses[8+12]; // sender HW, sender Protocol, dest HW, dest Protocol
} sgIP_Header_ARP;
#define SGIP_HEADER_ARP_BASESIZE 8
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_ARP_Init(void);
extern void sgIP_ARP_Timer100ms(void);
extern void sgIP_ARP_FlushInterface(sgIP_Hub_HWInterface * hw);
extern int sgIP_ARP_ProcessIPFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb);
extern int sgIP_ARP_ProcessARPFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb);
extern int sgIP_ARP_SendProtocolFrame(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb, unsigned short protocol, unsigned long destaddr);
extern int sgIP_ARP_SendARPResponse(sgIP_Hub_HWInterface * hw, sgIP_memblock * mb);
extern int sgIP_ARP_SendGratARP(sgIP_Hub_HWInterface * hw);
extern int sgIP_ARP_SendARPRequest(sgIP_Hub_HWInterface * hw, int protocol, unsigned long protocol_addr);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,274 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_CONFIG_H
#define SGIP_CONFIG_H
#include <errno.h>
//////////////////////////////////////////////////////////////////////////
// General options - these control the core functionality of the stack.
// SGIP_USEDYNAMICMEMORY: Allows the stack to use memory as it needs it, via malloc()/free()
// This option is extremely useful in environments where it can be used, as it prevents the
// overhead of allocating per-connection memory in advance, and allows an unlimited number
// of connections, provided the memory space. This option requires the implementation of
// two C functions, "void * sgIP_malloc(int)" and "void sgIP_free(void *)", which behave
// similarly to the malloc and free functions commonly used in C.
#define SGIP_USEDYNAMICMEMORY
// SGIP_INTERRUPT_THREADING_MODEL: Provides memory protection in a system that can allow
// multiple processing "threads" by way of interrupts. This is not required on single
// threaded systems, and not adequate on multithreaded systems, but provides a way to
// allow protection against contention on interrupt-driven systems. This option requires
// the system to implement two C functions "int sgIP_DisableInterrupts()" and additionally
// "void sgIP_RestoreInterrupts(int)" that takes as a parameter the value returned by
// sgIP_DisableInterrupts(). Interrupts are disabled upon beginning work with sensitive
// memory areas or allocation/deallocation of memory, and are restored afterwards.
#define SGIP_INTERRUPT_THREADING_MODEL
// SGIP_MULTITHREADED_THREADING_MODEL: Standard memory protection for large multithreaded
// systems, such as operating systems and the like. This kind of memory protection is
// useful for true multithreaded systems but useless in a single-threaded system and
// harmful in an interrupt-based multiprocess system.
//#define SGIP_MULTITHREADED_THREADING_MODEL
#define SGIP_LITTLEENDIAN
//////////////////////////////////////////////////////////////////////////
// Temporary memory system settings
// SGIP_MEMBLOCK_DATASIZE: This is the maximum data size contained in a single sgIP_memblock.
// for best performance ensure this value is larger than any packet that is expected to be
// received, however, in a memory-tight situation, much smaller values can be used.
#define SGIP_MEMBLOCK_DATASIZE 1600
// SGIP_MEMBLOCK_BASENUM: The starting number of memblocks that will be allocated. This is
// also the total number of memblocks that will be allocated if sgIP is not configured to use
// dynamic memory allocation.
#define SGIP_MEMBLOCK_BASENUM 12
// SGIP_MEMBLOCK_STEPNUM: In the case that all memblocks are full, and dynamic memory is
// enabled, this many additional memblocks will be allocated in an attempt to satasfy the
// memory usage demands of the stack.
#define SGIP_MEMBLOCK_STEPNUM 6
// SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL: Who cares what the other memblock defines say, let's
// Generate all memblocks by mallocing 'em.
#define SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
//////////////////////////////////////////////////////////////////////////
// Hardware layer settings
// SGIP_MAXHWADDRLEN: The maximum usable hardware address length. Ethernet is 6 bytes.
#define SGIP_MAXHWADDRLEN 8
// SGIP_MAXHWHEADER: The maximum allocated size for hardware headers.
#define SGIP_MAXHWHEADER 16
// SGIP_MTU_OVERRIDE: This is the maximum MTU that will be accepted. By default it is being
// set to 1460 bytes in order to be courteous to Ethernet and it's ridiculously low MTU.
// This value will allow you to prevent fragmentation of IP packets by not using the full
// MTU available to your network interface when the IP packet will just be sliced and diced
// at the next smaller MTU. (the stack will still use HW mtu if it's lower.)
#define SGIP_MTU_OVERRIDE 1460
//////////////////////////////////////////////////////////////////////////
// Connection settings - can be tuned to change memory usage and performance
// SGIP_TCP_STATELESS_LISTEN: Uses a technique to prevent syn-flooding from blocking listen
// ports by using all the connection blocks/memory.
#define SGIP_TCP_STATELESS_LISTEN
// SGIP_TCP_STEALTH: Only sends packets in response to connections to active ports. Doing so
// causes ports to appear not as closed, but as if the deviced does not exist when probing
// ports that are not in use.
//#define SGIP_TCP_STEALTH
// SGIP_TCP_TTL: Time-to-live value given to outgoing packets, in the absence of a reason to
// manually override this value.
#define SGIP_IP_TTL 128
// SGIP_TCPRECEIVEBUFFERLENGTH: The size (in bytes) of the receive FIFO in a TCP connection
#define SGIP_TCP_RECEIVEBUFFERLENGTH 8192
// SGIP_TCPTRANSMITBUFFERLENGTH: The size (in bytes) of the transmit FIFO in a TCP connection
#define SGIP_TCP_TRANSMITBUFFERLENGTH 8192
// SGIP_TCPOOBBUFFERLENGTH: The size (in bytes) of the receive OOB data FIFO in a TCP connection
#define SGIP_TCP_OOBBUFFERLENGTH 256
// SGIP_ARP_MAXENTRIES: The maximum number of cached ARP entries - this is defined staticly
// because it's somewhat impractical to dynamicly allocate memory for such a small structure
// (at least on most smaller systems)
#define SGIP_ARP_MAXENTRIES 32
// SGIP_HUB_MAXHWINTERFACES: The maximum number of hardware interfaces the sgIP hub will
// connect to. A hardware interface being some port (ethernet, wifi, etc) that will relay
// packets to the outside world.
#define SGIP_HUB_MAXHWINTERFACES 1
// SGIP_HUB_MAXPROTOCOLINTERFACES: The maximum number of protocol interfaces the sgIP hub will
// connect to. A protocol interface being a software handler for a certain protocol type
// (such as IP)
#define SGIP_HUB_MAXPROTOCOLINTERFACES 1
#define SGIP_TCP_FIRSTOUTGOINGPORT 40000
#define SGIP_TCP_LASTOUTGOINGPORT 65000
#define SGIP_UDP_FIRSTOUTGOINGPORT 40000
#define SGIP_UDP_LASTOUTGOINGPORT 65000
#define SGIP_TCP_GENTIMEOUTMS 6000
#define SGIP_TCP_TRANSMIT_DELAY 25
#define SGIP_TCP_TRANSMIT_IMMTHRESH 40
#define SGIP_TCP_TIMEMS_2MSL 1000*60*2
#define SGIP_TCP_MAXRETRY 7
#define SGIP_TCP_MAXSYNS 64
#define SGIP_TCP_REACK_THRESH 1000
#define SGIP_TCP_SYNRETRYMS 250
#define SGIP_TCP_GENRETRYMS 500
#define SGIP_TCP_BACKOFFMAX 6000
#define SGIP_SOCKET_MAXSOCKETS 32
//#define SGIP_SOCKET_DEFAULT_NONBLOCK 1
//////////////////////////////////////////////////////////////////////////
// DNS settings
#define SGIP_DNS_MAXRECORDSCACHE 16
#define SGIP_DNS_MAXRECORDADDRS 4
#define SGIP_DNS_MAXALIASES 4
#define SGIP_DNS_TIMEOUTMS 5000
#define SGIP_DNS_MAXRETRY 3
#define SGIP_DNS_MAXSERVERRETRY 4
//////////////////////////////////////////////////////////////////////////
#define SGIP_DHCP_ERRORTIMEOUT 45000
#define SGIP_DHCP_RESENDTIMEOUT 3000
#define SGIP_DHCP_DEFAULTHOSTNAME "NintendoDS"
#define SGIP_DHCP_CLASSNAME "sgIP 0.3"
//////////////////////////////////////////////////////////////////////////
// Static memory settings - only used if SGIP_USEDYNAMICMEMORY is NOT defined.
// SGIP_TCP_MAXCONNECTIONS: In the case dynamic memory is not used, this value gives the max
// number of TCP blocks available for inbound/outbound connections via TCP.
#define SGIP_TCP_MAXCONNECTIONS 10
//////////////////////////////////////////////////////////////////////////
// Debugging options
// SGIP_DEBUG: Enable debug logging.
// requires external function "void sgIP_dbgprint(char *, ...);"
//#define SGIP_DEBUG
#ifdef SGIP_DEBUG
#define SGIP_DEBUG_MESSAGE(param) sgIP_dbgprint param
#define SGIP_DEBUG_ERROR(param) sgIP_dbgprint param; while(1);
#else
#define SGIP_DEBUG_MESSAGE(param)
#define SGIP_DEBUG_ERROR(param)
#endif
//////////////////////////////////////////////////////////////////////////
// Error handling
extern int sgIP_errno;
#define SGIP_ERROR(a) ((errno=(a)), -1)
#define SGIP_ERROR0(a) ((errno=(a)), 0)
//////////////////////////////////////////////////////////////////////////
// Error checking
#ifdef SGIP_MULTITHREADED_THREADING_MODEL
#ifdef SGIP_INTERRUPT_THREADING_MODEL
#error SGIP_INTERRUPT_THREADING_MODEL and SGIP_MULTITHREADED_THREADING_MODEL cannot be used together!
#endif
#endif
//////////////////////////////////////////////////////////////////////////
// External option-based dependencies
#ifdef SGIP_INTERRUPT_THREADING_MODEL
#ifdef __cplusplus
extern "C" {
#endif
extern int sgIP_DisableInterrupts(void);
extern void sgIP_RestoreInterrupts(int);
extern void sgIP_IntrWaitEvent(void);
#ifdef __cplusplus
};
#endif
#define SGIP_INTR_PROTECT() \
int tIME; \
tIME=sgIP_DisableInterrupts()
#define SGIP_INTR_REPROTECT() \
tIME=sgIP_DisableInterrupts()
#define SGIP_INTR_UNPROTECT() \
sgIP_RestoreInterrupts(tIME)
#define SGIP_WAITEVENT() \
sgIP_IntrWaitEvent()
#else // !SGIP_INTERRUPT_THREADING_MODEL
#define SGIP_INTR_PROTECT()
#define SGIP_INTR_REPROTECT()
#define SGIP_INTR_UNPROTECT()
#define SGIP_WAITEVENT();
#endif // SGIP_INTERRUPT_THREADING_MODEL
#ifdef SGIP_DEBUG
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_dbgprint(char *, ...);
#ifdef __cplusplus
};
#endif
#endif // SGIP_DEBUG
#ifdef SGIP_USEDYNAMICMEMORY
#ifdef __cplusplus
extern "C" {
#endif
extern void * sgIP_malloc(int);
extern void sgIP_free(void *);
#ifdef __cplusplus
};
#endif
#endif // SGIP_USEDYNAMICMEMORY
#endif
@@ -1,375 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_DHCP.h"
#include "sgIP_DNS.h"
#include <string.h>
#include "sys/socket.h"
#include "netinet/in.h"
extern unsigned long volatile sgIP_timems;
int dhcp_socket;
char dhcp_hostname[64];
int dhcp_tid;
unsigned long dhcp_timestart, dhcp_timelastaction;
sgIP_DHCP_Packet * dhcp_p;
sgIP_Hub_HWInterface * dhcp_int;
int dhcp_optionptr;
int dhcp_requestDNS;
int dhcp_status;
int dhcp_state; // 0== send DHCPDISCOVER wait for DHCPOFFER, 1== send DHCPREQUEST wait for DHCPACK
unsigned long dhcp_rcvd_ip, dhcp_rcvd_gateway, dhcp_rcvd_snmask, dhcp_rcvd_dns[3], dhcp_serverip;
void sgIP_DHCP_Init() {
dhcp_socket=0;
dhcp_p=0;
dhcp_int=0;
dhcp_rcvd_ip=0;
strcpy(dhcp_hostname,SGIP_DHCP_DEFAULTHOSTNAME);
dhcp_status=SGIP_DHCP_STATUS_IDLE;
}
void sgIP_DHCP_SetHostName(char * s) {
strncpy(dhcp_hostname,s,63);
dhcp_hostname[63]=0;
}
int sgIP_DHCP_IsDhcpIp(unsigned long ip) { // check if the IP address was assigned via dhcp.
return ip==dhcp_rcvd_ip;
}
void sgIP_DHCP_SendDgram() {
struct sockaddr_in sain;
int len_dhcp;
sain.sin_port=htons(67); // bootp server port
sain.sin_addr.s_addr=0xFFFFFFFF; // broadcast
dhcp_p->options[dhcp_optionptr++]=0xFF; // terminate options list.
//sendto(dhcp_socket,dhcp_p,sizeof(sgIP_DHCP_Packet)-312+dhcp_optionptr,0,(struct sockaddr *)&sain,sizeof(sain));
len_dhcp = sizeof(sgIP_DHCP_Packet)-312+dhcp_optionptr;
if(len_dhcp<300) len_dhcp=300;
sendto(dhcp_socket,dhcp_p,len_dhcp,0,(struct sockaddr *)&sain,sizeof(sain));
sgIP_free(dhcp_p);
dhcp_p=0;
dhcp_timelastaction=sgIP_timems;
}
void sgIP_DHCP_BeginDgram(int dgramtype) {
int i;
if(dhcp_p) sgIP_free(dhcp_p);
dhcp_p = (sgIP_DHCP_Packet *) sgIP_malloc(sizeof(sgIP_DHCP_Packet));
if(!dhcp_p) return;
// ensure packet is zero'd.. seems to pacify some routers. malloc doesn't initialise the memory returned.
memset(dhcp_p,0,sizeof(sgIP_DHCP_Packet));
dhcp_p->op=1; // 1==BOOTREQUEST
dhcp_p->htype=1; // 1== ethernet address type
dhcp_p->hlen=6; // hardware address length
dhcp_p->hops=0; // client sets to zero
dhcp_p->xid=dhcp_tid; // DHCP transaction ID
dhcp_p->secs=(sgIP_timems-dhcp_timestart)/1000; // seconds since DHCP start
dhcp_p->flags=htons(0x0000); // top bit set = request broadcast response
dhcp_p->ciaddr=0;
dhcp_p->yiaddr=0;
dhcp_p->siaddr=0;
dhcp_p->giaddr=0;
memcpy(dhcp_p->chaddr,dhcp_int->hwaddr,6);
dhcp_optionptr=0;
dhcp_p->options[dhcp_optionptr++]=0x63;
dhcp_p->options[dhcp_optionptr++]=0x82;
dhcp_p->options[dhcp_optionptr++]=0x53;
dhcp_p->options[dhcp_optionptr++]=0x63; // 4-byte "magic cookie" (bleh!)
// add some necessary options... - by default add the dhcp message type, host name, class id, and parameter request list
dhcp_p->options[dhcp_optionptr++]=0x35; // DHCP Message type
dhcp_p->options[dhcp_optionptr++]=0x01;
dhcp_p->options[dhcp_optionptr++]=dgramtype;
dhcp_p->options[dhcp_optionptr++]=0x3D; // DHCP client identifier
dhcp_p->options[dhcp_optionptr++]=0x07; // length
dhcp_p->options[dhcp_optionptr++]=0x01; // hw type
for(i=0;i<6;i++) dhcp_p->options[dhcp_optionptr++]=dhcp_int->hwaddr[i];
dhcp_p->options[dhcp_optionptr++]=0x0C; // DHCP host name
dhcp_p->options[dhcp_optionptr++]=strlen(dhcp_hostname);
for(i=0;i<strlen(dhcp_hostname);i++) {
dhcp_p->options[dhcp_optionptr++]=dhcp_hostname[i];
}
dhcp_p->options[dhcp_optionptr++]=0x37; // DHCP Parameter request list
dhcp_p->options[dhcp_optionptr++]=2+dhcp_requestDNS;
dhcp_p->options[dhcp_optionptr++]=1; // subnet mask
dhcp_p->options[dhcp_optionptr++]=3; // router
if(dhcp_requestDNS) dhcp_p->options[dhcp_optionptr++]=6; // dns server
if(dgramtype==DHCP_TYPE_REQUEST) {
dhcp_p->options[dhcp_optionptr++]=0x32; // DHCP Requested IP address
dhcp_p->options[dhcp_optionptr++]=0x04;
dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip)&255;
dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip>>8)&255;
dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip>>16)&255;
dhcp_p->options[dhcp_optionptr++]=(dhcp_rcvd_ip>>24)&255;
dhcp_p->options[dhcp_optionptr++]=0x36; // DHCP Server identifier
dhcp_p->options[dhcp_optionptr++]=0x04;
dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip)&255;
dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip>>8)&255;
dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip>>16)&255;
dhcp_p->options[dhcp_optionptr++]=(dhcp_serverip>>24)&255;
}
dhcp_p->options[dhcp_optionptr++]=0x3C; // DHCP Vendor Class ID
dhcp_p->options[dhcp_optionptr++]=strlen(SGIP_DHCP_CLASSNAME);
for(i=0;i<strlen(SGIP_DHCP_CLASSNAME);i++) {
dhcp_p->options[dhcp_optionptr++]=(SGIP_DHCP_CLASSNAME)[i];
}
// reason we don't send it immediately is in case the calling code wants to modify some data or add some options.
}
void sgIP_DHCP_Start(sgIP_Hub_HWInterface * interface, int getDNS) { // begin dhcp transaction to get IP and maybe DNS data.
struct sockaddr_in sain;
int i;
SGIP_DEBUG_MESSAGE(("sgIP_DHCP_Start()"));
sgIP_DHCP_Terminate();
dhcp_requestDNS=getDNS?1:0;
dhcp_int=interface;
dhcp_timestart=sgIP_timems;
dhcp_timelastaction=sgIP_timems;
dhcp_tid=sgIP_timems;
dhcp_status=SGIP_DHCP_STATUS_WORKING;
dhcp_state=0;
dhcp_rcvd_ip = 0;
dhcp_rcvd_gateway=0;
dhcp_rcvd_snmask=0;
dhcp_rcvd_dns[0]=0;
dhcp_rcvd_dns[1]=0;
dhcp_rcvd_dns[2]=0;
dhcp_socket=socket(AF_INET,SOCK_DGRAM,0);
sain.sin_addr.s_addr=0;
sain.sin_port=htons(68); // BOOTP client
bind(dhcp_socket,(struct sockaddr *)&sain,sizeof(sain));
i=1;
ioctl(dhcp_socket,FIONBIO,&i);
sgIP_DHCP_BeginDgram(DHCP_TYPE_DISCOVER);
sgIP_DHCP_SendDgram();
}
void sgIP_DHCP_Release() { // call to dump our DHCP address and leave.
if(dhcp_status==SGIP_DHCP_STATUS_WORKING) {
sgIP_DHCP_Terminate();
} else {
sgIP_DHCP_BeginDgram(DHCP_TYPE_RELEASE);
dhcp_p->ciaddr=dhcp_int->ipaddr;
sgIP_DHCP_SendDgram();
}
}
int sgIP_DHCP_Update() { // MUST be called periodicly; returns status - call until it returns SGIP_DHCP_STATUS_SUCCESS or _FAILED.
sgIP_DHCP_Packet * p;
struct sockaddr_in * sain;
int i,j,n,l;
if(dhcp_status!=SGIP_DHCP_STATUS_WORKING) return dhcp_status;
int send = 0;
p=(sgIP_DHCP_Packet *)sgIP_malloc(sizeof(sgIP_DHCP_Packet));
if(p) {
while(1) {
l=recvfrom(dhcp_socket,p,sizeof(sgIP_DHCP_Packet),0,(struct sockaddr *)&sain,&n);
if(l==-1) break;
if(p->op!=2 || p->htype!=1 || p->hlen!=6 || p->xid!=dhcp_tid ) continue;
// check magic cookie
if(p->options[0]!=0x63 || p->options[1]!=0x82 || p->options[2]!=0x53 || p->options[3]!=0x63) continue;
i=4; // yay, the cookie is valid.
l -= (sizeof(sgIP_DHCP_Packet)-312); // number of bytes remaining in the options
while(i<l) {
n=p->options[i++];
switch(n) {
case 0: // ignore
break;
case 255: // end-of-options marker.
l=0;
break;
case 53: // message type, variable length, 2+n
j=p->options[i++];
if(dhcp_state==0) {
if(p->options[i]!=DHCP_TYPE_OFFER) l=-1;
} else {
if(p->options[i]==DHCP_TYPE_ACK) {
sgIP_free(p);
sgIP_DHCP_Terminate();
dhcp_int->ipaddr=dhcp_rcvd_ip;
dhcp_int->gateway=dhcp_rcvd_gateway;
dhcp_int->snmask=dhcp_rcvd_snmask;
SGIP_DEBUG_MESSAGE(("DHCP Configured!"));
SGIP_DEBUG_MESSAGE(("IP%08X SM%08X GW%08X",dhcp_rcvd_ip,dhcp_rcvd_snmask,dhcp_rcvd_gateway));
if(dhcp_requestDNS) {
dhcp_int->dns[0]=dhcp_rcvd_dns[0];
dhcp_int->dns[1]=dhcp_rcvd_dns[1];
dhcp_int->dns[2]=dhcp_rcvd_dns[2];
SGIP_DEBUG_MESSAGE(("DNS %08X %08X %08X",dhcp_rcvd_dns[0],dhcp_rcvd_dns[1],dhcp_rcvd_dns[2]));
}
dhcp_status=SGIP_DHCP_STATUS_SUCCESS;
return dhcp_status;
} else {
l=-1;
}
}
i+=j;
break;
case 1: // subnet mask field, variable length 2+n
j=p->options[i++];
if(dhcp_state==1 || j<4) {i+=j; break; }
dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24);
dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24);
dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24);
dhcp_rcvd_snmask = (dhcp_rcvd_snmask>>8) | (p->options[i++]<<24);
i+=j-4;
break;
case 3: // gateway, variable length 2+n
j=p->options[i++];
if(dhcp_state==1 || j<4) {i+=j; break; }
dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24);
dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24);
dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24);
dhcp_rcvd_gateway = (dhcp_rcvd_gateway>>8) | (p->options[i++]<<24);
i+=j-4;
break;
case 54: // server ID, variable length 2+n
j=p->options[i++];
if(dhcp_state==1 || j<4) {i+=j; break; }
dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24);
dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24);
dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24);
dhcp_serverip = (dhcp_serverip>>8) | (p->options[i++]<<24);
i+=j-4;
break;
case 6: // dns servers, variable length 2+n
if(dhcp_requestDNS && !dhcp_state) {
j=p->options[i++];
n=0;
while(n<3 && 4*n+3<j) {
dhcp_rcvd_dns[n] = (dhcp_rcvd_dns[n]>>8) | (p->options[i++]<<24);
dhcp_rcvd_dns[n] = (dhcp_rcvd_dns[n]>>8) | (p->options[i++]<<24);
dhcp_rcvd_dns[n] = (dhcp_rcvd_dns[n]>>8) | (p->options[i++]<<24);
dhcp_rcvd_dns[n] = (dhcp_rcvd_dns[n]>>8) | (p->options[i++]<<24);
n++;
}
i+=j-4*n;
break;
}
default:
j=p->options[i++];
i+=j;
}
}
if(l==-1) continue;
dhcp_rcvd_ip=(p->yiaddr);
// discover succeeded. increment transaction id. force sending REQUEST message next.
dhcp_state=1;
dhcp_tid += ( sgIP_timems-dhcp_timestart ) + 1;
send = 1;
break;
}
sgIP_free(p);
// has timeout expired?
if( (sgIP_timems-dhcp_timestart) > SGIP_DHCP_ERRORTIMEOUT) {
SGIP_DEBUG_MESSAGE(("sgIP DHCP error timeout!"));
sgIP_DHCP_Terminate();
dhcp_status=SGIP_DHCP_STATUS_FAILED;
return dhcp_status;
}
if( send || (sgIP_timems-dhcp_timelastaction) > SGIP_DHCP_RESENDTIMEOUT )
{
if(dhcp_state==0) sgIP_DHCP_BeginDgram(DHCP_TYPE_DISCOVER); else sgIP_DHCP_BeginDgram(DHCP_TYPE_REQUEST);
sgIP_DHCP_SendDgram();
}
} else {
SGIP_DEBUG_MESSAGE(("sgIP DHCP alloc failed!"));
sgIP_DHCP_Terminate();
dhcp_status=SGIP_DHCP_STATUS_FAILED;
}
return dhcp_status;
}
void sgIP_DHCP_Terminate() { // kill the process where it stands; deallocate all DHCP resources.
if(dhcp_socket) closesocket(dhcp_socket);
dhcp_socket=0;
if(dhcp_p) sgIP_free(dhcp_p);
dhcp_p=0;
dhcp_status=SGIP_DHCP_STATUS_IDLE;
}
int gethostname(char *name, size_t len)
{
int size = sizeof(dhcp_hostname);
if (name == NULL)
return SGIP_ERROR(EFAULT);
if ( len <= size )
return SGIP_ERROR(EINVAL);
strncpy(name, dhcp_hostname, size);
name[size]=0;
return 0;
}
int sethostname(const char *name, size_t len)
{
sgIP_DNS_Record *rec;
int size = sizeof(dhcp_hostname);
if (name == NULL)
return SGIP_ERROR(EFAULT);
if ( len > size - 1)
return SGIP_ERROR(EINVAL);
rec = sgIP_DNS_FindDNSRecord(dhcp_hostname);
strncpy(dhcp_hostname, name, len);
dhcp_hostname[len]=0;
strncpy(rec->aliases[0], name, len);
rec->aliases[0][len]=0;
strncpy(rec->name, name, len);
rec->name[len]=0;
return 0;
}
@@ -1,86 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_DHCP_H
#define SGIP_DHCP_H
#include "sgIP_Config.h"
#include "sgIP_Hub.h"
// "DHCP Server" port is 67, "DHCP Client" port is 68
// DHCP messages broadcast by a client prior to that client obtaining its IP address must have the source address field in the IP header set to 0.
typedef struct SGIP_DHCP_PACKET { // yes, freaking big endian prevails here too.
unsigned char op; // opcode/message type (1=BOOTREQUEST, 2=BOOTREPLY)
unsigned char htype; // hardware address type
unsigned char hlen; // Hardware address length (should be 6, for ethernet/wifi)
unsigned char hops; // set to 0
unsigned long xid; // 4-byte client specified transaction ID
unsigned short secs; // seconds elapsed since client started trying to boot
unsigned short flags; // flags
unsigned long ciaddr; // client IP address, filled in by client if verifying previous params
unsigned long yiaddr; // "your" (client) IP address
unsigned long siaddr; // IP addr of next server to use in bootstrap.
unsigned long giaddr; // Relay agent IP address
unsigned char chaddr[16]; // client hardware address
char sname[64]; // optional server hostname (null terminated string)
char file[128]; // boot file name, null terminated string
char options[312]; // optional parameters
} sgIP_DHCP_Packet;
enum SGIP_DHCP_STATUS {
SGIP_DHCP_STATUS_IDLE,
SGIP_DHCP_STATUS_WORKING,
SGIP_DHCP_STATUS_FAILED,
SGIP_DHCP_STATUS_SUCCESS
};
#define DHCP_TYPE_DISCOVER 1
#define DHCP_TYPE_OFFER 2
#define DHCP_TYPE_REQUEST 3
#define DHCP_TYPE_ACK 5
#define DHCP_TYPE_RELEASE 7
#ifdef __cplusplus
extern "C" {
#endif
void sgIP_DHCP_Init(void);
void sgIP_DHCP_SetHostName(char * s); // just for the fun of it.
int sgIP_DHCP_IsDhcpIp(unsigned long ip); // check if the IP address was assigned via dhcp.
void sgIP_DHCP_Start(sgIP_Hub_HWInterface * interface, int getDNS); // begin dhcp transaction to get IP and maybe DNS data.
void sgIP_DHCP_Release(void); // call to dump our DHCP address and leave.
int sgIP_DHCP_Update(void); // MUST be called periodicly after _Start; returns status - call until it returns something other than SGIP_DHCP_STATUS_WORKING
void sgIP_DHCP_Terminate(void); // kill the process where it stands; deallocate all DHCP resources.
#ifdef __cplusplus
};
#endif
#endif
@@ -1,492 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_DNS.h"
#include "sgIP_Hub.h"
#include "netinet/in.h"
#include "sys/socket.h"
int dns_sock;
int time_count;
int last_id;
int query_time_start;
extern unsigned long volatile sgIP_timems;
// cache record data
sgIP_DNS_Record dnsrecords[SGIP_DNS_MAXRECORDSCACHE];
// data to return via hostent
volatile sgIP_DNS_Record dnsrecord_return;
volatile char * alias_list[SGIP_DNS_MAXALIASES+1];
volatile char * addr_list[SGIP_DNS_MAXRECORDADDRS+1];
char ipaddr_alias[256];
unsigned long ipaddr_ip;
volatile sgIP_DNS_Hostent dnsrecord_hostent;
unsigned char querydata[512];
unsigned char responsedata[512];
void sgIP_DNS_Init() {
int i;
for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) dnsrecords[i].flags=0;
dns_sock=-1;
time_count=0;
}
void sgIP_DNS_Timer1000ms() {
int i;
time_count++;
for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
if(dnsrecords[i].flags & SGIP_DNS_FLAG_RESOLVED) {
dnsrecords[i].TTL-=1;
if(dnsrecords[i].TTL<=0) {
dnsrecords[i].flags=0;
}
}
}
}
int sgIP_DNS_isipaddress(const char * name, unsigned long * ipdest) {
int i,j,t,ndot;
unsigned long out_addr, g[4];
const char * c;
ndot=0;
c=name;
while(*c) { // scan for invalid characters
if(!((*c>='0' && *c<='9') || (*c>='A' && *c<='F') || (*c>='a' && *c<='f') || *c=='.' || *c=='x' || *c=='X')) return 0;
if(*c=='.') ndot++;
c++;
}
if(ndot>3) return 0;
c=name;
for(i=0;i<=ndot;i++) {
g[i]=0;
t=0;
j=0;
while(*c && *c!='.') {
if(j==0 && *c=='0') { t++; }
else if(j==1 && t==1 && (*c=='x' || *c=='X')) { t++; }
else {
switch(t) {
case 0: // decimal
if(*c=='x' || *c=='X' || (*c>='A' && *c<='F') || (*c>='a' && *c<='f')) return 0;
g[i]=(g[i]*10)+(*c-'0');
break;
case 1: // octal
if(*c=='x' || *c=='X' || (*c>='A' && *c<='F') || (*c>='a' && *c<='f') || *c=='8' || *c=='9') return 0;
g[i]=(g[i]<<3)+(*c-'0');
break;
case 2: // hex
if(*c=='x' || *c=='X') return 0;
if(*c>='0' && *c<='9') {
g[i]=(g[i]<<4)+(*c-'0');
} else {
g[i]=(g[i]<<4)+(*c&0xDF)+9;
}
break;
}
}
j++; c++;
}
if(*c) c++; else break;
}
out_addr=0;
switch(ndot) {
case 0:
out_addr=g[0];
break;
case 1:
if(g[0]>=0x100 || g[1]>=0x1000000) return 0;
out_addr= (g[0]<<24) | g[1];
break;
case 2:
if(g[0]>=0x100 || g[1]>=0x100 || g[2]>=0x10000) return 0;
out_addr= (g[0]<<24) | (g[1]<<16) | g[2];
break;
case 3:
if(g[0]>=0x100 || g[1]>=0x100 || g[2]>=0x100 || g[3]>=0x100) return 0;
out_addr= (g[0]<<24) | (g[1]<<16) | (g[2]<<8) | g[3];
break;
}
*ipdest=htonl(out_addr);
return 1;
}
sgIP_DNS_Record * sgIP_DNS_FindDNSRecord(const char * name) {
int i,j,k,n,c,c2;
SGIP_INTR_PROTECT();
for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
if((dnsrecords[i].flags&(SGIP_DNS_FLAG_ACTIVE|SGIP_DNS_FLAG_RESOLVED)) == (SGIP_DNS_FLAG_ACTIVE|SGIP_DNS_FLAG_RESOLVED)) {
for(j=0;j<dnsrecords[i].numalias;j++) {
k=0;
for(n=0;name[n] && dnsrecords[i].aliases[j][n]; n++) { // obscure and complex case-insensitive string compare.
c=name[n];
c2=dnsrecords[i].aliases[j][n];
if(c>='a' && c<='z') c+='A'-'a';
if(c2>='a' && c2<='z') c2+='A'-'a';
if(c==c2) {
k++;
} else {
k=0; break;
}
}
if(name[n] || dnsrecords[i].aliases[j][n]) k=0;
if(k) {
SGIP_INTR_UNPROTECT();
return dnsrecords+i;
}
}
}
}
SGIP_INTR_UNPROTECT();
return 0;
}
sgIP_DNS_Record * sgIP_DNS_GetUnusedRecord() {
int i,j,minttl;
SGIP_INTR_PROTECT();
for(i=0;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
if(!(dnsrecords[i].flags&SGIP_DNS_FLAG_ACTIVE)) {
SGIP_INTR_UNPROTECT();
return dnsrecords+i;
}
}
minttl=dnsrecords[0].TTL; j=0;
for(i=1;i<SGIP_DNS_MAXRECORDSCACHE;i++) {
if(dnsrecords[i].TTL<minttl && !(dnsrecords[i].flags&SGIP_DNS_FLAG_BUSY)) {
j=i;
minttl=dnsrecords[i].TTL;
}
}
dnsrecords[j].flags=0;
SGIP_INTR_UNPROTECT();
return dnsrecords+j;
}
static
void sgIP_ntoa(unsigned long ipaddr) {
int c,i,j,n;
c=0;
for(j=0;j<4;j++) {
if(j) ipaddr_alias[c++]='.';
n=(ipaddr>>(j*8))&255;
i=0;
if(n>=100) { i=n/100; ipaddr_alias[c++]='0'+i; n-=i*100; }
if(n>=10 || i) { i=n/10; ipaddr_alias[c++]='0'+i; n-=i*10; }
ipaddr_alias[c++]='0'+n;
}
ipaddr_alias[c]=0;
}
static
sgIP_DNS_Hostent * sgIP_DNS_GenerateHostentIP(unsigned long ipaddr) {
sgIP_ntoa(ipaddr);
alias_list[0]=ipaddr_alias;
alias_list[1]=0;
ipaddr_ip=ipaddr;
addr_list[0]=(char *)&ipaddr_ip;
addr_list[1]=0;
dnsrecord_hostent.h_addr_list=(char **)addr_list;
dnsrecord_hostent.h_addrtype=1;
dnsrecord_hostent.h_aliases=(char **)alias_list;
dnsrecord_hostent.h_length=4;
dnsrecord_hostent.h_name=ipaddr_alias;
return (sgIP_DNS_Hostent *)&dnsrecord_hostent;
}
sgIP_DNS_Hostent * sgIP_DNS_GenerateHostent(sgIP_DNS_Record * dnsrec) {
volatile int i;
dnsrecord_return = *dnsrec; // copy struct
for(i=0;i<dnsrecord_return.numalias;i++) {
alias_list[i]=dnsrecord_return.aliases[i];
}
alias_list[i]=0;
for(i=0;i<dnsrecord_return.numaddr;i++) {
addr_list[i]=(char *)&(dnsrecord_return.addrdata[i*dnsrecord_return.addrlen]);
}
addr_list[i]=0;
dnsrecord_hostent.h_addr_list=(char **)addr_list;
dnsrecord_hostent.h_addrtype=dnsrecord_return.addrclass;
dnsrecord_hostent.h_aliases=(char **)alias_list;
dnsrecord_hostent.h_length=dnsrecord_return.addrlen;
dnsrecord_hostent.h_name=(char *)dnsrecord_return.name;
return (sgIP_DNS_Hostent *)&dnsrecord_hostent;
}
static
int sgIP_DNS_genquery(const char * name) {
int i,j,c,l;
unsigned short * querydata_s = (unsigned short *) querydata;
unsigned char * querydata_c = querydata;
// header section
querydata_s[0]=htons(time_count&0xFFFF);
last_id=querydata_s[0];
querydata_s[1]=htons(0x0100); // recursion desired, standard query
querydata_s[2]=htons(1); // one QD (question)
querydata_s[3]=0; // no resource records
querydata_s[4]=0; // no nameserver records
querydata_s[5]=0; // no additional records
// question section
querydata_c+=12;
querydata_s+=6;
j=0;
i=0;
while(1) {
l=j;
j++;
c=0;
while(name[i]!=0 && name[i]!='.' && i<255) {
querydata_c[j++]=name[i++]; c++;
}
querydata_c[l]=c;
if(name[i]==0 || i>=255) break;
if(c==0) return 0; // this should never happen (unless there's really invalid input with 2 dots next to each other.)
i++;
}
querydata_c[j++]=0; // terminating zero length
// qtype
querydata_c[j++]=0;
querydata_c[j++]=1; // 00 01 "A" (address)
// qclass
querydata_c[j++]=0;
querydata_c[j++]=1; // 00 01 "IN" (internet)
return j+12; // length
}
void sgIP_DNS_CopyAliasAt(char * deststr,int offset) {
char * c;
int i,j;
i=0;
c=(char *)responsedata+offset;
do {
j=c[0];
if(j>63) {
j=((j&63)<<8) | c[1];
c=(char *)responsedata+j;
continue;
}
if(!j) break;
c++;
for(;j>0;j--) {
deststr[i++]= *(c++);
}
deststr[i++]='.';
} while(1);
if(i>0) i--;
deststr[i]=0;
}
sgIP_DNS_Hostent * sgIP_DNS_gethostbyname(const char * name) {
sgIP_DNS_Record * rec;
sgIP_DNS_Hostent * he;
sgIP_Hub_HWInterface * hw;
int len,i,sainlen;
int retries,dtime;
unsigned long serverip;
struct sockaddr_in sain;
unsigned long IP;
SGIP_INTR_PROTECT();
// is name an IP address?
if(sgIP_DNS_isipaddress(name,&IP)) {
SGIP_INTR_UNPROTECT();
return sgIP_DNS_GenerateHostentIP(IP);
}
// check cache, return if value required is in cache...
rec=sgIP_DNS_FindDNSRecord(name);
if(rec) {
he=sgIP_DNS_GenerateHostent(rec);
SGIP_INTR_UNPROTECT();
return he;
}
// not in cache? generate a query...
len=sgIP_DNS_genquery(name);
// send off the query, handle retransmit and trying other dns servers.
if(dns_sock==-1) {
hw=sgIP_Hub_GetDefaultInterface();
serverip=hw->dns[0];
dns_sock=socket(AF_INET,SOCK_DGRAM,0);
i=1;
i=ioctl(dns_sock,FIONBIO,&i); // set non-blocking
retries=0;
do {
query_time_start=sgIP_timems;
sain.sin_addr.s_addr=serverip;
sain.sin_port=htons(53);
i=sendto(dns_sock,querydata,len,0,(struct sockaddr *)&sain,sizeof(sain));
dns_listenonly:
do {
i=recvfrom(dns_sock,responsedata,512,0,(struct sockaddr *)&sain,&sainlen);
if(i!=-1) break;
dtime=sgIP_timems-query_time_start;
if(dtime>SGIP_DNS_TIMEOUTMS) break;
SGIP_INTR_UNPROTECT();
SGIP_WAITEVENT();
SGIP_INTR_REPROTECT();
} while(1);
if(i==-1) { // no reply, retry
retries++;
if(retries>=SGIP_DNS_MAXRETRY) { // maybe try another server? for now just quit.
closesocket(dns_sock);
dns_sock=-1;
SGIP_INTR_UNPROTECT();
return NULL;
}
continue; // send again
}
// got something, is it what we want?
if(i<12 || sain.sin_addr.s_addr!=serverip || sain.sin_port!=htons(53)) { // suspicious.
goto dns_listenonly; // yay! a goto! - go back and see if we can get a more official response.
}
// parse response.
{
const unsigned short * resdata_s = (unsigned short *) responsedata;
const unsigned char * resdata_c = responsedata;
const char * c;
int j,q,a, nalias,naddr;
if(last_id!=resdata_s[0]) { // bad.
goto dns_listenonly;
}
q=htons(resdata_s[2]);
a=htons(resdata_s[3]);
// no answer.
if (a == 0)
{
closesocket(dns_sock);
dns_sock=-1;
SGIP_INTR_UNPROTECT();
return NULL;
}
resdata_c+=12;
while(q) { // ignore questions
do {
j=resdata_c[0];
if(j>63) { resdata_c+=2; break; }
resdata_c += j+1;
} while(j);
resdata_c+=4;
q--;
}
nalias=0;
naddr=0;
rec=sgIP_DNS_GetUnusedRecord();
rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_BUSY;
while(a) {
if(nalias<SGIP_DNS_MAXALIASES) sgIP_DNS_CopyAliasAt(rec->aliases[nalias++],resdata_c-responsedata);
do {
j=resdata_c[0];
if(j>63) { resdata_c+=2; break; }
resdata_c += j+1;
} while(j);
// CNAME=5, A=1
j=resdata_c[1];
rec->addrclass=(resdata_c[2]<<8)|resdata_c[3];
rec->TTL = (resdata_c[4]<<24)|(resdata_c[5]<<16)|(resdata_c[6]<<8)|resdata_c[7];
if(j==1) { // A
if(naddr<SGIP_DNS_MAXRECORDADDRS) {
rec->addrdata[naddr*4] = resdata_c[10];
rec->addrdata[naddr*4+1] = resdata_c[11];
rec->addrdata[naddr*4+2] = resdata_c[12];
rec->addrdata[naddr*4+3] = resdata_c[13];
naddr++;
}
}
j=(resdata_c[8]<<8)|resdata_c[9];
resdata_c+=10+j;
a--;
}
// likely we have all the data we care for now.
rec->addrlen=4;
rec->numaddr=naddr;
rec->numalias=nalias;
for(c=name,i=0;*c;c++,i++) rec->name[i]=*c;
rec->name[i]=0;
rec->flags=SGIP_DNS_FLAG_ACTIVE | SGIP_DNS_FLAG_RESOLVED;
break; // we got our answer, let's get out of here!
}
} while(1);
closesocket(dns_sock);
dns_sock=-1;
} else {
SGIP_INTR_UNPROTECT();
return NULL;
}
// received response, return data
he=sgIP_DNS_GenerateHostent(rec);
SGIP_INTR_UNPROTECT();
return he;
}
unsigned long inet_addr(const char *cp) {
unsigned long IP;
if(sgIP_DNS_isipaddress(cp,&IP)) {
return IP;
}
return 0xFFFFFFFF;
}
int inet_aton(const char *cp, struct in_addr *inp) {
unsigned long IP;
if(sgIP_DNS_isipaddress(cp,&IP)) {
inp->s_addr = IP;
return 1;
}
return 0;
}
char *inet_ntoa(struct in_addr in) {
sgIP_ntoa(in.s_addr);
return (char *)ipaddr_alias;
}
@@ -1,69 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_DNS_H
#define SGIP_DNS_H
#include "sgIP_Config.h"
#define SGIP_DNS_FLAG_ACTIVE 1
#define SGIP_DNS_FLAG_RESOLVED 2
#define SGIP_DNS_FLAG_BUSY 4
typedef struct SGIP_DNS_RECORD {
char name [256];
char aliases[SGIP_DNS_MAXALIASES][256];
unsigned char addrdata[SGIP_DNS_MAXRECORDADDRS*4];
short addrlen;
short addrclass;
int numaddr,numalias;
int TTL;
int flags;
} sgIP_DNS_Record;
typedef struct SGIP_DNS_HOSTENT {
char * h_name;
char ** h_aliases;
int h_addrtype; // class - 1=IN (internet)
int h_length;
char ** h_addr_list;
} sgIP_DNS_Hostent;
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_DNS_Init(void);
extern void sgIP_DNS_Timer1000ms(void);
extern sgIP_DNS_Hostent * sgIP_DNS_gethostbyname(const char * name);
extern sgIP_DNS_Record * sgIP_DNS_GetUnusedRecord(void);
extern sgIP_DNS_Record * sgIP_DNS_FindDNSRecord(const char * name);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,211 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_Hub.h"
#include "sgIP_ARP.h"
//////////////////////////////////////////////////////////////////////////
// Global vars
int NumHWInterfaces;
int NumProtocolInterfaces;
sgIP_Hub_Protocol ProtocolInterfaces[SGIP_HUB_MAXPROTOCOLINTERFACES];
sgIP_Hub_HWInterface HWInterfaces[SGIP_HUB_MAXHWINTERFACES];
//////////////////////////////////////////////////////////////////////////
// Private functions
//////////////////////////////////////////////////////////////////////////
// Public functions
void sgIP_Hub_Init() {
NumHWInterfaces=0;
NumProtocolInterfaces=0;
}
sgIP_Hub_Protocol * sgIP_Hub_AddProtocolInterface(int protocolID, int (*ReceivePacket)(sgIP_memblock *), int (*InterfaceInit)(sgIP_Hub_Protocol *)) {
int n;
if(NumProtocolInterfaces>=SGIP_HUB_MAXPROTOCOLINTERFACES) return 0;
for(n=0;n<SGIP_HUB_MAXPROTOCOLINTERFACES;n++) {
if(!(ProtocolInterfaces[n].flags&SGIP_FLAG_PROTOCOL_IN_USE)) break;
}
if(n==SGIP_HUB_MAXPROTOCOLINTERFACES) return 0;
ProtocolInterfaces[n].flags=SGIP_FLAG_PROTOCOL_IN_USE | SGIP_FLAG_PROTOCOL_ENABLED;
ProtocolInterfaces[n].protocol=protocolID;
ProtocolInterfaces[n].ReceivePacket=ReceivePacket;
if(InterfaceInit) InterfaceInit(ProtocolInterfaces+n);
NumProtocolInterfaces++;
return ProtocolInterfaces+n;
}
sgIP_Hub_HWInterface * sgIP_Hub_AddHardwareInterface(int (*TransmitFunction)(sgIP_Hub_HWInterface *, sgIP_memblock *), int (*InterfaceInit)(sgIP_Hub_HWInterface *)) {
int n;
if(NumHWInterfaces>=SGIP_HUB_MAXHWINTERFACES) return 0;
for(n=0;n<SGIP_HUB_MAXHWINTERFACES;n++) {
if(!(HWInterfaces[n].flags&SGIP_FLAG_HWINTERFACE_IN_USE)) break;
}
if(n==SGIP_HUB_MAXHWINTERFACES) return 0;
HWInterfaces[n].flags = SGIP_FLAG_HWINTERFACE_IN_USE | SGIP_FLAG_HWINTERFACE_ENABLED;
HWInterfaces[n].TransmitFunction=TransmitFunction;
if(InterfaceInit) InterfaceInit(HWInterfaces+n);
NumHWInterfaces++;
return HWInterfaces+n;
}
extern void sgIP_Hub_RemoveProtocolInterface(sgIP_Hub_Protocol * protocol) {
int n;
for(n=0;n<SGIP_HUB_MAXPROTOCOLINTERFACES;n++) {
if(ProtocolInterfaces+n ==protocol) break;
}
if(n==SGIP_HUB_MAXPROTOCOLINTERFACES) return;
protocol->flags=0;
NumProtocolInterfaces--;
}
extern void sgIP_Hub_RemoveHardwareInterface(sgIP_Hub_HWInterface * hw) {
int n;
for(n=0;n<SGIP_HUB_MAXHWINTERFACES;n++) {
if(HWInterfaces+n == hw) break;
}
if(n==SGIP_HUB_MAXHWINTERFACES) return;
hw->flags=0;
NumHWInterfaces--;
}
int sgIP_Hub_ReceiveHardwarePacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet) {
if(!hw || !packet) return 0;
if(hw->flags & SGIP_FLAG_HWINTERFACE_ENABLED) {
int n;
int protocol;
protocol = ((unsigned short *)packet->datastart)[6];
// SGIP_DEBUG_MESSAGE(("hub: rx packet %04X %X",protocol,packet->totallength));
if(protocol==PROTOCOL_ETHER_ARP) { // arp
sgIP_ARP_ProcessARPFrame(hw,packet);
return 0;
}
if(protocol==PROTOCOL_ETHER_IP) { // IP, forward to the ARP system.
}
// hide ethernet header for higher-level protocols
sgIP_memblock_exposeheader(packet,-14);
for(n=0;n<SGIP_HUB_MAXPROTOCOLINTERFACES;n++) {
if(ProtocolInterfaces[n].flags&SGIP_FLAG_PROTOCOL_ENABLED && ProtocolInterfaces[n].protocol==protocol) { // this protocol handler
return ProtocolInterfaces[n].ReceivePacket(packet);
}
}
}
// hrmm, packet is unhandled. Ignore it for now.
sgIP_memblock_free(packet);
return 0;
}
// send packet from a protocol interface, resolve the requisite hardware interface addresses and send it.
int sgIP_Hub_SendProtocolPacket(int protocol, sgIP_memblock * packet, unsigned long dest_address, unsigned long src_address) {
if(!packet) return 0;
sgIP_Hub_HWInterface * hw;
int i;
hw=0;
// figure out what hardware interface is in use.
for(i=0;i<SGIP_HUB_MAXHWINTERFACES;i++) if(HWInterfaces[i].ipaddr==src_address) {hw=HWInterfaces+i; break;}
if(!hw) {
sgIP_memblock_free(packet);
return 0;
}
// resolve protocol address to hardware address & send packet
if( (src_address & hw->snmask) == (dest_address & hw->snmask) // on same network
|| dest_address == 0xFFFFFFFF ) // or broadcast address, send directly.
{
return sgIP_ARP_SendProtocolFrame(hw,packet,protocol,dest_address);
} else { // eek, on different network. Send to gateway
return sgIP_ARP_SendProtocolFrame(hw,packet,protocol,hw->gateway);
}
}
// send packet on a hardware interface.
int sgIP_Hub_SendRawPacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet) {
if(!hw || !packet) return 0;
if(hw->flags&SGIP_FLAG_HWINTERFACE_ENABLED) {
return hw->TransmitFunction(hw,packet);
}
sgIP_memblock_free(packet);
return 0;
}
int sgIP_Hub_IPMaxMessageSize(unsigned long ipaddr) {
return SGIP_MTU_OVERRIDE; // hack - make this more accurate soon!
}
unsigned long sgIP_Hub_GetCompatibleIP(unsigned long destIP) {
int n;
for(n=0;n<SGIP_HUB_MAXHWINTERFACES;n++) {
if((HWInterfaces[n].flags&SGIP_FLAG_HWINTERFACE_IN_USE)) {
if((HWInterfaces[n].ipaddr & HWInterfaces[n].snmask) == (destIP & HWInterfaces[n].snmask)) return HWInterfaces[n].ipaddr;
}
}
for(n=0;n<SGIP_HUB_MAXHWINTERFACES;n++) {
if((HWInterfaces[n].flags&SGIP_FLAG_HWINTERFACE_IN_USE)) {
return HWInterfaces[n].ipaddr;
}
}
return 0;
}
extern sgIP_Hub_HWInterface * sgIP_Hub_GetDefaultInterface() {
int n;
for(n=0;n<SGIP_HUB_MAXHWINTERFACES;n++) {
if((HWInterfaces[n].flags&SGIP_FLAG_HWINTERFACE_IN_USE)) {
return HWInterfaces+n;
}
}
return 0;
}
#ifdef SGIP_LITTLEENDIAN
unsigned short htons(unsigned short num) {
return ((num<<8)&0xFF00) | (num>>8);
}
unsigned long htonl(unsigned long num) {
return (num<<24) | ((num&0xFF00)<<8) | ((num&0xFF0000)>>8) | (num>>24);
}
#else
unsigned short htons(unsigned short num) {
return num;
}
unsigned long htonl(unsigned long num) {
return num;
}
#endif
@@ -1,109 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_HUB_H
#define SGIP_HUB_H
#include "sgIP_Config.h"
#include "sgIP_memblock.h"
#define SGIP_FLAG_PROTOCOL_IN_USE 0x0001
#define SGIP_FLAG_PROTOCOL_ENABLED 0x8000
#define SGIP_FLAG_HWINTERFACE_IN_USE 0x0001
#define SGIP_FLAG_HWINTERFACE_CONNECTED 0x0002
#define SGIP_FLAG_HWINTERFACE_USEDHCP 0x0004
#define SGIP_FLAG_HWINTERFACE_CHANGENETWORK 0x0008
#define SGIP_FLAG_HWINTERFACE_ENABLED 0x8000
#ifdef SGIP_LITTLEENDIAN
#define PROTOCOL_ETHER_ARP 0x0608
#define PROTOCOL_ETHER_IP 0x0008
#else
#define PROTOCOL_ETHER_ARP 0x0806
#define PROTOCOL_ETHER_IP 0x0800
#endif
// structure sgIP_Hub_Protocol: Used to record the interface between the sgIP Hub and a protocol handler
typedef struct SGIP_HUB_PROTOCOL {
unsigned short flags;
unsigned short protocol;
int (*ReceivePacket)(sgIP_memblock *);
} sgIP_Hub_Protocol;
typedef struct SGIP_HUB_HWINTERFACE {
unsigned short flags;
unsigned short hwaddrlen;
int MTU;
int (*TransmitFunction)(struct SGIP_HUB_HWINTERFACE *, sgIP_memblock *);
void * userdata;
unsigned long ipaddr, gateway, snmask, dns[3];
unsigned char hwaddr[SGIP_MAXHWADDRLEN];
} sgIP_Hub_HWInterface;
typedef struct SGIP_HEADER_ETHERNET {
unsigned char dest_mac[6];
unsigned char src_mac[6];
unsigned short protocol;
} sgIP_Header_Ethernet;
#define ntohs(num) htons(num)
#define ntohl(num) htonl(num)
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_Hub_Init(void);
extern sgIP_Hub_Protocol * sgIP_Hub_AddProtocolInterface(int protocolID, int (*ReceivePacket)(sgIP_memblock *), int (*InterfaceInit)(sgIP_Hub_Protocol *));
extern sgIP_Hub_HWInterface * sgIP_Hub_AddHardwareInterface(int (*TransmitFunction)(sgIP_Hub_HWInterface *, sgIP_memblock *), int (*InterfaceInit)(sgIP_Hub_HWInterface *));
extern void sgIP_Hub_RemoveProtocolInterface(sgIP_Hub_Protocol * protocol);
extern void sgIP_Hub_RemoveHardwareInterface(sgIP_Hub_HWInterface * hw);
extern int sgIP_Hub_ReceiveHardwarePacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet);
extern int sgIP_Hub_SendProtocolPacket(int protocol, sgIP_memblock * packet, unsigned long dest_address, unsigned long src_address);
extern int sgIP_Hub_SendRawPacket(sgIP_Hub_HWInterface * hw, sgIP_memblock * packet);
extern int sgIP_Hub_IPMaxMessageSize(unsigned long ipaddr);
unsigned long sgIP_Hub_GetCompatibleIP(unsigned long destIP);
extern sgIP_Hub_HWInterface * sgIP_Hub_GetDefaultInterface(void);
unsigned short htons(unsigned short num);
unsigned long htonl(unsigned long num);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,56 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_ICMP.h"
#include "sgIP_IP.h"
#include "sgIP_Hub.h"
void sgIP_ICMP_Init() {
}
int sgIP_ICMP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip) {
if(!mb) return 0;
sgIP_Header_ICMP * icmp;
icmp = (sgIP_Header_ICMP *) mb->datastart;
if(icmp->checksum!=0 && sgIP_memblock_IPChecksum(mb,0,mb->totallength)!=0xFFFF) {
SGIP_DEBUG_MESSAGE(("ICMP receive checksum incorrect"));
sgIP_memblock_free(mb);
return 0;
}
switch(icmp->type) {
case 8: // echo request
icmp->type=0; // change to echo reply
// mod checksum
icmp->checksum=0;
icmp->checksum=~sgIP_memblock_IPChecksum(mb,0,mb->totallength);
return sgIP_IP_SendViaIP(mb,PROTOCOL_IP_ICMP,destip,srcip);
case 0: // echo reply (ignore for now)
default: // others (ignore for now)
break;
}
sgIP_memblock_free(mb);
return 0;
}
@@ -1,52 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_ICMP_H
#define SGIP_ICMP_H
#include "sgIP_Config.h"
#include "sgIP_memblock.h"
typedef struct SGIP_HEADER_ICMP {
unsigned char type,code;
unsigned short checksum;
unsigned long xtra;
} sgIP_Header_ICMP;
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_ICMP_Init(void);
extern int sgIP_ICMP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,124 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_IP.h"
#include "sgIP_TCP.h"
#include "sgIP_UDP.h"
#include "sgIP_ICMP.h"
#include "sgIP_Hub.h"
int idnum_count;
int sgIP_IP_ReceivePacket(sgIP_memblock * mb) {
sgIP_Header_IP * iphdr;
unsigned short * chksum_calc;
int chksum_temp;
int hdrlen;
iphdr=(sgIP_Header_IP *)mb->datastart;
chksum_calc=(unsigned short *)mb->datastart;
// check that header is valid:
hdrlen=iphdr->version_ihl&15;
// check length...
if(mb->totallength<htons(iphdr->tot_length)) {
SGIP_DEBUG_MESSAGE(("IP: bad length!"));
SGIP_DEBUG_MESSAGE(("-%i/%i",mb->totallength,htons(iphdr->tot_length)));
sgIP_memblock_free(mb);
return 0; // bad size.
}
sgIP_memblock_trimsize(mb,htons(iphdr->tot_length));
// check version
if((iphdr->version_ihl>>4)!=4) {
SGIP_DEBUG_MESSAGE(("IP: bad version!"));
sgIP_memblock_free(mb);
return 0; // bad version.
}
// check checksum
chksum_temp=sgIP_memblock_IPChecksum(mb,0,hdrlen*4);
if(chksum_temp!=0xFFFF) { // bad chksum! kill packet.
SGIP_DEBUG_MESSAGE(("IP: bad checksum!"));
sgIP_memblock_free(mb);
return 0; // bad checksum.
}
if(htons(iphdr->fragment_offset)&0x3FFF) { // fragmented! oh noes! We can't deal with this!
SGIP_DEBUG_MESSAGE(("IP: fragmented!"));
sgIP_memblock_free(mb);
return 0; // fragmented.
}
sgIP_memblock_exposeheader(mb,-hdrlen*4);
switch(iphdr->protocol) {
case PROTOCOL_IP_ICMP: // ICMP
sgIP_ICMP_ReceivePacket(mb,iphdr->src_address,iphdr->dest_address);
break;
case PROTOCOL_IP_TCP: // TCP
sgIP_TCP_ReceivePacket(mb,iphdr->src_address,iphdr->dest_address);
break;
case PROTOCOL_IP_UDP: // UDP
sgIP_UDP_ReceivePacket(mb,iphdr->src_address,iphdr->dest_address);
break;
default:
sgIP_memblock_free(mb);
}
return 0;
}
int sgIP_IP_MaxContentsSize(unsigned long destip) {
return sgIP_Hub_IPMaxMessageSize(destip)-sgIP_IP_RequiredHeaderSize();
}
int sgIP_IP_RequiredHeaderSize() {
return 5*4; // we'll not include zeroed options.
}
int sgIP_IP_SendViaIP(sgIP_memblock * mb, int protocol, unsigned long srcip, unsigned long destip) {
sgIP_Header_IP * iphdr;
unsigned short * chksum_calc;
int chksum_temp,i;
sgIP_memblock_exposeheader(mb,20);
iphdr=(sgIP_Header_IP *)mb->datastart;
chksum_calc=(unsigned short *)mb->datastart;
iphdr->dest_address=destip;
iphdr->fragment_offset=0;
iphdr->header_checksum=0;
iphdr->identification=idnum_count++;
iphdr->protocol=protocol;
iphdr->src_address=srcip;
iphdr->tot_length=htons(mb->totallength);
iphdr->TTL=SGIP_IP_TTL;
iphdr->type_of_service=0;
iphdr->version_ihl=0x45;
chksum_temp=0;
for(i=0;i<10;i++) chksum_temp+=chksum_calc[i];
chksum_temp += chksum_temp>>16;
chksum_temp &= 0xFFFF;
chksum_temp = ~chksum_temp;
if(chksum_temp==0) chksum_temp=0xFFFF;
iphdr->header_checksum=chksum_temp;
return sgIP_Hub_SendProtocolPacket(htons(0x0800),mb,destip,srcip);
}
unsigned long sgIP_IP_GetLocalBindAddr(unsigned long srcip, unsigned long destip) {
if(srcip) return srcip;
return sgIP_Hub_GetCompatibleIP(destip);
}
@@ -1,64 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_IP_H
#define SGIP_IP_H
#include "sgIP_memblock.h"
#define PROTOCOL_IP_ICMP 1
#define PROTOCOL_IP_TCP 6
#define PROTOCOL_IP_UDP 17
typedef struct SGIP_HEADER_IP {
unsigned char version_ihl; // version = top 4 bits == 4, IHL = header length in 32bit increments = bottom 4 bits
unsigned char type_of_service; // [3bit prescidence][ D ][ T ][ R ][ 0 0 ] - D=low delya, T=high thoroughput, R= high reliability
unsigned short tot_length; // total length of packet including header
unsigned short identification; // value assigned by sender to aid in packet reassembly
unsigned short fragment_offset; // top 3 bits are flags [0][DF][MF] (Don't Fragment / More Fragments Exist) - offset is in 8-byte chunks.
unsigned char TTL; // time to live, measured in hops
unsigned char protocol; // protocols: ICMP=1, TCP=6, UDP=17
unsigned short header_checksum; // checksum:
unsigned long src_address; // src address is 32bit IP address
unsigned long dest_address; // dest address is 32bit IP address
unsigned char options[4]; // optional options come here.
} sgIP_Header_IP;
#ifdef __cplusplus
extern "C" {
#endif
extern int sgIP_IP_ReceivePacket(sgIP_memblock * mb);
extern int sgIP_IP_MaxContentsSize(unsigned long destip);
extern int sgIP_IP_RequiredHeaderSize(void);
extern int sgIP_IP_SendViaIP(sgIP_memblock * mb, int protocol, unsigned long srcip, unsigned long destip);
extern unsigned long sgIP_IP_GetLocalBindAddr(unsigned long srcip, unsigned long destip);
#ifdef __cplusplus
};
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -1,134 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_TCP_H
#define SGIP_TCP_H
#include "sgIP_Config.h"
#include "sgIP_memblock.h"
enum SGIP_TCP_STATE {
SGIP_TCP_STATE_NODATA, // newly allocated
SGIP_TCP_STATE_UNUSED, // allocated & BINDed
SGIP_TCP_STATE_LISTEN, // listening
SGIP_TCP_STATE_SYN_SENT, // connect initiated
SGIP_TCP_STATE_SYN_RECEIVED, // spawned from listen socket;
SGIP_TCP_STATE_ESTABLISHED, // syns have been exchanged
SGIP_TCP_STATE_FIN_WAIT_1, // sent a FIN, haven't got FIN or ACK yet.
SGIP_TCP_STATE_FIN_WAIT_2, // got ACK for our FIN, haven't got FIN yet.
SGIP_TCP_STATE_CLOSE_WAIT, // got FIN, wait for user code to close socket & send FIN
SGIP_TCP_STATE_CLOSING, // got FIN, waiting for ACK of our FIN
SGIP_TCP_STATE_LAST_ACK, // wait for ACK of our last FIN
SGIP_TCP_STATE_TIME_WAIT, // wait to ensure remote tcp knows it's been terminated.
SGIP_TCP_STATE_CLOSED, // Block is unused.
};
#define SGIP_TCP_FLAG_FIN 1
#define SGIP_TCP_FLAG_SYN 2
#define SGIP_TCP_FLAG_RST 4
#define SGIP_TCP_FLAG_PSH 8
#define SGIP_TCP_FLAG_ACK 16
#define SGIP_TCP_FLAG_URG 32
typedef struct SGIP_HEADER_TCP {
unsigned short srcport,destport;
unsigned long seqnum;
unsigned long acknum;
unsigned char dataofs_;
unsigned char tcpflags;
unsigned short window;
unsigned short checksum;
unsigned short urg_ptr;
unsigned char options[4];
} sgIP_Header_TCP;
// sgIP_Record_TCP - a TCP record, to store data for an active TCP connection.
typedef struct SGIP_RECORD_TCP {
struct SGIP_RECORD_TCP * next; // operate as a linked list
// TCP state information
int tcpstate;
unsigned long sequence; // sequence number of first byte not acknowledged by remote system
unsigned long ack; // external sequence number of next byte to receive
unsigned long sequence_next; // sequence number of first unsent byte
unsigned long rxwindow; // sequence of last byte in receive window
unsigned long txwindow; // sequence of last byte allowed to send
int time_last_action; // used for retransmission and etc.
int time_backoff;
int retrycount;
unsigned long srcip;
unsigned long destip;
unsigned short srcport,destport;
struct SGIP_RECORD_TCP ** listendata;
int maxlisten;
int errorcode;
int want_shutdown; // 0= don't want shutdown, 1= want shutdown, 2= being shutdown
int want_reack;
// TCP buffer information:
int buf_rx_in, buf_rx_out;
int buf_tx_in, buf_tx_out;
int buf_oob_in, buf_oob_out;
unsigned char buf_rx[SGIP_TCP_RECEIVEBUFFERLENGTH];
unsigned char buf_tx[SGIP_TCP_TRANSMITBUFFERLENGTH];
unsigned char buf_oob[SGIP_TCP_OOBBUFFERLENGTH];
} sgIP_Record_TCP;
typedef struct SGIP_TCP_SYNCOOKIE {
unsigned long localseq, remoteseq;
unsigned long localip, remoteip;
unsigned short localport, remoteport;
unsigned long timenext,timebackoff;
sgIP_Record_TCP * linked; // parent listening connection
} sgIP_TCP_SYNCookie;
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_TCP_Init(void);
extern void sgIP_TCP_Timer(void);
extern int sgIP_TCP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip);
extern int sgIP_TCP_SendPacket(sgIP_Record_TCP * rec, int flags, int datalength); // data sent is taken directly from the TX fifo.
extern int sgIP_TCP_SendSynReply(int flags,unsigned long seq, unsigned long ack, unsigned long srcip, unsigned long destip, int srcport, int destport, int windowlen);
extern sgIP_Record_TCP * sgIP_TCP_AllocRecord(void);
extern void sgIP_TCP_FreeRecord(sgIP_Record_TCP * rec);
extern int sgIP_TCP_Bind(sgIP_Record_TCP * rec, int srcport, unsigned long srcip);
extern int sgIP_TCP_Listen(sgIP_Record_TCP * rec, int maxlisten);
extern sgIP_Record_TCP * sgIP_TCP_Accept(sgIP_Record_TCP * rec);
extern int sgIP_TCP_Close(sgIP_Record_TCP * rec);
extern int sgIP_TCP_Connect(sgIP_Record_TCP * rec, unsigned long destip, int destport);
extern int sgIP_TCP_Send(sgIP_Record_TCP * rec, const char * datatosend, int datalength, int flags);
extern int sgIP_TCP_Recv(sgIP_Record_TCP * rec, char * databuf, int buflength, int flags);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,245 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_Hub.h"
#include "sgIP_UDP.h"
#include "sgIP_IP.h"
sgIP_Record_UDP * udprecords;
int udpport_counter;
extern unsigned long volatile sgIP_timems;
void sgIP_UDP_Init() {
udprecords=0;
udpport_counter=SGIP_UDP_FIRSTOUTGOINGPORT;
}
int sgIP_UDP_GetUnusedOutgoingPort() {
int myport,clear;
sgIP_Record_UDP * rec;
udpport_counter+=(sgIP_timems&1023); // semi-random
if(udpport_counter>SGIP_UDP_LASTOUTGOINGPORT) udpport_counter=SGIP_UDP_FIRSTOUTGOINGPORT;
while(1) {
rec = udprecords;
myport=udpport_counter++;
if(udpport_counter>SGIP_UDP_LASTOUTGOINGPORT) udpport_counter=SGIP_UDP_FIRSTOUTGOINGPORT;
clear=1;
while(rec) {
if(rec->srcport==myport) { clear=0; break; }
rec=rec->next;
}
if(clear) return myport;
}
}
int sgIP_UDP_CalcChecksum(sgIP_memblock * mb, unsigned long srcip, unsigned long destip, int totallength) {
int checksum;
if(!mb) return 0;
if(mb->totallength&1) mb->datastart[mb->totallength]=0;
checksum=sgIP_memblock_IPChecksum(mb,0,mb->totallength);
// add in checksum of "faux header"
checksum+=(destip&0xFFFF);
checksum+=(destip>>16);
checksum+=(srcip&0xFFFF);
checksum+=(srcip>>16);
checksum+=htons(totallength);
checksum+=(17)<<8;
checksum=(checksum&0xFFFF) + (checksum>>16);
checksum=(checksum&0xFFFF) + (checksum>>16);
checksum = (~checksum)&0xFFFF;
if(checksum==0) checksum=0xFFFF;
return checksum;
}
int sgIP_UDP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip) {
if(!mb) return 0;
int chk = sgIP_UDP_CalcChecksum(mb,srcip,destip,mb->totallength);
if(chk!=0xFFFF) {
SGIP_DEBUG_MESSAGE(("UDP receive checksum incorrect"));
sgIP_memblock_free(mb);
return 0; // checksum error
}
sgIP_Header_UDP * udp;
udp=(sgIP_Header_UDP *)mb->datastart;
sgIP_Record_UDP * rec;
sgIP_memblock *tmb;
SGIP_INTR_PROTECT();
rec=udprecords;
while(rec) {
if((rec->srcip==destip || rec->srcip==0) && rec->srcport==udp->destport && rec->state!=SGIP_UDP_STATE_UNUSED) break; // a match!
rec=rec->next;
}
if(!rec) { // no matching records
sgIP_memblock_free(mb);
SGIP_INTR_UNPROTECT();
return 0;
}
// we have a record and a packet for it; add some data to the record and stuff it into the record queue.
sgIP_memblock_exposeheader(mb,4);
*((unsigned long *)mb->datastart)=srcip; // keep srcip around.
if(rec->incoming_queue==0) {
rec->incoming_queue=mb;
} else {
rec->incoming_queue_end->next=mb;
}
tmb=mb;
while(tmb->next) tmb=tmb->next;
rec->incoming_queue_end=tmb;
// ok, data added to queue - yay!
// that means... we're done.
SGIP_INTR_UNPROTECT();
return 0;
}
int sgIP_UDP_SendPacket(sgIP_Record_UDP * rec, const char * data, int datalen, unsigned long destip, int destport) {
if(!rec || !data) return SGIP_ERROR(EINVAL);
if(rec->state!=SGIP_UDP_STATE_BOUND) {
rec->srcip=0;
rec->srcport=sgIP_UDP_GetUnusedOutgoingPort();
rec->state=SGIP_UDP_STATE_BOUND;
}
sgIP_memblock * mb = sgIP_memblock_alloc(sgIP_IP_RequiredHeaderSize()+8+datalen);
if(!mb) return SGIP_ERROR(ENOMEM);
sgIP_memblock_exposeheader(mb,-sgIP_IP_RequiredHeaderSize()); // hide IP header space for later
SGIP_INTR_PROTECT();
unsigned long srcip = sgIP_IP_GetLocalBindAddr(rec->srcip,destip);
sgIP_Header_UDP * udp = (sgIP_Header_UDP *) mb->datastart;
udp->srcport=rec->srcport;
udp->destport=destport;
udp->length=htons(datalen+8);
udp->checksum=0;
int i;
for(i=0;i<datalen;i++) {
mb->datastart[i+8]=data[i];
}
udp->checksum=sgIP_UDP_CalcChecksum(mb,srcip,destip,mb->totallength);
sgIP_IP_SendViaIP(mb,17,srcip,destip);
SGIP_INTR_UNPROTECT();
return datalen;
}
sgIP_Record_UDP * sgIP_UDP_AllocRecord() {
SGIP_INTR_PROTECT();
sgIP_Record_UDP * rec;
rec = (sgIP_Record_UDP *)sgIP_malloc(sizeof(sgIP_Record_UDP));
if(rec) {
rec->destip=0;
rec->destport=0;
rec->incoming_queue=0;
rec->incoming_queue_end=0;
rec->srcip=0;
rec->srcport=0;
rec->state=0;
rec->next=udprecords;
udprecords=rec;
}
SGIP_INTR_UNPROTECT();
return rec;
}
void sgIP_UDP_FreeRecord(sgIP_Record_UDP * rec) {
if(!rec) return;
SGIP_INTR_PROTECT();
sgIP_Record_UDP * t;
// incoming queue is all clumped together as a single memblock, so, time to free it all in one call :)
if(rec->incoming_queue) sgIP_memblock_free(rec->incoming_queue); // woohoo!
rec->state=0;
if(udprecords==rec) {
udprecords=rec->next;
} else {
t=udprecords;
while(t) {
if(t->next==rec) {
t->next=rec->next;
break;
}
t=t->next;
}
}
sgIP_free(rec);
SGIP_INTR_UNPROTECT();
}
int sgIP_UDP_Bind(sgIP_Record_UDP * rec, int srcport, unsigned long srcip) {
if(!rec) return SGIP_ERROR(EINVAL);
SGIP_INTR_PROTECT();
if(rec->state!=SGIP_UDP_STATE_UNUSED) {
rec->srcip=srcip;
rec->srcport=srcport;
if(rec->state==SGIP_UDP_STATE_UNBOUND) rec->state=SGIP_UDP_STATE_BOUND;
}
SGIP_INTR_UNPROTECT();
return 0;
}
int sgIP_UDP_RecvFrom(sgIP_Record_UDP * rec, char * destbuf, int buflength, int flags, unsigned long * sender_ip, unsigned short * sender_port) {
if(!rec || !destbuf || !sender_ip || !sender_port || buflength==0) return SGIP_ERROR(EINVAL);
SGIP_INTR_PROTECT();
if(rec->incoming_queue==0) {
SGIP_INTR_UNPROTECT();
return SGIP_ERROR(EWOULDBLOCK);
}
int packetlen=rec->incoming_queue->totallength-12;
if(packetlen>buflength) {
SGIP_INTR_UNPROTECT();
return SGIP_ERROR(EMSGSIZE);
}
sgIP_memblock * mb;
*sender_ip=*((unsigned long *)rec->incoming_queue->datastart);
*sender_port=((unsigned short *)rec->incoming_queue->datastart)[2];
int totlen,first, buf_start,i;
totlen=rec->incoming_queue->totallength;
first=12;
buf_start=0;
while(totlen>0 && rec->incoming_queue) {
totlen-=rec->incoming_queue->thislength;
for(i=first;i<rec->incoming_queue->thislength;i++) {
destbuf[buf_start+i-first]=rec->incoming_queue->datastart[i];
}
buf_start+=rec->incoming_queue->thislength-first;
first=0;
mb=rec->incoming_queue;
rec->incoming_queue=rec->incoming_queue->next;
mb->next=0;
sgIP_memblock_free(mb);
}
if(!(rec->incoming_queue)) rec->incoming_queue_end=0;
SGIP_INTR_UNPROTECT();
return buf_start;
}
int sgIP_UDP_SendTo(sgIP_Record_UDP * rec, const char * buf, int buflength, int flags, unsigned long dest_ip, int dest_port) {
return sgIP_UDP_SendPacket(rec,buf,buflength,dest_ip,dest_port);
}
@@ -1,81 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_UDP_H
#define SGIP_UDP_H
#include "sgIP_Config.h"
#include "sgIP_memblock.h"
enum SGIP_UDP_STATE {
SGIP_UDP_STATE_UNBOUND, // newly allocated
SGIP_UDP_STATE_BOUND, // got a source address/port
SGIP_UDP_STATE_UNUSED, // no longer in use.
};
typedef struct SGIP_HEADER_UDP {
unsigned short srcport,destport;
unsigned short length,checksum;
} sgIP_Header_UDP;
typedef struct SGIP_RECORD_UDP {
struct SGIP_RECORD_UDP * next;
int state;
unsigned long srcip;
unsigned long destip;
unsigned short srcport,destport;
sgIP_memblock * incoming_queue;
sgIP_memblock * incoming_queue_end;
} sgIP_Record_UDP;
#ifdef __cplusplus
extern "C" {
#endif
void sgIP_UDP_Init(void);
int sgIP_UDP_CalcChecksum(sgIP_memblock * mb, unsigned long srcip, unsigned long destip, int totallength);
int sgIP_UDP_ReceivePacket(sgIP_memblock * mb, unsigned long srcip, unsigned long destip);
int sgIP_UDP_SendPacket(sgIP_Record_UDP * rec, const char * data, int datalen, unsigned long destip, int destport);
sgIP_Record_UDP * sgIP_UDP_AllocRecord(void);
void sgIP_UDP_FreeRecord(sgIP_Record_UDP * rec);
int sgIP_UDP_Bind(sgIP_Record_UDP * rec, int srcport, unsigned long srcip);
int sgIP_UDP_RecvFrom(sgIP_Record_UDP * rec, char * destbuf, int buflength, int flags, unsigned long * sender_ip, unsigned short * sender_port);
int sgIP_UDP_SendTo(sgIP_Record_UDP * rec, const char * buf, int buflength, int flags, unsigned long dest_ip, int dest_port);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,295 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#include "sgIP_memblock.h"
#include <stdlib.h>
#include <string.h>
#ifndef SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
#ifndef SGIP_USEDYNAMICMEMORY
sgIP_memblock memblock_pool[SGIP_MEMBLOCK_BASENUM];
#else
sgIP_memblock * memblock_pool;
#endif
sgIP_memblock * memblock_poolfree;
int numused, numfree;
void * pool_link;
sgIP_memblock * sgIP_memblock_getunused() {
int i;
sgIP_memblock * mb;
SGIP_INTR_PROTECT();
if(memblock_poolfree) { // we still have free memblocks!
mb=memblock_poolfree;
memblock_poolfree=mb->next;
numfree--;
numused++;
} else { // oh noes, we have no more free memblocks.
mb = 0; // eventually alloc new blocks, but for now just stop.
}
SGIP_INTR_UNPROTECT();
return mb;
}
#endif //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
void sgIP_memblock_Init() {
#ifndef SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
int i;
#ifdef SGIP_USEDYNAMICMEMORY
pool_link = sgIP_malloc(sizeof(sgIP_memblock)*SGIP_MEMBLOCK_BASENUM+4);
((long *)pool_link)[0]=0;
memblock_pool = (sgIP_memblock *) (((char *)pool_link)+4);
#endif
numused=numfree=0;
memblock_poolfree=0;
for(i=0;i<SGIP_MEMBLOCK_BASENUM;i++) {
memblock_pool[i].totallength=0;
memblock_pool[i].next=memblock_poolfree;
memblock_poolfree=memblock_pool+i;
numfree++;
}
#endif //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
}
#ifdef SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
sgIP_memblock * sgIP_memblock_allocHW(int headersize, int packetsize) {
sgIP_memblock * mb;
mb = (sgIP_memblock *) sgIP_malloc(SGIP_MEMBLOCK_HEADERSIZE+SGIP_MAXHWHEADER+packetsize);
if(!mb) return 0;
mb->totallength=headersize+packetsize;
mb->thislength=mb->totallength;
mb->datastart=mb->reserved+SGIP_MAXHWHEADER-headersize;
mb->next=0;
return mb;
}
#else //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
sgIP_memblock * sgIP_memblock_allocHW(int headersize, int packetsize) {
sgIP_memblock * mb, * tmb, *t;
int totlen;
mb = sgIP_memblock_getunused();
if(!mb) return 0;
mb->totallength=headersize+packetsize;
mb->datastart=mb->reserved+SGIP_MAXHWHEADER-headersize;
mb->next=0;
mb->thislength=headersize+SGIP_MEMBLOCK_FIRSTINTERNALSIZE;
if(mb->thislength>=mb->totallength) {
mb->thislength = mb->totallength;
// SGIP_DEBUG_MESSAGE(("memblock_alloc: %i free, %i used",numfree,numused));
return mb;
} else { // need more blocks
totlen=mb->thislength;
tmb=mb;
while(totlen<mb->totallength) {
t=sgIP_memblock_getunused();
if(!t) { // we're skrewed.
sgIP_memblock_free(mb);
return 0;
}
tmb->next=t;
t->totallength=mb->totallength;
t->datastart=mb->reserved; // no header on blocks after the first.
t->next=0;
t->thislength=SGIP_MEMBLOCK_INTERNALSIZE;
if(t->thislength+totlen>=mb->totallength) {
t->thislength=mb->totallength-totlen;
// SGIP_DEBUG_MESSAGE(("memblock_alloc: %i free, %i used",numfree,numused));
return mb;
} else { // need YET more blocks.
totlen+=t->thislength;
tmb=t;
} // the cycle contiues.
}
sgIP_memblock_free(mb); // should never get here.
}
return 0;
}
#endif //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
sgIP_memblock * sgIP_memblock_alloc(int packetsize) {
return sgIP_memblock_allocHW(0,packetsize);
}
#ifdef SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
void sgIP_memblock_free(sgIP_memblock * mb) {
sgIP_memblock * f;
SGIP_INTR_PROTECT();
while(mb) {
mb->totallength=0;
mb->thislength=0;
f=mb;
mb = mb->next;
sgIP_free(f);
}
SGIP_INTR_UNPROTECT();
}
#else //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
void sgIP_memblock_free(sgIP_memblock * mb) {
sgIP_memblock * f;
SGIP_INTR_PROTECT();
while(mb) {
mb->totallength=0;
mb->thislength=0;
f=mb;
mb = mb->next;
numfree++; // reinstate memblock into the pool!
numused--;
f->next=memblock_poolfree;
memblock_poolfree=f;
}
// SGIP_DEBUG_MESSAGE(("memblock_free: %i free, %i used",numfree,numused));
SGIP_INTR_UNPROTECT();
}
#endif //SGIP_MEMBLOCK_DYNAMIC_MALLOC_ALL
// positive to expose, negative to hide.
void sgIP_memblock_exposeheader(sgIP_memblock * mb, int change) {
if(mb) {
mb->thislength+=change;
mb->totallength+=change;
mb->datastart-=change;
while(mb->next) {
mb->next->totallength=mb->totallength;
mb=mb->next;
}
}
}
void sgIP_memblock_trimsize(sgIP_memblock * mb, int newsize) {
int lentot;
if(mb) {
mb->totallength=newsize;
lentot=0;
while(mb) {
lentot+=mb->thislength;
if(lentot>newsize) {
mb->thislength-=(lentot-newsize);
if(mb->next) sgIP_memblock_free(mb->next);
mb->next=0;
return;
} else {
mb=mb->next;
}
}
}
}
int sgIP_memblock_IPChecksum(sgIP_memblock * mb, int startbyte, int chksum_length) {
int chksum_temp,offset;
// check checksum
chksum_temp=0;
offset=0;
while(mb && startbyte>mb->thislength) { startbyte-=mb->thislength; mb=mb->next; }
if(!mb) return 0;
while(chksum_length) {
while(startbyte+offset+1<mb->thislength && chksum_length>1) {
chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset] + (((unsigned char *)mb->datastart)[startbyte+offset+1]<<8);
offset+=2;
chksum_length-=2;
}
chksum_temp= (chksum_temp&0xFFFF) +(chksum_temp>>16);
if(startbyte+offset<mb->thislength && chksum_length>0) {
chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset];
if(chksum_length==1) break;
chksum_length--;
offset=0;
startbyte=0;
mb=mb->next;
if(!mb) break;
if(mb->thislength==0) break;
chksum_temp+= ((unsigned char *)mb->datastart)[startbyte+offset]<<8;
if(chksum_length==1) break;
offset++;
chksum_length--;
}
}
chksum_temp= (chksum_temp&0xFFFF) +(chksum_temp>>16);
chksum_temp= (chksum_temp&0xFFFF) +(chksum_temp>>16);
return chksum_temp;
}
int sgIP_memblock_CopyToLinear(sgIP_memblock * mb, void * dest_buf, int startbyte, int copy_length) {
int copylen,ofs_src, tot_copy;
ofs_src=startbyte;
while(mb && ofs_src>=mb->thislength) { ofs_src-=mb->thislength; mb=mb->next; }
if(!mb) return 0;
if(startbyte+copy_length>mb->totallength) copy_length=mb->totallength-startbyte;
if(copy_length<0) copy_length=0;
tot_copy=0;
while(copy_length>0) {
copylen=copy_length;
if(copylen>mb->thislength-ofs_src) copylen=mb->thislength-ofs_src;
memcpy(((char *)dest_buf)+tot_copy,mb->datastart+ofs_src,copylen);
copy_length-=copylen;
tot_copy+=copylen;
ofs_src=0;
mb=mb->next;
if(!mb) break;
}
return tot_copy;
}
int sgIP_memblock_CopyFromLinear(sgIP_memblock * mb, void * src_buf, int startbyte, int copy_length) {
int copylen,ofs_src, tot_copy;
ofs_src=startbyte;
while(mb && ofs_src>=mb->thislength) { ofs_src-=mb->thislength; mb=mb->next; }
if(!mb) return 0;
if(startbyte+copy_length>mb->totallength) copy_length=mb->totallength-startbyte;
if(copy_length<0) copy_length=0;
tot_copy=0;
while(copy_length>0) {
copylen=copy_length;
if(copylen>mb->thislength-ofs_src) copylen=mb->thislength-ofs_src;
memcpy(mb->datastart+ofs_src,((char *)src_buf)+tot_copy,copylen);
copy_length-=copylen;
tot_copy+=copylen;
ofs_src=0;
mb=mb->next;
if(!mb) break;
}
return tot_copy;
}
int sgIP_memblock_CopyBlock(sgIP_memblock * mb_src, sgIP_memblock * mb_dest, int start_src, int start_dest, int copy_length) {
return 0;
}
@@ -1,65 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_MEMBLOCK_H
#define SGIP_MEMBLOCK_H
#include "sgIP_Config.h"
typedef struct SGIP_MEMBLOCK {
int totallength;
int thislength;
struct SGIP_MEMBLOCK * next;
char * datastart;
char reserved[SGIP_MEMBLOCK_DATASIZE-16]; // assume the other 4 values are 16 bytes total in length.
} sgIP_memblock;
#define SGIP_MEMBLOCK_HEADERSIZE 16
#define SGIP_MEMBLOCK_INTERNALSIZE (SGIP_MEMBLOCK_DATASIZE-16)
#define SGIP_MEMBLOCK_FIRSTINTERNALSIZE (SGIP_MEMBLOCK_DATASIZE-16-SGIP_MAXHWHEADER)
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_memblock_Init(void);
extern sgIP_memblock * sgIP_memblock_alloc(int packetsize);
extern sgIP_memblock * sgIP_memblock_allocHW(int headersize, int packetsize);
extern void sgIP_memblock_free(sgIP_memblock * mb);
extern void sgIP_memblock_exposeheader(sgIP_memblock * mb, int change);
extern void sgIP_memblock_trimsize(sgIP_memblock * mb, int newsize);
extern int sgIP_memblock_IPChecksum(sgIP_memblock * mb, int startbyte, int chksum_length);
extern int sgIP_memblock_CopyToLinear(sgIP_memblock * mb, void * dest_buf, int startbyte, int copy_length);
extern int sgIP_memblock_CopyFromLinear(sgIP_memblock * mb, void * src_buf, int startbyte, int copy_length);
extern int sgIP_memblock_CopyBlock(sgIP_memblock * mb_src, sgIP_memblock * mb_dest, int start_src, int start_dest, int copy_length);
#ifdef __cplusplus
};
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -1,83 +0,0 @@
// DSWifi Project - sgIP Internet Protocol Stack Implementation
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef SGIP_SOCKETS_H
#define SGIP_SOCKETS_H
#include "sgIP_Config.h"
#include "sys/socket.h"
#include "netinet/in.h"
#include "netdb.h"
#define SGIP_SOCKET_FLAG_ACTIVE 0x8000
#define SGIP_SOCKET_FLAG_NONBLOCKING 0x4000
#define SGIP_SOCKET_FLAG_TYPEMASK 0x0001
#define SGIP_SOCKET_FLAG_TYPE_TCP 0x0001
#define SGIP_SOCKET_FLAG_TYPE_UDP 0x0000
typedef struct SGIP_SOCKET_DATA {
unsigned int flags;
void * conn_ptr;
} sgIP_socket_data;
#ifdef __cplusplus
extern "C" {
#endif
extern void sgIP_sockets_Init();
// sys/socket.h
extern int socket(int domain, int type, int protocol);
extern int bind(int socket, const struct sockaddr * addr, int addr_len);
extern int connect(int socket, const struct sockaddr * addr, int addr_len);
extern int send(int socket, const void * data, int sendlength, int flags);
extern int recv(int socket, void * data, int recvlength, int flags);
extern int sendto(int socket, const void * data, int sendlength, int flags, const struct sockaddr * addr, int addr_len);
extern int recvfrom(int socket, void * data, int recvlength, int flags, struct sockaddr * addr, int * addr_len);
extern int listen(int socket, int max_connections);
extern int accept(int socket, struct sockaddr * addr, int * addr_len);
extern int shutdown(int socket, int shutdown_type);
extern int closesocket(int socket);
extern int ioctl(int socket, long cmd, void * arg);
extern int setsockopt(int socket, int level, int option_name, const void * data, int data_len);
extern int getsockopt(int socket, int level, int option_name, void * data, int * data_len);
extern int getpeername(int socket, struct sockaddr *addr, int * addr_len);
extern int getsockname(int socket, struct sockaddr *addr, int * addr_len);
// sys/time.h (actually intersects partly with libnds, so I'm letting libnds handle fd_set for the time being)
extern int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
// arpa/inet.h
extern unsigned long inet_addr(const char *cp);
#ifdef __cplusplus
};
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -1,122 +0,0 @@
// DS Wifi interface code
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
// wifi_arm9.c - arm9 wifi support header
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef WIFI_ARM9_H
#define WIFI_ARM9_H
#include "wifi_shared.h"
// default option is to use 128k heap
#define WIFIINIT_OPTION_USEHEAP_128 0x0000
#define WIFIINIT_OPTION_USEHEAP_64 0x1000
#define WIFIINIT_OPTION_USEHEAP_256 0x2000
#define WIFIINIT_OPTION_USEHEAP_512 0x3000
#define WIFIINIT_OPTION_USECUSTOMALLOC 0x4000
#define WIFIINIT_OPTION_HEAPMASK 0xF000
#ifdef WIFI_USE_TCP_SGIP
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
};
#endif
#endif
extern volatile Wifi_MainStruct * WifiData;
enum WIFIGETDATA {
WIFIGETDATA_MACADDRESS, // MACADDRESS: returns data in the buffer, requires at least 6 bytes
WIFIGETDATA_NUMWFCAPS, // NUM WFC APS: returns number between 0 and 3, doesn't use buffer.
MAX_WIFIGETDATA
};
// Wifi Packet Handler function: (int packetID, int packetlength) - packetID is only valid while the called function is executing.
// call Wifi_RxRawReadPacket while in the packet handler function, to retreive the data to a local buffer.
typedef void (*WifiPacketHandler)(int, int);
// Wifi Sync Handler function: Callback function that is called when the arm7 needs to be told to synchronize with new fifo data.
// If this callback is used (see Wifi_SetSyncHandler()), it should send a message via the fifo to the arm7, which will call Wifi_Sync() on arm7.
typedef void (*WifiSyncHandler)(void);
#ifdef __cplusplus
extern "C" {
#endif
extern void Wifi_CopyMacAddr(volatile void * dest, volatile void * src);
extern int Wifi_CmpMacAddr(volatile void * mac1, volatile void * mac2);
extern unsigned long Wifi_Init(int initflags);
extern int Wifi_CheckInit(void);
extern int Wifi_RawTxFrame(u16 datalen, u16 rate, u16 * data);
extern void Wifi_SetSyncHandler(WifiSyncHandler wshfunc);
extern void Wifi_RawSetPacketHandler(WifiPacketHandler wphfunc);
extern int Wifi_RxRawReadPacket(s32 packetID, s32 readlength, u16 * data);
extern void Wifi_DisableWifi(void);
extern void Wifi_EnableWifi(void);
extern void Wifi_SetPromiscuousMode(int enable);
extern void Wifi_ScanMode(void);
extern void Wifi_SetChannel(int channel);
extern int Wifi_GetNumAP(void);
extern int Wifi_GetAPData(int apnum, Wifi_AccessPoint * apdata);
extern int Wifi_FindMatchingAP(int numaps, Wifi_AccessPoint * apdata, Wifi_AccessPoint * match_dest);
extern int Wifi_ConnectAP(Wifi_AccessPoint * apdata, int wepmode, int wepkeyid, u8 * wepkey);
extern void Wifi_AutoConnect(void);
extern int Wifi_AssocStatus(void);
extern int Wifi_DisconnectAP(void);
extern int Wifi_GetData(int datatype, int bufferlen, unsigned char * buffer);
extern void Wifi_Update(void);
extern void Wifi_Sync(void);
#ifdef WIFI_USE_TCP_SGIP
extern void Wifi_Timer(int num_ms);
extern void Wifi_SetIP(u32 IPaddr, u32 gateway, u32 subnetmask, u32 dns1, u32 dns2);
extern u32 Wifi_GetIP(void);
#endif
#ifdef __cplusplus
};
#endif
#endif
@@ -1,179 +0,0 @@
//////////////////////////////////////////////////////////////////////////
// DSRegs.h - (c) 2005-2006 Stephen Stair
// General reference mumbo jumbo to give me easy access to the regs I like.
//////////////////////////////////////////////////////////////////////////
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef DSREGS_H
#define DSREGS_H
#include <nds.h>
//////////////////////////////////////////////////////////////////////////
// General registers
// general memory range defines
#define PAL ((u16 *) 0x05000000)
#define VRAM1 ((u16 *) 0x06000000)
#define VRAM2 ((u16 *) 0x06200000)
//#define OAM ((u16 *) 0x07000000)
#define CART ((u16 *) 0x08000000)
// video registers
#define DISPCNT (*((u32 volatile *) 0x04000000))
#define DISPSTAT (*((u16 volatile *) 0x04000004))
#define VCOUNT (*((u16 volatile *) 0x04000006))
#define BG0CNT (*((u16 volatile *) 0x04000008))
#define BG1CNT (*((u16 volatile *) 0x0400000A))
#define BG2CNT (*((u16 volatile *) 0x0400000C))
#define BG3CNT (*((u16 volatile *) 0x0400000E))
#define BG0HOFS (*((u16 volatile *) 0x04000010))
#define BG0VOFS (*((u16 volatile *) 0x04000012))
#define BG1HOFS (*((u16 volatile *) 0x04000014))
#define BG1VOFS (*((u16 volatile *) 0x04000016))
#define BG2HOFS (*((u16 volatile *) 0x04000018))
#define BG2VOFS (*((u16 volatile *) 0x0400001A))
#define BG3HOFS (*((u16 volatile *) 0x0400001C))
#define BG3VOFS (*((u16 volatile *) 0x0400001E))
#define BG2PA (*((u16 volatile *) 0x04000020))
#define BG2PB (*((u16 volatile *) 0x04000022))
#define BG2PC (*((u16 volatile *) 0x04000024))
#define BG2PD (*((u16 volatile *) 0x04000026))
#define BG2X (*((u32 volatile *) 0x04000028))
#define BG2Y (*((u32 volatile *) 0x0400002C))
#define BG3PA (*((u16 volatile *) 0x04000030))
#define BG3PB (*((u16 volatile *) 0x04000032))
#define BG3PC (*((u16 volatile *) 0x04000034))
#define BG3PD (*((u16 volatile *) 0x04000036))
#define BG3X (*((u32 volatile *) 0x04000038))
#define BG3Y (*((u32 volatile *) 0x0400003C))
#define WIN0H (*((u16 volatile *) 0x04000040))
#define WIN1H (*((u16 volatile *) 0x04000042))
#define WIN0V (*((u16 volatile *) 0x04000044))
#define WIN1V (*((u16 volatile *) 0x04000046))
#define WININ (*((u16 volatile *) 0x04000048))
#define WINOUT (*((u16 volatile *) 0x0400004A))
#define MOSAIC (*((u16 volatile *) 0x0400004C))
#define BLDCNT (*((u16 volatile *) 0x04000050))
#define BLDALPHA (*((u16 volatile *) 0x04000052))
#define BLDY (*((u16 volatile *) 0x04000054))
#define DISPCNT2 (*((u32 volatile *) 0x04001000))
#define DISPSTAT2 (*((u16 volatile *) 0x04001004))
#define VCOUNT2 (*((u16 volatile *) 0x04001006))
#define BG0CNT2 (*((u16 volatile *) 0x04001008))
#define BG1CNT2 (*((u16 volatile *) 0x0400100A))
#define BG2CNT2 (*((u16 volatile *) 0x0400100C))
#define BG3CNT2 (*((u16 volatile *) 0x0400100E))
#define BG0HOFS2 (*((u16 volatile *) 0x04001010))
#define BG0VOFS2 (*((u16 volatile *) 0x04001012))
#define BG1HOFS2 (*((u16 volatile *) 0x04001014))
#define BG1VOFS2 (*((u16 volatile *) 0x04001016))
#define BG2HOFS2 (*((u16 volatile *) 0x04001018))
#define BG2VOFS2 (*((u16 volatile *) 0x0400101A))
#define BG3HOFS2 (*((u16 volatile *) 0x0400101C))
#define BG3VOFS2 (*((u16 volatile *) 0x0400101E))
#define BG2PA2 (*((u16 volatile *) 0x04001020))
#define BG2PB2 (*((u16 volatile *) 0x04001022))
#define BG2PC2 (*((u16 volatile *) 0x04001024))
#define BG2PD2 (*((u16 volatile *) 0x04001026))
#define BG2X2 (*((u32 volatile *) 0x04001028))
#define BG2Y2 (*((u32 volatile *) 0x0400102C))
#define BG3PA2 (*((u16 volatile *) 0x04001030))
#define BG3PB2 (*((u16 volatile *) 0x04001032))
#define BG3PC2 (*((u16 volatile *) 0x04001034))
#define BG3PD2 (*((u16 volatile *) 0x04001036))
#define BG3X2 (*((u32 volatile *) 0x04001038))
#define BG3Y2 (*((u32 volatile *) 0x0400103C))
#define WIN0H2 (*((u16 volatile *) 0x04001040))
#define WIN1H2 (*((u16 volatile *) 0x04001042))
#define WIN0V2 (*((u16 volatile *) 0x04001044))
#define WIN1V2 (*((u16 volatile *) 0x04001046))
#define WININ2 (*((u16 volatile *) 0x04001048))
#define WINOUT2 (*((u16 volatile *) 0x0400104A))
#define MOSAIC2 (*((u16 volatile *) 0x0400104C))
#define BLDCNT2 (*((u16 volatile *) 0x04001050))
#define BLDALPHA2 (*((u16 volatile *) 0x04001052))
#define BLDY2 (*((u16 volatile *) 0x04001054))
// video memory defines
#define PAL_BG1 ((u16 *) 0x05000000)
#define PAL_FG1 ((u16 *) 0x05000200)
#define PAL_BG2 ((u16 *) 0x05000400)
#define PAL_FG2 ((u16 *) 0x05000600)
// other video defines
#define VRAMBANKCNT (((u16 volatile *) 0x04000240))
#define RGB(r,g,b) ( ((r)&31) | (((g)&31)<<5) | (((b)&31)<<10) )
#define VRAM_SETBANK(bank, set) \
if((bank)&1) { VRAMBANKCNT[(bank)>>1] = (VRAMBANKCNT[(bank)>>1]&0x00ff) | (((set)&0xff)<<8); } else \
{ VRAMBANKCNT[(bank)>>1] = (VRAMBANKCNT[(bank)>>1]&0xff00) | ((set)&0xff); }
// joypad input
#define KEYINPUT (*((u16 volatile *) 0x04000130))
#define KEYCNT (*((u16 volatile *) 0x04000132))
// System registers
#define WAITCNT (*((u16 volatile *) 0x04000204))
//#define IME (*((u16 volatile *) 0x04000208))
//#define IE (*((u32 volatile *) 0x04000210))
//#define IF (*((u32 volatile *) 0x04000214))
#define HALTCNT (*((u16 volatile *) 0x04000300))
//////////////////////////////////////////////////////////////////////////
// ARM7 specific registers
#ifdef ARM7
#define POWERCNT7 (*((u16 volatile *) 0x04000304))
#define SPI_CR (*((u16 volatile *) 0x040001C0))
#define SPI_DATA (*((u16 volatile *) 0x040001C2))
#endif
//////////////////////////////////////////////////////////////////////////
// ARM9 specific registers
#ifdef ARM9
#define POWERCNT (*((u16 volatile *) 0x04000308))
#endif
// End of file!
#endif
@@ -1,41 +0,0 @@
.text
.code 32
.GLOBL SLasm_Acquire, SLasm_Release
.ARM
SLasm_Acquire:
ldr r2,[r0]
cmp r2,#0
movne r0,#1
bxne lr
mov r2,r1
swp r2,r2,[r0]
cmp r2,#0
cmpne r2,r1
moveq r0,#0
bxeq lr
swp r2,r2,[r0]
mov r0,#1
bx lr
SLasm_Release:
ldr r2,[r0]
cmp r2,r1
movne r0,#2
bxne lr
mov r2,#0
swp r2,r2,[r0]
cmp r2,r1
moveq r0,#0
movne r0,#2
bx lr
.pool
.end
@@ -1,63 +0,0 @@
// DS Wifi interface code
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
// spinlock.h - code for spinlocking for basic wifi structure memory protection
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
/*
__asm__ (
".GLOBL SLasm_Acquire, SLasm_Release \n"
".ARM \n"
"SLasm_Acquire: \n"
" ldr r2,[r0] \n"
" cmp r2,#0 \n"
" movne r0,#1 \n"
" bxne lr \n"
" mov r2,r1 \n"
" swp r2,r2,[r0] \n"
" cmp r2,#0 \n"
" cmpne r2,r1 \n"
" moveq r0,#0 \n"
" bxeq lr \n"
" swp r2,r2,[r0] \n"
" mov r0,#1 \n"
" bx lr \n"
"\n\n"
"SLasm_Release: \n"
" ldr r2,[r0] \n"
" cmp r2,r1 \n"
" movne r0,#2 \n"
" bxne lr \n"
" mov r2,#0 \n"
" swp r2,r2,[r0] \n"
" cmp r2,r1 \n"
" moveq r0,#0 \n"
" movne r0,#2 \n"
" bx lr \n"
);
*/
@@ -1,284 +0,0 @@
// DS Wifi interface code
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
// wifi_shared.h - Shared structures to be used by arm9 and arm7
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef WIFI_SHARED_H
#define WIFI_SHARED_H
#include <nds.h>
// on spinlock contention, the side unsuccessfully attempting the lock reverts the lock.
// if the unlocking side sees the lock incorrectly set, the unlocking side will delay until it has reverted to the correct value, then continue unlocking.
// there should be a delay of at least about ~10-20 cycles between a lock and unlock, to prevent contention.
#define SPINLOCK_NOBODY 0x0000
#define SPINLOCK_ARM7 0x0001
#define SPINLOCK_ARM9 0x0002
#define SPINLOCK_OK 0x0000
#define SPINLOCK_INUSE 0x0001
#define SPINLOCK_ERROR 0x0002
#ifdef ARM7
#define SPINLOCK_VALUE SPINLOCK_ARM7
#endif
#ifdef ARM9
#define SPINLOCK_VALUE SPINLOCK_ARM9
#endif
#define Spinlock_Acquire(structtolock) SLasm_Acquire(&((structtolock).spinlock),SPINLOCK_VALUE)
#define Spinlock_Release(structtolock) SLasm_Release(&((structtolock).spinlock),SPINLOCK_VALUE)
#define Spinlock_Check(structtolock) (((structtolock).spinlock)!=SPINLOCK_NOBODY)
#ifdef __cplusplus
extern "C" {
#endif
extern u32 SLasm_Acquire(volatile u32 * lockaddr, u32 lockvalue);
extern u32 SLasm_Release(volatile u32 * lockaddr, u32 lockvalue);
#ifdef __cplusplus
};
#endif
// If for whatever reason you want to ditch SGIP and use your own stack, comment out the following line.
#define WIFI_USE_TCP_SGIP 1
#define WIFI_RXBUFFER_SIZE (1024*12)
#define WIFI_TXBUFFER_SIZE (1024*24)
#define WIFI_MAX_AP 32
#define WIFI_MAX_ASSOC_RETRY 30
#define WIFI_PS_POLL_CONST 2
#define WIFI_MAX_PROBE 4
#define WIFI_AP_TIMEOUT 40
#define WFLAG_PACKET_DATA 0x0001
#define WFLAG_PACKET_MGT 0x0002
#define WFLAG_PACKET_BEACON 0x0004
#define WFLAG_PACKET_CTRL 0x0008
#define WFLAG_PACKET_ALL 0xFFFF
#define WFLAG_ARM7_ACTIVE 0x0001
#define WFLAG_ARM7_RUNNING 0x0002
#define WFLAG_ARM9_ACTIVE 0x0001
#define WFLAG_ARM9_USELED 0x0002
#define WFLAG_ARM9_ARM7READY 0x0004
#define WFLAG_ARM9_NETUP 0x0008
#define WFLAG_ARM9_NETREADY 0x0010
#define WFLAG_ARM9_INITFLAGMASK 0x0002
#define WFLAG_IP_GOTDHCP 0x0001
// request - request flags
#define WFLAG_REQ_APCONNECT 0x0001
#define WFLAG_REQ_APCOPYVALUES 0x0002
#define WFLAG_REQ_APADHOC 0x0008
#define WFLAG_REQ_PROMISC 0x0010
#define WFLAG_REQ_USEWEP 0x0020
// request - informational flags
#define WFLAG_REQ_APCONNECTED 0x8000
#define WFLAG_APDATA_ADHOC 0x0001
#define WFLAG_APDATA_WEP 0x0002
#define WFLAG_APDATA_WPA 0x0004
#define WFLAG_APDATA_COMPATIBLE 0x0008
#define WFLAG_APDATA_EXTCOMPATIBLE 0x0010
#define WFLAG_APDATA_SHORTPREAMBLE 0x0020
#define WFLAG_APDATA_ACTIVE 0x8000
enum WIFI_RETURN {
WIFI_RETURN_OK = 0, // Everything went ok
WIFI_RETURN_LOCKFAILED = 1, // the spinlock attempt failed (it wasn't retried cause that could lock both cpus- retry again after a delay.
WIFI_RETURN_ERROR = 2, // There was an error in attempting to complete the requested task.
WIFI_RETURN_PARAMERROR = 3, // There was an error in the parameters passed to the function.
};
enum WIFI_STATS {
// software stats
WSTAT_RXQUEUEDPACKETS, // number of packets queued into the rx fifo
WSTAT_TXQUEUEDPACKETS, // number of packets queued into the tx fifo
WSTAT_RXQUEUEDBYTES, // number of bytes queued into the rx fifo
WSTAT_TXQUEUEDBYTES, // number of bytes queued into the tx fifo
WSTAT_RXQUEUEDLOST, // number of packets lost due to space limitations in queuing
WSTAT_TXQUEUEDREJECTED, // number of packets rejected due to space limitations in queuing
WSTAT_RXPACKETS,
WSTAT_RXBYTES,
WSTAT_RXDATABYTES,
WSTAT_TXPACKETS,
WSTAT_TXBYTES,
WSTAT_TXDATABYTES,
WSTAT_ARM7_UPDATES,
WSTAT_DEBUG,
// harware stats (function mostly unknown.)
WSTAT_HW_1B0,WSTAT_HW_1B1,WSTAT_HW_1B2,WSTAT_HW_1B3,WSTAT_HW_1B4,WSTAT_HW_1B5,WSTAT_HW_1B6,WSTAT_HW_1B7,
WSTAT_HW_1B8,WSTAT_HW_1B9,WSTAT_HW_1BA,WSTAT_HW_1BB,WSTAT_HW_1BC,WSTAT_HW_1BD,WSTAT_HW_1BE,WSTAT_HW_1BF,
WSTAT_HW_1C0,WSTAT_HW_1C1,WSTAT_HW_1C4,WSTAT_HW_1C5,
WSTAT_HW_1D0,WSTAT_HW_1D1,WSTAT_HW_1D2,WSTAT_HW_1D3,WSTAT_HW_1D4,WSTAT_HW_1D5,WSTAT_HW_1D6,WSTAT_HW_1D7,
WSTAT_HW_1D8,WSTAT_HW_1D9,WSTAT_HW_1DA,WSTAT_HW_1DB,WSTAT_HW_1DC,WSTAT_HW_1DD,WSTAT_HW_1DE,WSTAT_HW_1DF,
NUM_WIFI_STATS
};
enum WIFI_MODE {
WIFIMODE_DISABLED,
WIFIMODE_NORMAL,
WIFIMODE_SCAN,
WIFIMODE_ASSOCIATE,
WIFIMODE_ASSOCIATED,
WIFIMODE_DISASSOCIATE,
WIFIMODE_CANNOTASSOCIATE,
};
enum WIFI_AUTHLEVEL {
WIFI_AUTHLEVEL_DISCONNECTED,
WIFI_AUTHLEVEL_AUTHENTICATED,
WIFI_AUTHLEVEL_ASSOCIATED,
WIFI_AUTHLEVEL_DEASSOCIATED,
};
enum WEPMODES {
WEPMODE_NONE = 0,
WEPMODE_40BIT = 1,
WEPMODE_128BIT = 2
};
enum WIFI_ASSOCSTATUS {
ASSOCSTATUS_DISCONNECTED, // not *trying* to connect
ASSOCSTATUS_SEARCHING, // data given does not completely specify an AP, looking for AP that matches the data.
ASSOCSTATUS_AUTHENTICATING, // connecting...
ASSOCSTATUS_ASSOCIATING, // connecting...
ASSOCSTATUS_ACQUIRINGDHCP, // connected to AP, but getting IP data from DHCP
ASSOCSTATUS_ASSOCIATED, // Connected! (COMPLETE if Wifi_ConnectAP was called to start)
ASSOCSTATUS_CANNOTCONNECT, // error in connecting... (COMPLETE if Wifi_ConnectAP was called to start)
};
typedef struct WIFI_TXHEADER {
u16 enable_flags;
u16 unknown;
u16 countup;
u16 beaconfreq;
u16 tx_rate;
u16 tx_length;
} Wifi_TxHeader;
typedef struct WIFI_RXHEADER {
u16 a;
u16 b;
u16 c;
u16 d;
u16 byteLength;
u16 rssi_;
} Wifi_RxHeader;
typedef struct WIFI_ACCESSPOINT {
char ssid[33]; // 0-32byte data, zero
char ssid_len;
u8 bssid[6];
u8 macaddr[6];
u16 maxrate; // max rate is measured in steps of 1/2Mbit - 5.5Mbit will be represented as 11, or 0x0B
u32 timectr;
u16 rssi;
u16 flags;
u32 spinlock;
u8 channel;
u8 rssi_past[8];
u8 base_rates[16]; // terminated by a 0 entry
} Wifi_AccessPoint;
typedef struct WIFI_MAINSTRUCT {
unsigned long dummy1[8];
// wifi status
u16 curChannel, reqChannel;
u16 curMode, reqMode;
u16 authlevel,authctr;
u32 flags9, flags7, reqPacketFlags;
u16 curReqFlags, reqReqFlags;
u32 counter7,bootcounter7;
char MacAddr[6];
u16 authtype;
u16 iptype,ipflags;
u32 ip,snmask,gateway;
// current AP data
char ssid7[34],ssid9[34];
u8 bssid7[6], bssid9[6];
u8 apmac7[6], apmac9[6];
char wepmode7, wepmode9;
char wepkeyid7, wepkeyid9;
u8 wepkey7[20],wepkey9[20];
u8 baserates7[16], baserates9[16];
u8 apchannel7, apchannel9;
u8 maxrate7;
u16 ap_rssi;
u16 pspoll_period;
// AP data
Wifi_AccessPoint aplist[WIFI_MAX_AP];
// probe stuff
u8 probe9_numprobe;
u8 probe9_ssidlen[WIFI_MAX_PROBE];
char probe9_ssid[WIFI_MAX_PROBE][32];
// WFC data
u8 wfc_enable[4]; // wep mode, or 0x80 for "enabled"
Wifi_AccessPoint wfc_ap[3];
unsigned long wfc_config[3][5]; // ip, snmask, gateway, primarydns, 2nddns
u8 wfc_wepkey[3][16];
// wifi data
u32 rxbufIn, rxbufOut; // bufIn/bufOut have 2-byte granularity.
u16 rxbufData[WIFI_RXBUFFER_SIZE/2]; // send raw 802.11 data through! rxbuffer is for rx'd data, arm7->arm9 transfer
u32 txbufIn, txbufOut;
u16 txbufData[WIFI_TXBUFFER_SIZE/2]; // tx buffer is for data to tx, arm9->arm7 transfer
// stats data
u32 stats[NUM_WIFI_STATS];
u16 debug[30];
u32 random; // semirandom number updated at the convenience of the arm7. use for initial seeds & such.
unsigned long dummy2[8];
} Wifi_MainStruct;
#endif
@@ -1,27 +0,0 @@
DSWifi Project - sgIP Internet Protocol Stack Implementation
Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org
http://www.akkit.org
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -1,89 +0,0 @@
// DSWifi Project - Arm7 Library Header file (dswifi7.h)
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef DSWIFI7_H
#define DSWIFI7_H
#include "dswifi_version.h"
// Wifi Sync Handler function: Callback function that is called when the arm9 needs to be told to synchronize with new fifo data.
// If this callback is used (see Wifi_SetSyncHandler()), it should send a message via the fifo to the arm9, which will call Wifi_Sync() on arm9.
typedef void (*WifiSyncHandler)(void);
#ifdef __cplusplus
extern "C" {
#endif
// Read_Flash: Reads an arbitrary amount of data from the firmware flash chip
// int address: Offset to start reading from in the flash chip
// char * destination: Pointer to a memory buffer to hold incoming data
// int length: The number of bytes to read
extern void Read_Flash(int address, char * destination, int length);
// PowerChip_ReadWrite: Reads or writes a value to the DS's power chip
// int cmp: The byte-long command to send to the chip (top bit 1=read, 0=write - other bits = register ID to read/write)
// int data: The data to write to the chip (if sending a read command, this should be zero)
// Returns: The data read returned by the serial connection; only really useful when reading.
extern int PowerChip_ReadWrite(int cmd, int data);
// Wifi_Interrupt: Handler for the arm7 wifi interrupt. Should be called by the
// interrupt handler on arm7, and should *not* have multiple interrupts enabled.
extern void Wifi_Interrupt(void);
// Wifi_Update: Sync function to ensure data continues to flow between the two
// CPUs smoothly. Should be called at a periodic interval, such as in vblank.
extern void Wifi_Update(void);
// Wifi_Init: Requires the data returned by the arm9 wifi init call. The arm9
// init call's returned data must be passed to the arm7 and then given to this
// function. (or else very bad things happen)
// This function also enables power to the wifi system, which will shorten
// battery life.
// unsigned long WifiData: You must pass the 32bit value returned by the call to
// Wifi_Init on the ARM9.
extern void Wifi_Init(unsigned long WifiData);
// Wifi_Deinit: In the case that it is necessary, this function cuts power to
// the wifi system. After this the wifi will be unusable until Wifi_Init is
// called again.
extern void Wifi_Deinit(void);
// Wifi_Sync: Call this function when requested to sync by the arm9 side of the
// wifi lib
extern void Wifi_Sync(void);
// Wifi_SetSyncHandler: Call this function to request notification of when the
// ARM9-side Wifi_Sync function should be called.
// WifiSyncHandler sh: Pointer to the function to be called for notification.
extern void Wifi_SetSyncHandler(WifiSyncHandler sh);
#ifdef __cplusplus
};
#endif
#endif // DSWIFI7_H
@@ -1,337 +0,0 @@
// DSWifi Project - Arm9 Library Header File (dswifi9.h)
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef DSWIFI9_H
#define DSWIFI9_H
#include "dswifi_version.h"
// well, some flags and stuff are just stuffed in here and not documented very well yet... Most of the important stuff is documented though.
// Next version should clean up some of this a lot more :)
#define WIFIINIT_OPTION_USELED 0x0002
// default option is to use 128k heap
#define WIFIINIT_OPTION_USEHEAP_128 0x0000
#define WIFIINIT_OPTION_USEHEAP_64 0x1000
#define WIFIINIT_OPTION_USEHEAP_256 0x2000
#define WIFIINIT_OPTION_USEHEAP_512 0x3000
#define WIFIINIT_OPTION_USECUSTOMALLOC 0x4000
#define WIFIINIT_OPTION_HEAPMASK 0xF000
#define WFLAG_PACKET_DATA 0x0001
#define WFLAG_PACKET_MGT 0x0002
#define WFLAG_PACKET_BEACON 0x0004
#define WFLAG_PACKET_CTRL 0x0008
#define WFLAG_PACKET_ALL 0xFFFF
#define WFLAG_APDATA_ADHOC 0x0001
#define WFLAG_APDATA_WEP 0x0002
#define WFLAG_APDATA_WPA 0x0004
#define WFLAG_APDATA_COMPATIBLE 0x0008
#define WFLAG_APDATA_EXTCOMPATIBLE 0x0010
#define WFLAG_APDATA_SHORTPREAMBLE 0x0020
#define WFLAG_APDATA_ACTIVE 0x8000
enum WIFI_RETURN {
WIFI_RETURN_OK = 0, // Everything went ok
WIFI_RETURN_LOCKFAILED = 1, // the spinlock attempt failed (it wasn't retried cause that could lock both cpus- retry again after a delay.
WIFI_RETURN_ERROR = 2, // There was an error in attempting to complete the requested task.
WIFI_RETURN_PARAMERROR = 3, // There was an error in the parameters passed to the function.
};
enum WIFI_STATS {
// software stats
WSTAT_RXQUEUEDPACKETS, // number of packets queued into the rx fifo
WSTAT_TXQUEUEDPACKETS, // number of packets queued into the tx fifo
WSTAT_RXQUEUEDBYTES, // number of bytes queued into the rx fifo
WSTAT_TXQUEUEDBYTES, // number of bytes queued into the tx fifo
WSTAT_RXQUEUEDLOST, // number of packets lost due to space limitations in queuing
WSTAT_TXQUEUEDREJECTED, // number of packets rejected due to space limitations in queuing
WSTAT_RXPACKETS,
WSTAT_RXBYTES,
WSTAT_RXDATABYTES,
WSTAT_TXPACKETS,
WSTAT_TXBYTES,
WSTAT_TXDATABYTES,
// harware stats (function mostly unknown.)
WSTAT_HW_1B0,WSTAT_HW_1B1,WSTAT_HW_1B2,WSTAT_HW_1B3,WSTAT_HW_1B4,WSTAT_HW_1B5,WSTAT_HW_1B6,WSTAT_HW_1B7,
WSTAT_HW_1B8,WSTAT_HW_1B9,WSTAT_HW_1BA,WSTAT_HW_1BB,WSTAT_HW_1BC,WSTAT_HW_1BD,WSTAT_HW_1BE,WSTAT_HW_1BF,
WSTAT_HW_1C0,WSTAT_HW_1C1,WSTAT_HW_1C4,WSTAT_HW_1C5,
WSTAT_HW_1D0,WSTAT_HW_1D1,WSTAT_HW_1D2,WSTAT_HW_1D3,WSTAT_HW_1D4,WSTAT_HW_1D5,WSTAT_HW_1D6,WSTAT_HW_1D7,
WSTAT_HW_1D8,WSTAT_HW_1D9,WSTAT_HW_1DA,WSTAT_HW_1DB,WSTAT_HW_1DC,WSTAT_HW_1DD,WSTAT_HW_1DE,WSTAT_HW_1DF,
NUM_WIFI_STATS
};
// user code should NEVER have to use the WIFI_MODE or WIFI_AUTHLEVEL enums... is here in case I want to have some debug code...
enum WIFI_MODE {
WIFIMODE_DISABLED,
WIFIMODE_NORMAL,
WIFIMODE_SCAN,
WIFIMODE_ASSOCIATE,
WIFIMODE_ASSOCIATED,
WIFIMODE_DISASSOCIATE,
WIFIMODE_CANNOTASSOCIATE,
};
enum WIFI_AUTHLEVEL {
WIFI_AUTHLEVEL_DISCONNECTED,
WIFI_AUTHLEVEL_AUTHENTICATED,
WIFI_AUTHLEVEL_ASSOCIATED,
WIFI_AUTHLEVEL_DEASSOCIATED,
};
// user code uses members of the WIFIGETDATA structure in calling Wifi_GetData to retreive miscellaneous odd information
enum WIFIGETDATA {
WIFIGETDATA_MACADDRESS, // MACADDRESS: returns data in the buffer, requires at least 6 bytes
WIFIGETDATA_NUMWFCAPS, // NUM WFC APS: returns number between 0 and 3, doesn't use buffer.
MAX_WIFIGETDATA
};
enum WEPMODES {
WEPMODE_NONE = 0,
WEPMODE_40BIT = 1,
WEPMODE_128BIT = 2
};
// WIFI_ASSOCSTATUS - returned by Wifi_AssocStatus() after calling Wifi_ConnectAPk
enum WIFI_ASSOCSTATUS {
ASSOCSTATUS_DISCONNECTED, // not *trying* to connect
ASSOCSTATUS_SEARCHING, // data given does not completely specify an AP, looking for AP that matches the data.
ASSOCSTATUS_AUTHENTICATING, // connecting...
ASSOCSTATUS_ASSOCIATING, // connecting...
ASSOCSTATUS_ACQUIRINGDHCP, // connected to AP, but getting IP data from DHCP
ASSOCSTATUS_ASSOCIATED, // Connected! (COMPLETE if Wifi_ConnectAP was called to start)
ASSOCSTATUS_CANNOTCONNECT, // error in connecting... (COMPLETE if Wifi_ConnectAP was called to start)
};
// most user code will never need to know about the WIFI_TXHEADER or WIFI_RXHEADER
typedef struct WIFI_TXHEADER {
u16 enable_flags;
u16 unknown;
u16 countup;
u16 beaconfreq;
u16 tx_rate;
u16 tx_length;
} Wifi_TxHeader;
typedef struct WIFI_RXHEADER {
u16 a;
u16 b;
u16 c;
u16 d;
u16 byteLength;
u16 rssi_;
} Wifi_RxHeader;
// WIFI_ACCESSPOINT is an important structure in that it defines how to connect to an access point.
// listed inline are information about the members and their function
// if a field is not necessary for Wifi_ConnectAP it will be marked as such
// *only* 4 fields are absolutely required to be filled in correctly for the connection to work, they are:
// ssid, ssid_len, bssid, and channel - all others can be ignored (though flags should be set to 0)
typedef struct WIFI_ACCESSPOINT {
char ssid[33]; // the AP's SSID - zero terminated is not necessary.. if ssid[0] is zero, the ssid will be ignored in trying to find an AP to connect to. [REQUIRED]
char ssid_len; // number of valid bytes in the ssid field (0-32) [REQUIRED]
u8 bssid[6]; // BSSID is the AP's SSID - setting it to all 00's indicates this is not known and it will be ignored [REQUIRED]
u8 macaddr[6]; // mac address of the "AP" is only necessary in ad-hoc mode. [generally not required to connect]
u16 maxrate; // max rate is measured in steps of 1/2Mbit - 5.5Mbit will be represented as 11, or 0x0B [not required to connect]
u32 timectr; // internal information about how recently a beacon has been received [not required to connect]
u16 rssi; // running average of the recent RSSI values for this AP, will be set to 0 after not receiving beacons for a while. [not required to connect]
u16 flags; // flags indicating various parameters for the AP [not required, but the WFLAG_APDATA_ADHOC flag will be used]
u32 spinlock; // internal data word used to lock the record to guarantee data coherence [not required to connect]
u8 channel; // valid channels are 1-13, setting the channel to 0 will indicate the system should search. [REQUIRED]
u8 rssi_past[8]; // rssi_past indicates the RSSI values for the last 8 beacons received ([7] is the most recent) [not required to connect]
u8 base_rates[16]; // list of the base rates "required" by the AP (same format as maxrate) - zero-terminated list [not required to connect]
} Wifi_AccessPoint;
// Wifi Packet Handler function: (int packetID, int packetlength) - packetID is only valid while the called function is executing.
// call Wifi_RxRawReadPacket while in the packet handler function, to retreive the data to a local buffer.
typedef void (*WifiPacketHandler)(int, int);
// Wifi Sync Handler function: Callback function that is called when the arm7 needs to be told to synchronize with new fifo data.
// If this callback is used (see Wifi_SetSyncHandler()), it should send a message via the fifo to the arm7, which will call Wifi_Sync() on arm7.
typedef void (*WifiSyncHandler)(void);
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////////
// Init/update/state management functions
// Wifi_Init: Initializes the wifi library (arm9 side) and the sgIP library.
// int initflags: set up some optional things, like controlling the LED blinking.
// Returns: a 32bit value that *must* be passed to arm7.
extern unsigned long Wifi_Init(int initflags);
// Wifi_CheckInit: Verifies when the ARM7 has been successfully initialized
// Returns: 1 if the arm7 is ready for wifi, 0 otherwise
extern int Wifi_CheckInit(void);
// Wifi_DisableWifi: Instructs the ARM7 to disengage wireless and stop receiving or
// transmitting.
extern void Wifi_DisableWifi(void);
// Wifi_EnableWifi: Instructs the ARM7 to go into a basic "active" mode, not actually
// associated to an AP, but actively receiving and potentially transmitting
extern void Wifi_EnableWifi(void);
// Wifi_SetPromiscuousMode: Allows the DS to enter or leave a "promsicuous" mode, in which
// all data that can be received is forwarded to the arm9 for user processing.
// Best used with Wifi_RawSetPacketHandler, to allow user code to use the data
// (well, the lib won't use 'em, so they're just wasting CPU otherwise.)
// int enable: 0 to disable promiscuous mode, nonzero to engage
extern void Wifi_SetPromiscuousMode(int enable);
// Wifi_ScanMode: Instructs the ARM7 to periodically rotate through the channels to
// pick up and record information from beacons given off by APs
extern void Wifi_ScanMode(void);
// Wifi_SetChannel: If the wifi system is not connected or connecting to an access point, instruct
// the chipset to change channel
// int channel: the channel to change to, in the range of 1-13
extern void Wifi_SetChannel(int channel);
// Wifi_GetNumAP:
// Returns: the current number of APs that are known about and tracked internally
extern int Wifi_GetNumAP(void);
// Wifi_GetAPData: Grabs data from internal structures for user code (always succeeds)
// int apnum: the 0-based index of the access point record to fetch
// Wifi_AccessPoint * apdata: Pointer to the location where the retrieved data should be stored
extern int Wifi_GetAPData(int apnum, Wifi_AccessPoint * apdata);
// Wifi_FindMatchingAP: determines whether various APs exist in the local area. You provide a
// list of APs, and it will return the index of the first one in the list that can be found
// in the internal list of APs that are being tracked
// int numaps: number of records in the list
// Wifi_AccessPoint * apdata: pointer to an array of structures with information about the APs to find
// Wifi_AccessPoint * match_dest: OPTIONAL pointer to a record to receive the matching AP record.
// Returns: -1 for none found, or a positive/zero integer index into the array
extern int Wifi_FindMatchingAP(int numaps, Wifi_AccessPoint * apdata, Wifi_AccessPoint * match_dest);
// Wifi_ConnectAP: Connect to an access point
// Wifi_AccessPoint * apdata: basic data on the AP
// int wepmode: indicates whether wep is used, and what kind
// int wepkeyid: indicates which wep key ID to use for transmitting
// unsigned char * wepkey: the wep key, to be used in all 4 key slots (should make this more flexible in the future)
// Returns: 0 for ok, -1 for error with input data
extern int Wifi_ConnectAP(Wifi_AccessPoint * apdata, int wepmode, int wepkeyid, unsigned char * wepkey);
// Wifi_AutoConnect: Connect to an access point specified by the WFC data in the firmware
extern void Wifi_AutoConnect(void);
// Wifi_AssocStatus: Returns information about the status of connection to an AP
// Returns: a value from the WIFI_ASSOCSTATUS enum, continue polling until you
// receive ASSOCSTATUS_CONNECTED or ASSOCSTATUS_CANNOTCONNECT
extern int Wifi_AssocStatus(void);
// Wifi_DisconnectAP: Disassociate from the Access Point
extern int Wifi_DisconnectAP(void);
// Wifi_Timer: This function should be called in a periodic interrupt. It serves as the basis
// for all updating in the sgIP library, all retransmits, timeouts, and etc are based on this
// function being called. It's not timing critical but it is rather essential.
// int num_ms: The number of milliseconds since the last time this function was called.
extern void Wifi_Timer(int num_ms);
// Wifi_GetIP:
// Returns: The current IP address of the DS (may not be valid before connecting to an AP, or setting the IP manually.)
extern unsigned long Wifi_GetIP(void); // get local ip
// Wifi_GetIPInfo: (values may not be valid before connecting to an AP, or setting the IP manually.)
// unsigned long * pGateway: pointer to receive the currently configured gateway IP
// unsigned long * pSnmask: pointer to receive the currently configured subnet mask
// unsigned long * pDns1: pointer to receive the currently configured primary DNS server IP
// unsigned long * pDns2: pointer to receive the currently configured secondary DNS server IP
// Returns: The current IP address of the DS
extern unsigned long Wifi_GetIPInfo(unsigned long * pGateway,unsigned long * pSnmask,unsigned long * pDns1,unsigned long * pDns2);
// Wifi_SetIP: Set the DS's IP address and other IP configuration information.
// unsigned long IPaddr: The new IP address (NOTE! if this value is zero, the IP, the gateway, and the subnet mask will be allocated via DHCP)
// unsigned long gateway: The new gateway (example: 192.168.1.1 is 0xC0A80101)
// unsigned long subnetmask: The new subnet mask (example: 255.255.255.0 is 0xFFFFFF00)
// unsigned long dns1: The new primary dns server (NOTE! if this value is zero AND the IPaddr value is zero, dns1 and dns2 will be allocated via DHCP)
// unsigned long dns2: The new secondary dns server
extern void Wifi_SetIP(unsigned long IPaddr, unsigned long gateway, unsigned long subnetmask, unsigned long dns1, unsigned long dns2);
// Wifi_GetData: Retrieve an arbitrary or misc. piece of data from the wifi hardware. see WIFIGETDATA enum.
// int datatype: element from the WIFIGETDATA enum specifing what kind of data to get
// int bufferlen: length of the buffer to copy data to (not always used)
// unsigned char * buffer: buffer to copy element data to (not always used)
// Returns: -1 for failure, the number of bytes written to the buffer, or the value requested if the buffer isn't used.
extern int Wifi_GetData(int datatype, int bufferlen, unsigned char * buffer);
// Wifi_GetStats: Retreive an element of the wifi statistics gathered
// int statnum: Element from the WIFI_STATS enum, indicating what statistic to return
// Returns: the requested stat, or 0 for failure
extern u32 Wifi_GetStats(int statnum);
//////////////////////////////////////////////////////////////////////////
// Raw Send/Receive functions
// Wifi_RawTxFrame: Send a raw 802.11 frame at a specified rate
// unsigned short datalen: The length in bytes of the frame to send
// unsigned short rate: The rate to transmit at (Specified as mbits/10, 1mbit=0x000A, 2mbit=0x0014)
// unsigned short * data: Pointer to the data to send (should be halfword-aligned)
// Returns: Nothing of interest.
extern int Wifi_RawTxFrame(unsigned short datalen, unsigned short rate, unsigned short * data);
// Wifi_RawSetPacketHandler: Set a handler to process all raw incoming packets
// WifiPacketHandler wphfunc: Pointer to packet handler (see WifiPacketHandler definition for more info)
extern void Wifi_RawSetPacketHandler(WifiPacketHandler wphfunc);
// Wifi_RxRawReadPacket: Allows user code to read a packet from within the WifiPacketHandler function
// long packetID: a non-unique identifier which locates the packet specified in the internal buffer
// long readlength: number of bytes to read (actually reads (number+1)&~1 bytes)
// unsigned short * data: location for the data to be read into
extern int Wifi_RxRawReadPacket(long packetID, long readlength, unsigned short * data);
//////////////////////////////////////////////////////////////////////////
// Fast transfer support - update functions
// Wifi_Update: Checks for new data from the arm7 and initiates routing if data
// is available.
extern void Wifi_Update(void);
// Wifi_Sync: Call this function when requested to sync by the arm7 side of the
// wifi lib
extern void Wifi_Sync(void);
// Wifi_SetSyncHandler: Call this function to request notification of when the
// ARM7-side Wifi_Sync function should be called.
// WifiSyncHandler sh: Pointer to the function to be called for notification.
extern void Wifi_SetSyncHandler(WifiSyncHandler sh);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,10 +0,0 @@
#ifndef _dswifi_version_h_
#define _dswifi_version_h_
#define DSWIFI_MAJOR 0
#define DSWIFI_MINOR 3
#define DSWIFI_REVISION 4
#define DSWIFI_VERSION "0.3.4"
#endif // _dswifi_version_h_
@@ -1,49 +0,0 @@
// DSWifi Project - socket emulation layer defines/prototypes (netdb.h)
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef NETDB_H
#define NETDB_H
struct hostent {
char * h_name;
char ** h_aliases;
int h_addrtype;
int h_length;
char ** h_addr_list;
};
#ifdef __cplusplus
extern "C" {
#endif
extern struct hostent * gethostbyname(const char * name);
#ifdef __cplusplus
};
#endif
#endif
@@ -1,61 +0,0 @@
// DSWifi Project - socket emulation layer defines/prototypes (netinet/in.h)
// Copyright (C) 2005-2006 Stephen Stair - sgstair@akkit.org - http://www.akkit.org
/******************************************************************************
DSWifi Lib and test materials are licenced under the MIT open source licence:
Copyright (c) 2005-2006 Stephen Stair
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef NETINET_IN_H
#define NETINET_IN_H
#include "sys/socket.h"
#define INADDR_ANY 0x00000000
#define INADDR_BROADCAST 0xFFFFFFFF
#define INADDR_NONE 0xFFFFFFFF
struct in_addr {
unsigned long s_addr;
};
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
#ifdef __cplusplus
extern "C" {
#endif
// actually from arpa/inet.h - but is included through netinet/in.h
unsigned long inet_addr(const char *cp);
int inet_aton(const char *cp, struct in_addr *inp);
char *inet_ntoa(struct in_addr in);
#ifdef __cplusplus
};
#endif
#endif

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