Skip to content
Browse files

Merge Network code with webserver etc

Add some re entrancy fixes to circbuffer and ringbuffer
Allow network to be eliminated from build with make NONETWORK=1
  • Loading branch information...
1 parent bd81574 commit d4ee6ee239981a7fbc9fb24849182d5b9e2cee29 @wolfmanjm wolfmanjm committed Dec 22, 2013
Showing with 11,924 additions and 58 deletions.
  1. +10 −0 ConfigSamples/Smoothieboard/config
  2. +14 −2 build/common.mk
  3. +5 −0 mbed/src/mbed-lpc1768.mk
  4. +55 −0 smoothie-stream.py
  5. +100 −0 smoothie-upload.py
  6. +2 −2 src/libs/Kernel.cpp
  7. +56 −50 src/libs/Network/Drivers/LPC17XX_Ethernet.cpp
  8. +7 −4 src/libs/Network/Drivers/LPC17XX_Ethernet.h
  9. +3 −0 src/libs/Network/net_util.h
  10. +67 −0 src/libs/Network/uip/CallbackStream.cpp
  11. +34 −0 src/libs/Network/uip/CallbackStream.h
  12. +68 −0 src/libs/Network/uip/CommandQueue.cpp
  13. +33 −0 src/libs/Network/uip/CommandQueue.h
  14. +428 −0 src/libs/Network/uip/Network.cpp
  15. +49 −0 src/libs/Network/uip/Network.h
  16. +8 −0 src/libs/Network/uip/NetworkPublicAccess.h
  17. +18 −0 src/libs/Network/uip/c-fifo.h
  18. +53 −0 src/libs/Network/uip/clock-arch.c
  19. +50 −0 src/libs/Network/uip/clock-arch.h
  20. +388 −0 src/libs/Network/uip/dhcpc/dhcpc.c
  21. +76 −0 src/libs/Network/uip/dhcpc/dhcpc.h
  22. +39 −0 src/libs/Network/uip/fifo.cpp
  23. +180 −0 src/libs/Network/uip/fifo.h
  24. +104 −0 src/libs/Network/uip/lib/memb.c
  25. +141 −0 src/libs/Network/uip/lib/memb.h
  26. +228 −0 src/libs/Network/uip/sftp/sftpd.cpp
  27. +39 −0 src/libs/Network/uip/sftp/sftpd.h
  28. +280 −0 src/libs/Network/uip/telnetd/shell.cpp
  29. +104 −0 src/libs/Network/uip/telnetd/shell.h
  30. +413 −0 src/libs/Network/uip/telnetd/telnetd.cpp
  31. +84 −0 src/libs/Network/uip/telnetd/telnetd.h
  32. +168 −0 src/libs/Network/uip/uip-conf.h
  33. +95 −0 src/libs/Network/uip/uip/clock.h
  34. +83 −0 src/libs/Network/uip/uip/lc-addrlabels.h
  35. +76 −0 src/libs/Network/uip/uip/lc-switch.h
  36. +131 −0 src/libs/Network/uip/uip/lc.h
  37. +373 −0 src/libs/Network/uip/uip/psock.c
  38. +409 −0 src/libs/Network/uip/uip/psock.h
  39. +323 −0 src/libs/Network/uip/uip/pt.h
  40. +127 −0 src/libs/Network/uip/uip/timer.c
  41. +94 −0 src/libs/Network/uip/uip/timer.h
  42. +537 −0 src/libs/Network/uip/uip/uip-fw.c
  43. +176 −0 src/libs/Network/uip/uip/uip-fw.h
  44. +164 −0 src/libs/Network/uip/uip/uip-neighbor.c
  45. +61 −0 src/libs/Network/uip/uip/uip-neighbor.h
  46. +152 −0 src/libs/Network/uip/uip/uip-split.c
  47. +96 −0 src/libs/Network/uip/uip/uip-split.h
  48. +1,923 −0 src/libs/Network/uip/uip/uip.c
  49. +1,638 −0 src/libs/Network/uip/uip/uip.h
  50. +138 −0 src/libs/Network/uip/uip/uip_arch.h
  51. +428 −0 src/libs/Network/uip/uip/uip_arp.c
  52. +150 −0 src/libs/Network/uip/uip/uip_arp.h
  53. +74 −0 src/libs/Network/uip/uip/uiplib.c
  54. +71 −0 src/libs/Network/uip/uip/uiplib.h
  55. +546 −0 src/libs/Network/uip/uip/uipopt.h
  56. +41 −0 src/libs/Network/uip/webserver/http-strings
  57. +120 −0 src/libs/Network/uip/webserver/http-strings.c
  58. +40 −0 src/libs/Network/uip/webserver/http-strings.h
  59. +137 −0 src/libs/Network/uip/webserver/httpd-fs.c
  60. +57 −0 src/libs/Network/uip/webserver/httpd-fs.h
  61. +8 −0 src/libs/Network/uip/webserver/httpd-fs/404.html
  62. BIN src/libs/Network/uip/webserver/httpd-fs/img/control_xy.png
  63. BIN src/libs/Network/uip/webserver/httpd-fs/img/control_z.png
  64. +283 −0 src/libs/Network/uip/webserver/httpd-fs/index.html
  65. +69 −0 src/libs/Network/uip/webserver/httpd-fsdata.h
Sorry, we could not display the entire diff because it was too big.
View
10 ConfigSamples/Smoothieboard/config
@@ -181,3 +181,13 @@ currentcontrol_module_enable true #
return_error_on_unhandled_gcode false #
+# network settings
+network.enable false # enable the ethernet network services
+network.webserver.enable true # enable the webserver
+network.telnet.enable true # enable the telnet server
+network.ip_address auto # use dhcp to get ip address
+# uncomment the 3 below to manually setup ip address
+#network.ip_address 192.168.3.222 # the IP address
+#network.ip_mask 255.255.255.0 # the ip mask
+#network.ip_gateway 192.168.3.1 # the gateway address
+#network.mac_override xx.xx.xx.xx.xx.xx # override the mac address, only do this if you have a conflict
View
16 build/common.mk
@@ -76,12 +76,24 @@ MRI_INIT_PARAMETERS=$(MRI_UART)
OUTDIR=../$(DEVICE)
# List of sources to be compiled/assembled
-CSRCS = $(wildcard $(SRC)/*.c $(SRC)/*/*.c $(SRC)/*/*/*.c $(SRC)/*/*/*/*.c $(SRC)/*/*/*/*/*.c $(SRC)/*/*/*/*/*/*.c)
+CSRCS1 = $(wildcard $(SRC)/*.c $(SRC)/*/*.c $(SRC)/*/*/*.c $(SRC)/*/*/*/*.c $(SRC)/*/*/*/*/*.c $(SRC)/*/*/*/*/*/*.c)
+ifeq "$(NONETWORK)" "1"
+CSRCS = $(filter-out $(SRC)/libs/Network/%,$(CSRCS1))
+DEFINES += -DNONETWORK
+else
+CSRCS = $(CSRCS1)
+endif
+
ASRCS = $(wildcard $(SRC)/*.S $(SRC)/*/*.S $(SRC)/*/*/*.S $(SRC)/*/*/*/*.S $(SRC)/*/*/*/*/*.S)
ifneq "$(OS)" "Windows_NT"
ASRCS += $(wildcard $(SRC)/*.s $(SRC)/*/*.s $(SRC)/*/*/*.s $(SRC)/*/*/*/*.s $(SRC)/*/*/*/*/*.s)
endif
-CPPSRCS = $(wildcard $(SRC)/*.cpp $(SRC)/*/*.cpp $(SRC)/*/*/*.cpp $(SRC)/*/*/*/*.cpp $(SRC)/*/*/*/*/*.cpp $(SRC)/*/*/*/*/*/*.cpp)
+CPPSRCS1 = $(wildcard $(SRC)/*.cpp $(SRC)/*/*.cpp $(SRC)/*/*/*.cpp $(SRC)/*/*/*/*.cpp $(SRC)/*/*/*/*/*.cpp $(SRC)/*/*/*/*/*/*.cpp)
+ifeq "$(NONETWORK)" "1"
+CPPSRCS = $(filter-out $(SRC)/libs/Network/%,$(CPPSRCS1))
+else
+CPPSRCS = $(CPPSRCS1)
+endif
# List of the objects files to be compiled/assembled
OBJECTS = $(patsubst %.c,$(OUTDIR)/%.o,$(CSRCS)) $(patsubst %.s,$(OUTDIR)/%.o,$(patsubst %.S,$(OUTDIR)/%.o,$(ASRCS))) $(patsubst %.cpp,$(OUTDIR)/%.o,$(CPPSRCS))
View
5 mbed/src/mbed-lpc1768.mk
@@ -27,5 +27,10 @@ DEVICE=LPC1768
DEVICE_C_FLAGS =-mcpu=cortex-m3 -mthumb -mthumb-interwork
DEVICE_AS_FLAGS=-mcpu=cortex-m3 -mthumb
+# If compiling for newer smoothie boards set clock to 120MHz
+SMOOTHIEBETA?=1
+ifeq "$(SMOOTHIEBETA)" "0"
+DEVICE_C_FLAGS += -DUSE120MHZ
+endif
include arm-common.mk
View
55 smoothie-stream.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+"""\
+Stream g-code to Smoothie telnet connection
+
+Based on GRBL stream.py
+"""
+
+from __future__ import print_function
+import sys
+import telnetlib
+import argparse
+
+# Define command line argument interface
+parser = argparse.ArgumentParser(description='Stream g-code file to Smoothie over telnet.')
+parser.add_argument('gcode_file', type=argparse.FileType('r'),
+ help='g-code filename to be streamed')
+parser.add_argument('ipaddr',
+ help='Smoothie IP address')
+parser.add_argument('-q','--quiet',action='store_true', default=False,
+ help='suppress output text')
+args = parser.parse_args()
+
+f = args.gcode_file
+verbose = not args.quiet
+
+# Stream g-code to Smoothie
+print("Streaming " + args.gcode_file.name + " to " + args.ipaddr)
+
+tn = telnetlib.Telnet(args.ipaddr)
+# read startup prompt
+tn.read_until("> ")
+
+okcnt= 0
+linecnt= 0
+for line in f:
+ tn.write(line)
+ linecnt+=1
+ rep= tn.read_eager()
+ okcnt += rep.count("ok")
+ if verbose: print("SND " + str(linecnt) + ": " + line.strip() + " - " + str(okcnt))
+
+print("Waiting for complete...")
+
+while okcnt < linecnt:
+ rep= tn.read_some()
+ okcnt += rep.count("ok")
+ if verbose: print(str(linecnt) + " - " + str(okcnt) )
+
+tn.write("exit\n")
+tn.read_all()
+
+print("Done")
+
+
+
View
100 smoothie-upload.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+"""\
+Upload a file to Smoothie over the network
+"""
+
+from __future__ import print_function
+import sys
+import argparse
+import socket
+import os
+# Define command line argument interface
+parser = argparse.ArgumentParser(description='Upload a file to Smoothie over network.')
+parser.add_argument('file', type=argparse.FileType('r'),
+ help='filename to be uploaded')
+parser.add_argument('ipaddr',
+ help='Smoothie IP address')
+parser.add_argument('-v','--verbose',action='store_true',
+ help='Show data being uploaded')
+parser.add_argument('-o','--output',
+ help='Set output filename')
+parser.add_argument('-q','--quiet',action='store_true',
+ help='suppress all output to terminal')
+
+args = parser.parse_args()
+
+f = args.file
+verbose = args.verbose
+output = args.output
+if output == None :
+ output= args.file.name
+
+filesize= os.path.getsize(args.file.name)
+
+if not args.quiet : print("Uploading " + args.file.name + " to " + args.ipaddr + " as " + output + " size: " + str(filesize) )
+
+# make connection to sftp server
+s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+s.settimeout(4.0)
+s.connect((args.ipaddr, 115))
+tn= s.makefile()
+
+# read startup prompt
+ln= tn.readline()
+if not ln.startswith("+") :
+ print("Failed to connect with sftp: " + ln)
+ sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+# Issue initial store command
+tn.write("STOR OLD /sd/" + output + "\n")
+tn.flush()
+
+ln= tn.readline()
+if not ln.startswith("+") :
+ print("Failed to create file: " + ln)
+ sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+# send size of file
+tn.write("SIZE " + str(filesize) + "\n")
+tn.flush()
+
+ln= tn.readline()
+if not ln.startswith("+") :
+ print("Failed: " + ln)
+ sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+cnt= 0
+# now send file
+for line in f:
+ tn.write(line)
+ if verbose :
+ print("SND: " + line.strip())
+ elif not args.quiet :
+ cnt += len(line)
+ print(str(cnt) + "/" + str(filesize) + "\r", end='')
+
+
+tn.flush()
+
+ln= tn.readline()
+if not ln.startswith("+") :
+ print("Failed to save file: " + ln)
+ sys.exit();
+
+if verbose: print("RSP: " + ln.strip())
+
+# exit
+tn.write("DONE\n")
+tn.flush()
+ln= tn.readline()
+tn.close()
+f.close()
+
+if not args.quiet : print("Upload complete")
+
View
4 src/libs/Kernel.cpp
@@ -39,13 +39,13 @@ static int isDebugMonitorUsingUart0(){
// The kernel is the central point in Smoothie : it stores modules, and handles event calls
Kernel::Kernel(){
instance= this; // setup the Singleton instance of the kernel
-
+
// Config first, because we need the baud_rate setting before we start serial
this->config = new Config();
// Serial second, because the other modules might want to say something
this->streams = new StreamOutputPool();
-
+
// Configure UART depending on MRI config
// If MRI is using UART0, we want to use UART1, otherwise, we want to use UART0. This makes it easy to use only one UART for both debug and actual commands.
NVIC_SetPriorityGrouping(0);
View
106 src/libs/Network/Drivers/LPC17XX_Ethernet.cpp
@@ -1,6 +1,8 @@
-#if 0
+#if 1
#include "LPC17XX_Ethernet.h"
+#include "Kernel.h"
+
#include <cstring>
#include <cstdio>
@@ -153,33 +155,35 @@ int32_t emac_SetPHYMode(uint32_t ulPHYMode)
return (0);
}
-_rxbuf_t LPC17XX_Ethernet::rxbuf __attribute__ ((section ("AHBSRAM1")));
-_txbuf_t LPC17XX_Ethernet::txbuf __attribute__ ((section ("AHBSRAM1")));
+_rxbuf_t LPC17XX_Ethernet::rxbuf __attribute__ ((section ("AHBSRAM1"))) __attribute__((aligned(8)));
+_txbuf_t LPC17XX_Ethernet::txbuf __attribute__ ((section ("AHBSRAM1"))) __attribute__((aligned(8)));
LPC17XX_Ethernet* LPC17XX_Ethernet::instance;
LPC17XX_Ethernet::LPC17XX_Ethernet()
{
- mac_address[0] = 0xAE;
- mac_address[1] = 0xF0;
- mac_address[2] = 0x28;
- mac_address[3] = 0x5D;
- mac_address[4] = 0x66;
- mac_address[5] = 0x41;
-
- ip_address = IPA(192,168,1,27);
- ip_mask = 0xFFFFFF00;
-
- for (int i = 0; i < 5; i++)
- {
+ // TODO these need to be configurable
+ // mac_address[0] = 0xAE;
+ // mac_address[1] = 0xF0;
+ // mac_address[2] = 0x28;
+ // mac_address[3] = 0x5D;
+ // mac_address[4] = 0x66;
+ // mac_address[5] = 0x41;
+
+ // ip_address = IPA(192,168,3,222);
+ // ip_mask = 0xFFFFFF00;
+
+ for (int i = 0; i < LPC17XX_RXBUFS; i++) {
rxbuf.rxdesc[i].packet = rxbuf.buf[i];
- rxbuf.rxdesc[i].control = (1536 - 1) | EMAC_RCTRL_INT;
+ rxbuf.rxdesc[i].control = (LPC17XX_MAX_PACKET - 1) | EMAC_RCTRL_INT;
rxbuf.rxstat[i].Info = 0;
rxbuf.rxstat[i].HashCRC = 0;
+ }
+ for (int i = 0; i < LPC17XX_TXBUFS; i++) {
txbuf.txdesc[i].packet = txbuf.buf[i];
- txbuf.txdesc[i].control = (1536 - 1) | EMAC_TCTRL_PAD | EMAC_TCTRL_CRC | EMAC_TCTRL_LAST | EMAC_TCTRL_INT;
+ txbuf.txdesc[i].control = (LPC17XX_MAX_PACKET - 1) | EMAC_TCTRL_PAD | EMAC_TCTRL_CRC | EMAC_TCTRL_LAST | EMAC_TCTRL_INT;
txbuf.txstat[i].Info = 0;
}
@@ -202,19 +206,24 @@ void LPC17XX_Ethernet::on_module_loaded()
emac_init();
printf("INIT OK\n");
- register_for_event(ON_IDLE);
+ //register_for_event(ON_IDLE);
register_for_event(ON_SECOND_TICK);
}
void LPC17XX_Ethernet::on_idle(void*)
{
- _receive_frame();
+ //_receive_frame();
+}
+
+void LPC17XX_Ethernet::on_second_tick(void *) {
+ check_interface();
}
-void LPC17XX_Ethernet::on_second_tick(void*)
+void LPC17XX_Ethernet::check_interface()
{
// LPC_EMAC->Command = 0x303;
// setEmacAddr(mac_address);
+
uint32_t st;
st = read_PHY (EMAC_PHY_REG_BMSR);
@@ -243,6 +252,7 @@ void LPC17XX_Ethernet::on_second_tick(void*)
printf("Unknown speed: SCSR = 0x%04lX\n", scsr);
break;
}
+ printf("MAC Address: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n", (LPC_EMAC->SA2) & 0xFF, (LPC_EMAC->SA2 >> 8) & 0xFF, (LPC_EMAC->SA1) & 0xFF, (LPC_EMAC->SA1 >> 8) & 0xFF, (LPC_EMAC->SA0) & 0xFF, (LPC_EMAC->SA0 >> 8) & 0xFF);
}
else if (((st & EMAC_PHY_BMSR_LINK_ESTABLISHED) == 0) && up)
{
@@ -252,13 +262,13 @@ void LPC17XX_Ethernet::on_second_tick(void*)
printf("%s: link down\n", interface_name);
}
-// printf("PHY: id:%04lX %04lX st:%04lX\n", id1, id2, st);
-// printf("ETH: Rx:%lu/%lu Tx:%lu/%lu\n", LPC_EMAC->RxConsumeIndex, LPC_EMAC->RxProduceIndex, LPC_EMAC->TxProduceIndex, LPC_EMAC->TxConsumeIndex);
-// printf("MII: 0x%1lX\n", LPC_EMAC->MIND);
-// printf("Command: 0x%03lX Status: 0x%1lX\n", LPC_EMAC->Command, LPC_EMAC->Status);
-// printf("RxN: %lu TxN: %lu\n", LPC_EMAC->RxDescriptorNumber, LPC_EMAC->TxDescriptorNumber);
-// printf("MAC1: 0x%04lX MAC2: 0x%04lX\n", LPC_EMAC->MAC1, LPC_EMAC->MAC2);
-// printf("MAC Address: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n", (LPC_EMAC->SA2) & 0xFF, (LPC_EMAC->SA2 >> 8) & 0xFF, (LPC_EMAC->SA1) & 0xFF, (LPC_EMAC->SA1 >> 8) & 0xFF, (LPC_EMAC->SA0) & 0xFF, (LPC_EMAC->SA0 >> 8) & 0xFF);
+ //printf("PHY: id:%04lX %04lX st:%04lX\n", id1, id2, st);
+ // printf("ETH: Rx:%lu/%lu Tx:%lu/%lu\n", LPC_EMAC->RxConsumeIndex, LPC_EMAC->RxProduceIndex, LPC_EMAC->TxProduceIndex, LPC_EMAC->TxConsumeIndex);
+ // printf("MII: 0x%1lX\n", LPC_EMAC->MIND);
+ // printf("Command: 0x%03lX Status: 0x%1lX\n", LPC_EMAC->Command, LPC_EMAC->Status);
+ // printf("RxN: %lu TxN: %lu\n", LPC_EMAC->RxDescriptorNumber, LPC_EMAC->TxDescriptorNumber);
+ // printf("MAC1: 0x%04lX MAC2: 0x%04lX\n", LPC_EMAC->MAC1, LPC_EMAC->MAC2);
+ // printf("MAC Address: %02lX:%02lX:%02lX:%02lX:%02lX:%02lX\n", (LPC_EMAC->SA2) & 0xFF, (LPC_EMAC->SA2 >> 8) & 0xFF, (LPC_EMAC->SA1) & 0xFF, (LPC_EMAC->SA1 >> 8) & 0xFF, (LPC_EMAC->SA0) & 0xFF, (LPC_EMAC->SA0 >> 8) & 0xFF);
}
void LPC17XX_Ethernet::emac_init()
@@ -337,11 +347,11 @@ void LPC17XX_Ethernet::emac_init()
/* Initialize Tx and Rx DMA Descriptors */
LPC_EMAC->RxDescriptor = (uint32_t) rxbuf.rxdesc;
LPC_EMAC->RxStatus = (uint32_t) rxbuf.rxstat;
- LPC_EMAC->RxDescriptorNumber = 4;
+ LPC_EMAC->RxDescriptorNumber = LPC17XX_RXBUFS-1;
LPC_EMAC->TxDescriptor = (uint32_t) txbuf.txdesc;
LPC_EMAC->TxStatus = (uint32_t) txbuf.txstat;
- LPC_EMAC->TxDescriptorNumber = 4;
+ LPC_EMAC->TxDescriptorNumber = LPC17XX_TXBUFS-1;
// Set Receive Filter register: enable broadcast and multicast
LPC_EMAC->RxFilterCtrl = EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;
@@ -364,42 +374,38 @@ void LPC17XX_Ethernet::set_mac(uint8_t* newmac)
memcpy(mac_address, newmac, 6);
}
-void LPC17XX_Ethernet::_receive_frame()
+bool LPC17XX_Ethernet::_receive_frame(void *packet, int *size)
{
if (can_read_packet() && can_write_packet())
{
int i = LPC_EMAC->RxConsumeIndex;
RX_Stat* stat = &(rxbuf.rxstat[i]);
- NET_PACKET packet = (NET_PACKET) rxbuf.buf[i];
+ *size = stat->Info & EMAC_RINFO_SIZE;
+ memcpy(packet, rxbuf.buf[i], *size);
- int size = stat->Info & EMAC_RINFO_SIZE;
- printf("Received %d byte Ethernet frame %lu/%lu\n", size, LPC_EMAC->RxProduceIndex, LPC_EMAC->RxConsumeIndex);
-
-// TODO: feed received packet to network stack here
-// int s = net->receive_packet(this, packet, size);
-// if (s)
-// {
-// memcpy(request_packet_buffer(), packet, s);
-// write_packet((uint8_t*) request_packet_buffer(), s);
-// }
+ //printf("Received %d byte Ethernet frame %lu/%lu\n", *size, LPC_EMAC->RxProduceIndex, LPC_EMAC->RxConsumeIndex);
uint32_t r = LPC_EMAC->RxConsumeIndex + 1;
if (r > LPC_EMAC->RxDescriptorNumber)
r = 0;
LPC_EMAC->RxConsumeIndex = r;
+
+ return true;
}
+
+ return false;
}
void LPC17XX_Ethernet::irq()
{
- if (EMAC_IntGetStatus(EMAC_INT_RX_DONE))
- {
- _receive_frame();
- }
-
- if (EMAC_IntGetStatus(EMAC_INT_TX_DONE))
- {
- }
+ // if (EMAC_IntGetStatus(EMAC_INT_RX_DONE))
+ // {
+ // //_receive_frame();
+ // }
+
+ // if (EMAC_IntGetStatus(EMAC_INT_TX_DONE))
+ // {
+ // }
}
bool LPC17XX_Ethernet::can_read_packet()
@@ -431,7 +437,7 @@ bool LPC17XX_Ethernet::can_write_packet()
int LPC17XX_Ethernet::write_packet(uint8_t* buf, int size)
{
- txbuf.txdesc[LPC_EMAC->TxProduceIndex].control = size | EMAC_TCTRL_LAST | EMAC_TCTRL_CRC | EMAC_TCTRL_PAD | EMAC_TCTRL_INT;
+ txbuf.txdesc[LPC_EMAC->TxProduceIndex].control = ((size - 1) & 0x7ff) | EMAC_TCTRL_LAST | EMAC_TCTRL_CRC | EMAC_TCTRL_PAD | EMAC_TCTRL_INT;
uint32_t r = LPC_EMAC->TxProduceIndex + 1;
if (r > LPC_EMAC->TxDescriptorNumber)
View
11 src/libs/Network/Drivers/LPC17XX_Ethernet.h
@@ -11,9 +11,9 @@
// SMSC 8720A special control/status register
#define EMAC_PHY_REG_SCSR 0x1F
-#define LPC17XX_MAX_PACKET 1536
-#define LPC17XX_TXBUFS 5
-#define LPC17XX_RXBUFS 5
+#define LPC17XX_MAX_PACKET 600
+#define LPC17XX_TXBUFS 4
+#define LPC17XX_RXBUFS 4
typedef struct {
void* packet;
@@ -49,7 +49,7 @@ class LPC17XX_Ethernet : public Module, public NetworkInterface
void irq(void);
- void _receive_frame(void);
+ bool _receive_frame(void *packet, int* size);
// NetworkInterface methods
// void provide_net(netcore* n);
@@ -72,8 +72,11 @@ class LPC17XX_Ethernet : public Module, public NetworkInterface
static LPC17XX_Ethernet* instance;
+private:
static _rxbuf_t rxbuf;
static _txbuf_t txbuf;
+
+ void check_interface();
};
#endif /* _LPC17XX_ETHERNET_H */
View
3 src/libs/Network/net_util.h
@@ -75,6 +75,8 @@ class NetworkInterface : public Encapsulator {
virtual void set_ip(uint32_t new_ip) { ip_address = new_ip; };
virtual void set_mac(uint8_t new_mac[6]) { memcpy(mac_address, new_mac, 6); };
+ bool isUp() { return up; }
+
// netcore* net;
uint8_t* interface_name;
@@ -92,5 +94,6 @@ bool compare_mac(const uint8_t*, const uint8_t*, const uint8_t*);
int format_mac(uint8_t*, uint8_t*);
int format_ip(uint32_t, uint8_t*);
int checksum16(uint8_t*, int, int);
+uint32_t crc32(uint8_t* buf, int length);
#endif /* _NET_UTIL_H */
View
67 src/libs/Network/uip/CallbackStream.cpp
@@ -0,0 +1,67 @@
+#include "CallbackStream.h"
+#include "Kernel.h"
+
+#define DEBUG_PRINTF std::printf
+
+CallbackStream::CallbackStream(cb_t cb, void *u)
+{
+ DEBUG_PRINTF("Callbackstream ctor: %p\n", this);
+ callback= cb;
+ user= u;
+ closed= false;
+ use_count= 0;
+}
+
+CallbackStream::~CallbackStream()
+{
+ DEBUG_PRINTF("Callbackstream dtor: %p\n", this);
+}
+
+int CallbackStream::puts(const char *s)
+{
+ if(closed) return 0;
+
+ if(s == NULL) return (*callback)(NULL, user);
+
+ int len = strlen(s);
+ int n;
+ do {
+ // call this streams result callback
+ n= (*callback)(s, user);
+
+ // if closed just pretend we sent it
+ if(n == -1) {
+ closed= true;
+ return len;
+
+ }else if(n == 0) {
+ // if output queue is full
+ // call idle until we can output more
+ THEKERNEL->call_event(ON_IDLE);
+ }
+ } while(n == 0);
+
+ return len;
+}
+
+void CallbackStream::mark_closed()
+{
+ closed= true;
+ if(use_count <= 0) delete this;
+}
+void CallbackStream::dec()
+{
+ use_count--;
+ if(closed && use_count <= 0) delete this;
+}
+
+extern "C" void *new_callback_stream(cb_t cb, void *u)
+{
+ return new CallbackStream(cb, u);
+}
+
+extern "C" void delete_callback_stream(void *p)
+{
+ // we don't delete it in case it is still on the command queue
+ ((CallbackStream*)p)->mark_closed();
+}
View
34 src/libs/Network/uip/CallbackStream.h
@@ -0,0 +1,34 @@
+#ifndef CALLBACKSTREAM_H
+#define CALLBACKSTREAM_H
+
+typedef int (*cb_t)(const char *, void *);
+
+#ifdef __cplusplus
+#include "libs/StreamOutput.h"
+
+
+class CallbackStream : public StreamOutput {
+ public:
+ CallbackStream(cb_t cb, void *u);
+ virtual ~CallbackStream();
+ int puts(const char*);
+ void inc() { use_count++; }
+ void dec();
+ int get_count() { return use_count; }
+ void mark_closed();
+
+ private:
+ cb_t callback;
+ void *user;
+ bool closed;
+ int use_count;
+};
+
+#else
+
+extern void *new_callback_stream(cb_t cb, void *);
+extern void delete_callback_stream(void *);
+
+#endif // __cplusplus
+
+#endif
View
68 src/libs/Network/uip/CommandQueue.cpp
@@ -0,0 +1,68 @@
+#include "CommandQueue.h"
+
+#include "stdio.h"
+#include "string.h"
+#include "stdlib.h"
+
+#include "Kernel.h"
+#include "libs/SerialMessage.h"
+#include "CallbackStream.h"
+
+static CommandQueue *command_queue_instance;
+CommandQueue *CommandQueue::instance = NULL;
+
+
+CommandQueue::CommandQueue()
+{
+ command_queue_instance = this;
+ null_stream= &(StreamOutput::NullStream);
+}
+
+CommandQueue* CommandQueue::getInstance()
+{
+ if(instance == 0) instance= new CommandQueue();
+ return instance;
+}
+
+extern "C" {
+ int network_add_command(const char *cmd, void *pstream)
+ {
+ return command_queue_instance->add(cmd, (StreamOutput*)pstream);
+ }
+}
+
+int CommandQueue::add(const char *cmd, StreamOutput *pstream)
+{
+ cmd_t c= {strdup(cmd), pstream==NULL?null_stream:pstream};
+ q.push(c);
+ if(pstream != NULL) {
+ // count how many times this is on the queue
+ CallbackStream *s= static_cast<CallbackStream *>(pstream);
+ s->inc();
+ }
+ return q.size();
+}
+
+// pops the next command off the queue and submits it.
+bool CommandQueue::pop()
+{
+ if (q.size() == 0) return false;
+
+ cmd_t c= q.pop();
+ char *cmd= c.str;
+
+ struct SerialMessage message;
+ message.message = cmd;
+ message.stream = c.pstream;
+
+ free(cmd);
+ THEKERNEL->call_event(ON_CONSOLE_LINE_RECEIVED, &message );
+
+ if(message.stream != null_stream) {
+ message.stream->puts(NULL); // indicates command is done
+ // decrement usage count
+ CallbackStream *s= static_cast<CallbackStream *>(message.stream);
+ s->dec();
+ }
+ return true;
+}
View
33 src/libs/Network/uip/CommandQueue.h
@@ -0,0 +1,33 @@
+#ifndef _COMMANDQUEUE_H_
+#define _COMMANDQUEUE_H_
+
+#ifdef __cplusplus
+
+#include "fifo.h"
+#include <string>
+
+#include "StreamOutput.h"
+
+class CommandQueue
+{
+public:
+ CommandQueue();
+ ~CommandQueue();
+ bool pop();
+ int add(const char* cmd, StreamOutput *pstream);
+ int size() {return q.size();}
+ static CommandQueue* getInstance();
+
+private:
+ typedef struct {char* str; StreamOutput *pstream; } cmd_t;
+ Fifo<cmd_t> q;
+ static CommandQueue *instance;
+ StreamOutput *null_stream;
+};
+
+#else
+
+extern int network_add_command(const char * cmd, void *pstream);
+#endif
+
+#endif
View
428 src/libs/Network/uip/Network.cpp
@@ -0,0 +1,428 @@
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+#include "CommandQueue.h"
+
+#include "Kernel.h"
+
+#include "Network.h"
+#include "PublicDataRequest.h"
+#include "PlayerPublicAccess.h"
+#include "net_util.h"
+#include "uip_arp.h"
+#include "clock-arch.h"
+
+#include "uip.h"
+#include "telnetd.h"
+#include "webserver.h"
+#include "dhcpc.h"
+#include "sftpd.h"
+
+
+#include <mri.h>
+
+#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
+
+extern "C" void uip_log(char *m)
+{
+ printf("uIP log message: %s\n", m);
+}
+
+static bool webserver_enabled, telnet_enabled, use_dhcp;
+static Network *theNetwork;
+static Sftpd *sftpd;
+static CommandQueue *command_q= CommandQueue::getInstance();
+
+Network* Network::instance;
+Network::Network()
+{
+ ethernet = new LPC17XX_Ethernet();
+ tickcnt= 0;
+ theNetwork= this;
+ sftpd= NULL;
+ instance= this;
+}
+
+Network::~Network()
+{
+ delete ethernet;
+}
+
+static uint32_t getSerialNumberHash()
+{
+#define IAP_LOCATION 0x1FFF1FF1
+ uint32_t command[1];
+ uint32_t result[5];
+ typedef void (*IAP)(uint32_t *, uint32_t *);
+ IAP iap = (IAP) IAP_LOCATION;
+
+ __disable_irq();
+
+ command[0] = 58;
+ iap(command, result);
+ __enable_irq();
+ return crc32((uint8_t *)&result[1], 4 * 4);
+}
+
+static bool parse_ip_str(const string &s, uint8_t *a, int len, char sep = '.')
+{
+ int p = 0;
+ const char *n;
+ for (int i = 0; i < len; i++) {
+ if (i < len - 1) {
+ size_t o = s.find(sep, p);
+ if (o == string::npos) return false;
+ n = s.substr(p, o - p).c_str();
+ p = o + 1;
+ } else {
+ n = s.substr(p).c_str();
+ }
+ a[i] = atoi(n);
+ }
+ return true;
+}
+
+void Network::on_module_loaded()
+{
+ if ( !THEKERNEL->config->value( network_checksum, network_enable_checksum )->by_default(false)->as_bool() ) {
+ // as not needed free up resource
+ delete this;
+ return;
+ }
+
+ webserver_enabled = THEKERNEL->config->value( network_checksum, network_webserver_checksum, network_enable_checksum )->by_default(false)->as_bool();
+ telnet_enabled = THEKERNEL->config->value( network_checksum, network_telnet_checksum, network_enable_checksum )->by_default(false)->as_bool();
+
+ string mac = THEKERNEL->config->value( network_checksum, network_mac_override_checksum )->by_default("")->as_string();
+ if (mac.size() == 17 ) { // parse mac address
+ if (!parse_ip_str(mac, mac_address, 6, ':')) {
+ printf("Invalid MAC address: %s\n", mac.c_str());
+ printf("Network not started due to errors in config");
+ return;
+ }
+
+ } else { // autogenerate
+ uint32_t h = getSerialNumberHash();
+ mac_address[0] = 0x00; // OUI
+ mac_address[1] = 0x1F; // OUI
+ mac_address[2] = 0x11; // OUI
+ mac_address[3] = 0x02; // Openmoko allocation for smoothie board
+ mac_address[4] = 0x04; // 04-14 03 bits -> chip id, 1 bits -> hashed serial
+ mac_address[5] = h & 0xFF; // 00-FF 8bits -> hashed serial
+ }
+
+ ethernet->set_mac(mac_address);
+
+ // get IP address, mask and gateway address here....
+ bool bad = false;
+ string s = THEKERNEL->config->value( network_checksum, network_ip_address_checksum )->by_default("192.168.3.222")->as_string();
+ if (s == "auto") {
+ use_dhcp = true;
+
+ } else {
+ use_dhcp = false;
+ if (!parse_ip_str(s, ipaddr, 4)) {
+ printf("Invalid IP address: %s\n", s.c_str());
+ bad = true;
+ }
+ s = THEKERNEL->config->value( network_checksum, network_ip_mask_checksum )->by_default("255.255.255.0")->as_string();
+ if (!parse_ip_str(s, ipmask, 4)) {
+ printf("Invalid IP Mask: %s\n", s.c_str());
+ bad = true;
+ }
+ s = THEKERNEL->config->value( network_checksum, network_ip_gateway_checksum )->by_default("192.168.3.1")->as_string();
+ if (!parse_ip_str(s, ipgw, 4)) {
+ printf("Invalid IP gateway: %s\n", s.c_str());
+ bad = true;
+ }
+
+ if (bad) {
+ printf("Network not started due to errors in config");
+ return;
+ }
+ }
+
+ THEKERNEL->add_module( ethernet );
+ THEKERNEL->slow_ticker->attach( 100, this, &Network::tick );
+
+ // Register for events
+ this->register_for_event(ON_IDLE);
+ this->register_for_event(ON_MAIN_LOOP);
+ this->register_for_event(ON_GET_PUBLIC_DATA);
+
+ this->init();
+}
+
+void Network::on_get_public_data(void* argument) {
+ PublicDataRequest* pdr = static_cast<PublicDataRequest*>(argument);
+
+ if(!pdr->starts_with(network_checksum)) return;
+
+ if(pdr->second_element_is(get_ip_checksum)) {
+ pdr->set_data_ptr(this->ipaddr);
+ pdr->set_taken();
+
+ }else if(pdr->second_element_is(get_ipconfig_checksum)) {
+ // NOTE caller must free the returned string when done
+ char buf[200];
+ int n1= snprintf(buf, sizeof(buf), "IP Addr: %d.%d.%d.%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+ int n2= snprintf(&buf[n1], sizeof(buf)-n1, "IP GW: %d.%d.%d.%d\n", ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
+ int n3= snprintf(&buf[n1+n2], sizeof(buf)-n1-n2, "IP mask: %d.%d.%d.%d\n", ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
+ int n4= snprintf(&buf[n1+n2+n3], sizeof(buf)-n1-n2-n3, "MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ mac_address[0], mac_address[1], mac_address[2], mac_address[3], mac_address[4], mac_address[5]);
+ char *str = (char *)malloc(n1+n2+n3+n4+1);
+ memcpy(str, buf, n1+n2+n3+n4);
+ str[n1+n2+n3+n4]= '\0';
+ pdr->set_data_ptr(str);
+ pdr->set_taken();
+ }
+}
+
+uint32_t Network::tick(uint32_t dummy)
+{
+ do_tick();
+ tickcnt++;
+ return 0;
+}
+
+void Network::on_idle(void *argument)
+{
+ if (!ethernet->isUp()) return;
+
+ int len;
+ if (ethernet->_receive_frame(uip_buf, &len)) {
+ uip_len = len;
+ this->handlePacket();
+
+ } else {
+
+ if (timer_expired(&periodic_timer)) { /* no packet but periodic_timer time out (0.1s)*/
+ timer_reset(&periodic_timer);
+
+ for (int i = 0; i < UIP_CONNS; i++) {
+ uip_periodic(i);
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+ if (uip_len > 0) {
+ uip_arp_out();
+ tapdev_send(uip_buf, uip_len);
+ }
+ }
+
+#if UIP_CONF_UDP
+ for (int i = 0; i < UIP_UDP_CONNS; i++) {
+ uip_udp_periodic(i);
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+ if (uip_len > 0) {
+ uip_arp_out();
+ tapdev_send(uip_buf, uip_len);
+ }
+ }
+#endif
+ }
+/*
+ This didn't work actually made it worse,it should have worked though
+ else{
+ // TODO if the command queue is below a certain amount we should poll any stopped connections
+ if(command_q->size() < 4) {
+ for (struct uip_conn *connr = &uip_conns[0]; connr <= &uip_conns[UIP_CONNS - 1]; ++connr) {
+ if(uip_stopped(connr)){
+ // Force a poll of this
+ printf("Force poll of connection\n");
+ uip_poll_conn(connr);
+ }
+ }
+ }
+ }
+*/
+ /* Call the ARP timer function every 10 seconds. */
+ if (timer_expired(&arp_timer)) {
+ timer_reset(&arp_timer);
+ uip_arp_timer();
+ }
+ }
+}
+
+static void setup_servers()
+{
+ if (webserver_enabled) {
+ // Initialize the HTTP server, listen to port 80.
+ httpd_init();
+ printf("Webserver initialized\n");
+ }
+
+ if (telnet_enabled) {
+ // Initialize the telnet server
+ Telnetd::init();
+ printf("Telnetd initialized\n");
+ }
+
+ // sftpd service, which is lazily created on reciept of first packet
+ uip_listen(HTONS(115));
+}
+
+extern "C" void dhcpc_configured(const struct dhcpc_state *s)
+{
+ printf("Got IP address %d.%d.%d.%d\n",
+ uip_ipaddr1(&s->ipaddr), uip_ipaddr2(&s->ipaddr),
+ uip_ipaddr3(&s->ipaddr), uip_ipaddr4(&s->ipaddr));
+ printf("Got netmask %d.%d.%d.%d\n",
+ uip_ipaddr1(&s->netmask), uip_ipaddr2(&s->netmask),
+ uip_ipaddr3(&s->netmask), uip_ipaddr4(&s->netmask));
+ printf("Got DNS server %d.%d.%d.%d\n",
+ uip_ipaddr1(&s->dnsaddr), uip_ipaddr2(&s->dnsaddr),
+ uip_ipaddr3(&s->dnsaddr), uip_ipaddr4(&s->dnsaddr));
+ printf("Got default router %d.%d.%d.%d\n",
+ uip_ipaddr1(&s->default_router), uip_ipaddr2(&s->default_router),
+ uip_ipaddr3(&s->default_router), uip_ipaddr4(&s->default_router));
+ printf("Lease expires in %ld seconds\n", ntohl(s->lease_time));
+
+ theNetwork->dhcpc_configured(s->ipaddr, s->netmask, s->default_router);
+}
+
+void Network::dhcpc_configured(uint32_t ipaddr, uint32_t ipmask, uint32_t ipgw)
+{
+ memcpy(this->ipaddr, &ipaddr, 4);
+ memcpy(this->ipmask, &ipmask, 4);
+ memcpy(this->ipgw, &ipgw, 4);
+
+ uip_sethostaddr((u16_t*)this->ipaddr);
+ uip_setnetmask((u16_t*)this->ipmask);
+ uip_setdraddr((u16_t*)this->ipgw);
+
+ setup_servers();
+}
+
+void Network::init(void)
+{
+ // two timers for tcp/ip
+ timer_set(&periodic_timer, CLOCK_SECOND / 2); /* 0.5s */
+ timer_set(&arp_timer, CLOCK_SECOND * 10); /* 10s */
+
+ // Initialize the uIP TCP/IP stack.
+ uip_init();
+
+ uip_setethaddr(mac_address);
+
+ if (!use_dhcp) { // manual setup of ip
+ uip_ipaddr_t tip; /* local IP address */
+ uip_ipaddr(tip, ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+ uip_sethostaddr(tip); /* host IP address */
+ printf("IP Addr: %d.%d.%d.%d\n", ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);
+
+ uip_ipaddr(tip, ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
+ uip_setdraddr(tip); /* router IP address */
+ printf("IP GW: %d.%d.%d.%d\n", ipgw[0], ipgw[1], ipgw[2], ipgw[3]);
+
+ uip_ipaddr(tip, ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
+ uip_setnetmask(tip); /* mask */
+ printf("IP mask: %d.%d.%d.%d\n", ipmask[0], ipmask[1], ipmask[2], ipmask[3]);
+ setup_servers();
+
+ }else{
+ #if UIP_CONF_UDP
+ dhcpc_init(mac_address, sizeof(mac_address));
+ dhcpc_request();
+ printf("Getting IP address....\n");
+ #endif
+ }
+}
+
+void Network::on_main_loop(void *argument)
+{
+ // issue commands here if any available
+ while(command_q->pop()) {
+ // keep feeding them until empty
+ }
+}
+
+// select between webserver and telnetd server
+extern "C" void app_select_appcall(void)
+{
+ switch (uip_conn->lport) {
+ case HTONS(80):
+ if (webserver_enabled) httpd_appcall();
+ break;
+
+ case HTONS(23):
+ if (telnet_enabled) Telnetd::appcall();
+ break;
+
+ case HTONS(115):
+ if(sftpd == NULL) {
+ sftpd= new Sftpd();
+ sftpd->init();
+ printf("Created sftpd service\n");
+ }
+ sftpd->appcall();
+ break;
+
+ default:
+ printf("unknown app for port: %d\n", uip_conn->lport);
+
+ }
+}
+
+void Network::tapdev_send(void *pPacket, unsigned int size)
+{
+ memcpy(ethernet->request_packet_buffer(), pPacket, size);
+ ethernet->write_packet((uint8_t *) pPacket, size);
+}
+
+// define this to split full frames into two to illicit an ack from the endpoint
+#define SPLIT_OUTPUT
+
+#ifdef SPLIT_OUTPUT
+extern "C" void uip_split_output(void);
+extern "C" void tcpip_output()
+{
+ theNetwork->tapdev_send(uip_buf, uip_len);
+}
+void network_device_send()
+{
+ uip_split_output();
+ //tcpip_output();
+}
+#else
+void network_device_send()
+{
+ tapdev_send(uip_buf, uip_len);
+}
+#endif
+
+void Network::handlePacket(void)
+{
+ if (uip_len > 0) { /* received packet */
+ //printf("handlePacket: %d\n", uip_len);
+
+ if (BUF->type == htons(UIP_ETHTYPE_IP)) { /* IP packet */
+ uip_arp_ipin();
+ uip_input();
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+
+ if (uip_len > 0) {
+ uip_arp_out();
+ network_device_send();
+ }
+
+ } else if (BUF->type == htons(UIP_ETHTYPE_ARP)) { /*ARP packet */
+ uip_arp_arpin();
+ /* If the above function invocation resulted in data that
+ should be sent out on the network, the global variable
+ uip_len is set to a value > 0. */
+ if (uip_len > 0) {
+ tapdev_send(uip_buf, uip_len); /* ARP ack*/
+ }
+
+ } else {
+ printf("Unknown ethernet packet type %04X\n", htons(BUF->type));
+ uip_len = 0;
+ }
+ }
+}
View
49 src/libs/Network/uip/Network.h
@@ -0,0 +1,49 @@
+#ifndef _NETWORK_H
+#define _NETWORK_H
+
+#include "timer.h"
+#include "LPC17XX_Ethernet.h"
+#include "Module.h"
+#include "NetworkPublicAccess.h"
+
+#define network_enable_checksum CHECKSUM("enable")
+#define network_webserver_checksum CHECKSUM("webserver")
+#define network_telnet_checksum CHECKSUM("telnet")
+#define network_mac_override_checksum CHECKSUM("mac_override")
+#define network_ip_address_checksum CHECKSUM("ip_address")
+#define network_ip_gateway_checksum CHECKSUM("ip_gateway")
+#define network_ip_mask_checksum CHECKSUM("ip_mask")
+
+class Network : public Module
+{
+public:
+ Network();
+ virtual ~Network();
+
+ void on_module_loaded();
+ void on_idle(void* argument);
+ void on_main_loop(void* argument);
+ void on_get_public_data(void* argument);
+ void dhcpc_configured(uint32_t ipaddr, uint32_t ipmask, uint32_t ipgw);
+ static Network *getInstance() { return instance;}
+ void tapdev_send(void *pPacket, unsigned int size);
+
+private:
+ void init();
+ uint32_t tick(uint32_t dummy);
+ void handlePacket();
+
+ static Network *instance;
+
+ LPC17XX_Ethernet *ethernet;
+
+ struct timer periodic_timer, arp_timer;
+ uint8_t mac_address[6];
+ uint8_t ipaddr[4];
+ uint8_t ipmask[4];
+ uint8_t ipgw[4];
+ volatile uint32_t tickcnt;
+
+};
+
+#endif
View
8 src/libs/Network/uip/NetworkPublicAccess.h
@@ -0,0 +1,8 @@
+#ifndef NETWORKPUBLICACCESS_H
+#define NETWORKPUBLICACCESS_H
+
+#define network_checksum CHECKSUM("network")
+#define get_ip_checksum CHECKSUM("getip")
+#define get_ipconfig_checksum CHECKSUM("getipconfig")
+
+#endif
View
18 src/libs/Network/uip/c-fifo.h
@@ -0,0 +1,18 @@
+#ifndef _CFIFO_H_
+#define _CFIFO_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void *new_fifo();
+void delete_fifo(void *);
+char *fifo_pop(void *);
+void fifo_push(void *, char *);
+int fifo_size(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
View
53 src/libs/Network/uip/clock-arch.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: clock-arch.c,v 1.2 2006/06/12 08:00:31 adam Exp $
+ */
+
+/**
+ * \file
+ * Implementation of architecture-specific clock functionality
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+#include "clock-arch.h"
+static clock_time_t Ticks;
+
+void do_tick() {
+ Ticks++;
+}
+
+/*---------------------------------------------------------------------------*/
+clock_time_t clock_time(void)
+{
+ return Ticks;
+}
+/*---------------------------------------------------------------------------*/
View
50 src/libs/Network/uip/clock-arch.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: clock-arch.h,v 1.2 2006/06/12 08:00:31 adam Exp $
+ */
+
+#ifndef __CLOCK_ARCH_H__
+#define __CLOCK_ARCH_H__
+
+typedef unsigned clock_time_t;
+#define CLOCK_CONF_SECOND 100
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void do_tick();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CLOCK_ARCH_H__ */
View
388 src/libs/Network/uip/dhcpc/dhcpc.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * @(#)$Id: dhcpc.c,v 1.2 2006/06/11 21:46:37 adam Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "uip.h"
+#include "dhcpc.h"
+#include "timer.h"
+#include "pt.h"
+
+#if UIP_CONF_UDP
+
+#define STATE_INITIAL 0
+#define STATE_SENDING 1
+#define STATE_OFFER_RECEIVED 2
+#define STATE_CONFIG_RECEIVED 3
+
+#define ntohl(a) ((((a) >> 24) & 0x000000FF) | (((a) >> 8) & 0x0000FF00) | (((a) << 8) & 0x00FF0000) | (((a) << 24) & 0xFF000000))
+static struct dhcpc_state s __attribute__ ((section ("AHBSRAM1")));
+//#define UIP_CONF_DHCP_LIGHT
+
+struct dhcp_msg {
+ u8_t op, htype, hlen, hops;
+ u8_t xid[4];
+ u16_t secs, flags;
+ u8_t ciaddr[4];
+ u8_t yiaddr[4];
+ u8_t siaddr[4];
+ u8_t giaddr[4];
+ u8_t chaddr[16];
+#ifndef UIP_CONF_DHCP_LIGHT
+ u8_t sname[64];
+ u8_t file[128];
+#endif
+ u8_t options[312];
+};
+
+#define BOOTP_BROADCAST 0x8000
+
+#define DHCP_REQUEST 1
+#define DHCP_REPLY 2
+#define DHCP_HTYPE_ETHERNET 1
+#define DHCP_HLEN_ETHERNET 6
+#define DHCP_MSG_LEN 236
+
+#define DHCPC_SERVER_PORT 67
+#define DHCPC_CLIENT_PORT 68
+
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
+
+#define DHCP_OPTION_SUBNET_MASK 1
+#define DHCP_OPTION_ROUTER 3
+#define DHCP_OPTION_DNS_SERVER 6
+#define DHCP_OPTION_REQ_IPADDR 50
+#define DHCP_OPTION_LEASE_TIME 51
+#define DHCP_OPTION_MSG_TYPE 53
+#define DHCP_OPTION_SERVER_ID 54
+#define DHCP_OPTION_REQ_LIST 55
+#define DHCP_OPTION_END 255
+
+static uint32_t xid= 0x00112233;
+
+static const u8_t magic_cookie[4] = {99, 130, 83, 99};
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_msg_type(u8_t *optptr, u8_t type)
+{
+ *optptr++ = DHCP_OPTION_MSG_TYPE;
+ *optptr++ = 1;
+ *optptr++ = type;
+ return optptr;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_server_id(u8_t *optptr)
+{
+ *optptr++ = DHCP_OPTION_SERVER_ID;
+ *optptr++ = 4;
+ memcpy(optptr, &s.serverid, 4);
+ return optptr + 4;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_req_ipaddr(u8_t *optptr)
+{
+ *optptr++ = DHCP_OPTION_REQ_IPADDR;
+ *optptr++ = 4;
+ memcpy(optptr, &s.ipaddr, 4);
+ return optptr + 4;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_req_options(u8_t *optptr)
+{
+ *optptr++ = DHCP_OPTION_REQ_LIST;
+ *optptr++ = 3;
+ *optptr++ = DHCP_OPTION_SUBNET_MASK;
+ *optptr++ = DHCP_OPTION_ROUTER;
+ *optptr++ = DHCP_OPTION_DNS_SERVER;
+ return optptr;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t *
+add_end(u8_t *optptr)
+{
+ *optptr++ = DHCP_OPTION_END;
+ return optptr;
+}
+/*---------------------------------------------------------------------------*/
+static void
+create_msg(register struct dhcp_msg *m, int rea)
+{
+ m->op = DHCP_REQUEST;
+ m->htype = DHCP_HTYPE_ETHERNET;
+ m->hlen = s.mac_len;
+ m->hops = 0;
+ memcpy(m->xid, &xid, sizeof(m->xid));
+ m->secs = 0;
+ m->flags = HTONS(BOOTP_BROADCAST); /* Broadcast bit. */
+ /* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/
+ if(rea == 0 ) memcpy(m->ciaddr, uip_hostaddr, sizeof(m->ciaddr));
+ else memset(m->ciaddr, 0, sizeof(m->ciaddr));
+ memset(m->yiaddr, 0, sizeof(m->yiaddr));
+ memset(m->siaddr, 0, sizeof(m->siaddr));
+ memset(m->giaddr, 0, sizeof(m->giaddr));
+ memcpy(m->chaddr, s.mac_addr, s.mac_len);
+ memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len);
+#ifndef UIP_CONF_DHCP_LIGHT
+ memset(m->sname, 0, sizeof(m->sname));
+ memset(m->file, 0, sizeof(m->file));
+#endif
+
+ memcpy(m->options, magic_cookie, sizeof(magic_cookie));
+}
+/*---------------------------------------------------------------------------*/
+static void
+send_discover(void)
+{
+ u8_t *end;
+ struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+
+ create_msg(m, 0);
+
+ end = add_msg_type(&m->options[4], DHCPDISCOVER);
+ end = add_req_options(end);
+ end = add_end(end);
+
+ uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+}
+/*---------------------------------------------------------------------------*/
+static void
+send_request(int rea)
+{
+ u8_t *end;
+ struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+
+ create_msg(m, rea);
+
+ end = add_msg_type(&m->options[4], DHCPREQUEST);
+ end = add_server_id(end);
+ end = add_req_ipaddr(end);
+ end = add_end(end);
+
+ uip_send(uip_appdata, end - (u8_t *)uip_appdata);
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+parse_options(u8_t *optptr, int len)
+{
+ u8_t *end = optptr + len;
+ u8_t type = 0;
+
+ while (optptr < end) {
+ switch (*optptr) {
+ case DHCP_OPTION_SUBNET_MASK:
+ memcpy(&s.netmask, optptr + 2, 4);
+ break;
+ case DHCP_OPTION_ROUTER:
+ memcpy(&s.default_router, optptr + 2, 4);
+ break;
+ case DHCP_OPTION_DNS_SERVER:
+ memcpy(&s.dnsaddr, optptr + 2, 4);
+ break;
+ case DHCP_OPTION_MSG_TYPE:
+ type = *(optptr + 2);
+ break;
+ case DHCP_OPTION_SERVER_ID:
+ memcpy(s.serverid, optptr + 2, 4);
+ break;
+ case DHCP_OPTION_LEASE_TIME:
+ memcpy(&s.lease_time, optptr + 2, 4);
+ break;
+ case DHCP_OPTION_END:
+ return type;
+ }
+
+ optptr += optptr[1] + 2;
+ }
+ return type;
+}
+/*---------------------------------------------------------------------------*/
+u8_t
+parse_msg(void)
+{
+ struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
+
+ if (m->op == DHCP_REPLY &&
+ memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
+ memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
+ memcpy(&s.ipaddr, m->yiaddr, 4);
+ return parse_options(&m->options[4], uip_datalen());
+ }
+ return 0;
+}
+/*---------------------------------------------------------------------------*/
+static
+PT_THREAD(handle_dhcp(void))
+{
+ PT_BEGIN(&s.pt);
+
+ /* try_again:*/
+ s.state = STATE_SENDING;
+ s.ticks = CLOCK_SECOND;
+ xid++;
+
+ send_discover();
+ do {
+ timer_set(&s.timer, s.ticks);
+ PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+ // if we timed out then increase time out and send discover again
+ if (timer_expired(&s.timer)) {
+ if (s.ticks < CLOCK_SECOND * 60) {
+ s.ticks *= 2;
+ }
+ send_discover();
+ }else{
+ // we may have gotten some other UDP packet in which case just wait some more for the right packet
+ if (uip_newdata() && parse_msg() == DHCPOFFER) {
+ s.state = STATE_OFFER_RECEIVED;
+ break;
+ }
+ }
+ PT_YIELD(&s.pt);
+
+ } while (s.state != STATE_OFFER_RECEIVED);
+
+ s.ticks = CLOCK_SECOND;
+ xid++;
+
+ send_request(0);
+ do {
+ timer_set(&s.timer, s.ticks);
+ PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+
+ if (timer_expired(&s.timer)) {
+ if (s.ticks <= CLOCK_SECOND * 10) {
+ s.ticks += CLOCK_SECOND;
+ send_request(0); // resend only on timeout
+ } else {
+ PT_RESTART(&s.pt);
+ }
+ }else{
+ if (uip_newdata() && parse_msg() == DHCPACK) {
+ s.state = STATE_CONFIG_RECEIVED;
+ break;
+ }
+ }
+ PT_YIELD(&s.pt);
+
+ } while (s.state != STATE_CONFIG_RECEIVED);
+
+ dhcpc_configured(&s);
+
+ // now we wait for close to expiration and renew the lease
+ do {
+ // we should reacquire expired leases here.
+ timer_set(&s.timer, (ntohl(s.lease_time) * 0.5)*CLOCK_SECOND); // half of lease expire time
+ PT_WAIT_UNTIL(&s.pt, timer_expired(&s.timer));
+
+ uip_log("reaquire dhcp lease");
+
+ // spec says send request direct to server that gave it to us, but seems to be unecessary
+ //uip_ipaddr_copy(&s.conn->ripaddr, s.serverid);
+
+ s.ticks = CLOCK_SECOND;
+ xid++;
+ send_request(0);
+ do {
+ timer_set(&s.timer, s.ticks);
+ PT_WAIT_UNTIL(&s.pt, uip_newdata() || timer_expired(&s.timer));
+
+ if (timer_expired(&s.timer)) {
+ if (s.ticks <= CLOCK_SECOND * 10) {
+ s.ticks += CLOCK_SECOND;
+ send_request(0); // resend only on timeout
+ } else {
+ // give up
+ // TODO probably need to deal with upstream apps and stop them then reinit them
+ PT_RESTART(&s.pt);
+ }
+ }else{
+ if (parse_msg() == DHCPACK) {
+ uip_log("dhcp lease renewed");
+ break;
+ }
+ }
+ PT_YIELD(&s.pt);
+ }while(1);
+
+ }while(1);
+
+ PT_END(&s.pt);
+}
+/*---------------------------------------------------------------------------*/
+void
+dhcpc_init(const void *mac_addr, int mac_len)
+{
+ uip_ipaddr_t addr;
+
+ s.mac_addr = mac_addr;
+ s.mac_len = mac_len;
+
+ s.state = STATE_INITIAL;
+ uip_ipaddr(addr, 255, 255, 255, 255);
+ s.conn = uip_udp_new(&addr, HTONS(DHCPC_SERVER_PORT));
+ if (s.conn != NULL) {
+ uip_udp_bind(s.conn, HTONS(DHCPC_CLIENT_PORT));
+ }
+ PT_INIT(&s.pt);
+}
+/*---------------------------------------------------------------------------*/
+void
+dhcpc_appcall(void)
+{
+ handle_dhcp();
+}
+/*---------------------------------------------------------------------------*/
+void
+dhcpc_request(void)
+{
+ u16_t ipaddr[2];
+
+ if (s.state == STATE_INITIAL) {
+ uip_ipaddr(ipaddr, 0, 0, 0, 0);
+ uip_sethostaddr(ipaddr);
+ /* handle_dhcp(PROCESS_EVENT_NONE, NULL);*/
+ }
+}
+/*---------------------------------------------------------------------------*/
+
+#endif
View
76 src/libs/Network/uip/dhcpc/dhcpc.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2005, Swedish Institute of Computer Science
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * @(#)$Id: dhcpc.h,v 1.3 2006/06/11 21:46:37 adam Exp $
+ */
+#ifndef __DHCPC_H__
+#define __DHCPC_H__
+
+#include "timer.h"
+#include "pt.h"
+
+struct dhcpc_state {
+ struct pt pt;
+ char state;
+ struct uip_udp_conn *conn;
+ struct timer timer;
+ u16_t ticks;
+ const void *mac_addr;
+ int mac_len;
+
+ u8_t serverid[4];
+
+ uint32_t lease_time;
+ uint32_t ipaddr;
+ uint32_t netmask;
+ uint32_t dnsaddr;
+ uint32_t default_router;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void dhcpc_init(const void *mac_addr, int mac_len);
+void dhcpc_request(void);
+
+void dhcpc_appcall(void);
+
+void dhcpc_configured(const struct dhcpc_state *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+typedef struct dhcpc_state uip_udp_appstate_t;
+#define UIP_UDP_APPCALL dhcpc_appcall
+
+
+#endif /* __DHCPC_H__ */
View
39 src/libs/Network/uip/fifo.cpp
@@ -0,0 +1,39 @@
+// c accessibllity to the c++ fifo class
+#include "fifo.h"
+#include "c-fifo.h"
+
+void *new_fifo()
+{
+ return new Fifo<char*>;
+}
+
+void delete_fifo(void *fifo)
+{
+ if(fifo == NULL) return;
+ Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+ while(f->size() > 0) {
+ char *s= f->pop();
+ if (s != NULL) {
+ free(s);
+ }
+ }
+ delete f;
+}
+
+char *fifo_pop(void *fifo)
+{
+ Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+ return f->pop();
+}
+
+void fifo_push(void *fifo, char *str)
+{
+ Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+ f->push(str);
+}
+
+int fifo_size(void *fifo)
+{
+ Fifo<char *> *f= static_cast<Fifo<char *> *>(fifo);
+ return f->size();
+}
View
180 src/libs/Network/uip/fifo.h
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * $Author: Jim Morris $
+ * $Date: 1999/02/05 21:05:00 $
+ *
+ * this code is Licensed LGPL
+ *
+ *************************************************************************/
+#ifndef _FIFO_H_
+#define _FIFO_H_
+
+#include <stdlib.h>
+
+// Doubly Linked list class
+
+template<class T> class LList;
+
+template<class T>
+class Tlink
+{
+public:
+ Tlink<T> *pnext;
+ Tlink<T> *pprev;
+
+public:
+ Tlink()
+ {
+ pnext = pprev = 0;
+ }
+ Tlink(Tlink *p, Tlink *n)
+ {
+ pprev = p;
+ pnext = n;
+ }
+ Tlink(const T &d) : data(d)
+ {
+ pnext = pprev = 0;
+ }
+ T data;
+};
+
+template<class T>
+class list_base
+{
+private:
+ Tlink<T> *head;
+ Tlink<T> *tail;
+ int cnt;
+
+protected:
+ list_base()
+ {
+ head = tail = NULL;
+ cnt = 0;
+ }
+
+ list_base(Tlink<T> *n) // link into head of list
+ {
+ cnt = 1;
+ n->pnext = NULL;
+ n->pprev = NULL;
+ head = n;
+ tail = n;
+ }
+
+ Tlink<T> *gethead(void) const
+ {
+ return head;
+ }
+ Tlink<T> *gettail(void) const
+ {
+ return tail;
+ }
+ Tlink<T> *getnext(Tlink<T> *n) const
+ {
+ return n->pnext;
+ }
+ Tlink<T> *getprev(Tlink<T> *n) const
+ {
+ return n->pprev;
+ }
+
+ void addtohead(Tlink<T> *n) // add at head of list
+ {
+ n->pnext = head;
+ n->pprev = NULL;
+ if (head) head->pprev = n;
+ head = n;
+ if (tail == NULL) // first one
+ tail = n;
+ cnt++;
+ }
+
+ void addtohead(int c, Tlink<T> *a, Tlink<T> *b) // add list at head of list
+ {
+ b->pnext = head;
+ a->pprev = NULL;
+ if (head) head->pprev = b;
+ head = a;
+ if (tail == NULL) // first one
+ tail = b;
+ cnt += c;
+ }
+
+ void addtotail(Tlink<T> *n) // add to tail of list
+ {
+ n->pnext = NULL;
+ n->pprev = tail;
+ if (tail) tail->pnext = n;
+ tail = n;
+ if (head == NULL) // first one
+ head = n;
+ cnt++;
+ }
+
+ void remove(Tlink<T> *n) // remove it by relinking
+ {
+ cnt--;
+ if (n->pprev) n->pprev->pnext = n->pnext;
+ else head = n->pnext; // it must be the head
+ if (n->pnext) n->pnext->pprev = n->pprev;
+ else tail = n->pprev;
+ }
+
+ void reset()
+ {
+ head = tail = NULL;
+ cnt = 0;
+ }
+ int count() const
+ {
+ return cnt;
+ }
+};
+
+// fifo
+template<class T>
+class Fifo : private list_base<T>
+{
+public:
+ Fifo(){}
+
+ void push(const T &a);
+ T pop();
+ T peek();
+ int size() const;
+};
+
+template <class T>
+int Fifo<T>::size() const
+{
+ return list_base<T>::count();
+}
+
+// add to end of list (FIFO)
+template <class T>
+void Fifo<T>::push(const T &a)
+{
+ list_base<T>::addtotail(new Tlink<T>(a));
+}
+
+// return the first item in the list
+template <class T>
+T Fifo<T>::peek()
+{
+ Tlink<T> *p = list_base<T>::gethead();
+ return p->data;
+}
+
+// pop the first item off the fifo
+template <class T>
+T Fifo<T>::pop()
+{
+ Tlink<T> *p = list_base<T>::gethead();
+ T data = p->data;
+ list_base<T>::remove(p);
+ delete p;
+ return data;
+};
+#endif
View
104 src/libs/Network/uip/lib/memb.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: memb.c,v 1.1 2006/06/12 08:21:43 adam Exp $
+ */
+
+/**
+ * \addtogroup memb
+ * @{
+ */
+
+ /**
+ * \file
+ * Memory block allocation routines.
+ * \author Adam Dunkels <adam@sics.se>
+ */
+#include <string.h>
+
+#include "memb.h"
+
+/*---------------------------------------------------------------------------*/
+void
+memb_init(struct memb_blocks *m)
+{
+ memset(m->count, 0, m->num);
+ memset(m->mem, 0, m->size * m->num);
+}
+/*---------------------------------------------------------------------------*/
+void *
+memb_alloc(struct memb_blocks *m)
+{
+ int i;
+
+ for(i = 0; i < m->num; ++i) {
+ if(m->count[i] == 0) {
+ /* If this block was unused, we increase the reference count to
+ indicate that it now is used and return a pointer to the
+ memory block. */
+ ++(m->count[i]);
+ return (void *)((char *)m->mem + (i * m->size));
+ }
+ }
+
+ /* No free block was found, so we return NULL to indicate failure to
+ allocate block. */
+ return NULL;
+}
+/*---------------------------------------------------------------------------*/
+char
+memb_free(struct memb_blocks *m, void *ptr)
+{
+ int i;
+ char *ptr2;
+
+ /* Walk through the list of blocks and try to find the block to
+ which the pointer "ptr" points to. */
+ ptr2 = (char *)m->mem;
+ for(i = 0; i < m->num; ++i) {
+
+ if(ptr2 == (char *)ptr) {
+ /* We've found to block to which "ptr" points so we decrease the
+ reference count and return the new value of it. */
+ if(m->count[i] > 0) {
+ /* Make sure that we don't deallocate free memory. */
+ --(m->count[i]);
+ }
+ return m->count[i];
+ }
+ ptr2 += m->size;
+ }
+ return -1;
+}
+/*---------------------------------------------------------------------------*/
+
+/** @} */
View
141 src/libs/Network/uip/lib/memb.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: memb.h,v 1.1 2006/06/12 08:21:43 adam Exp $
+ */
+
+/**
+ * \defgroup memb Memory block management functions
+ *
+ * The memory block allocation routines provide a simple yet powerful
+ * set of functions for managing a set of memory blocks of fixed
+ * size. A set of memory blocks is statically declared with the
+ * MEMB() macro. Memory blocks are allocated from the declared
+ * memory by the memb_alloc() function, and are deallocated with the
+ * memb_free() function.
+ *
+ * \note Because of namespace clashes only one MEMB() can be
+ * declared per C module, and the name scope of a MEMB() memory
+ * block is local to each C module.
+ *
+ * The following example shows how to declare and use a memory block
+ * called "cmem" which has 8 chunks of memory with each memory chunk
+ * being 20 bytes large.
+ *
+ * @{
+ */
+
+
+/**
+ * \file
+ * Memory block allocation routines.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __MEMB_H__
+#define __MEMB_H__
+
+/*
+ * Here we define a C preprocessing macro for concatenating to
+ * strings. We need use two macros in order to allow concatenation of
+ * two #defined macros.
+ */
+#define MEMB_CONCAT2(s1, s2) s1##s2
+#define MEMB_CONCAT(s1, s2) MEMB_CONCAT2(s1, s2)
+
+/**
+ * Declare a memory block.
+ *
+ * This macro is used to staticall declare a block of memory that can
+ * be used by the block allocation functions. The macro statically
+ * declares a C array with a size that matches the specified number of
+ * blocks and their individual sizes.
+ *
+ * Example:
+ \code
+MEMB(connections, sizeof(struct connection), 16);
+ \endcode
+ *
+ * \param name The name of the memory block (later used with
+ * memb_init(), memb_alloc() and memb_free()).
+ *
+ * \param size The size of each memory chunk, in bytes.
+ *
+ * \param num The total number of memory chunks in the block.
+ *
+ */
+#define MEMB(name, structure, num) static char MEMB_CONCAT(name,_memb_count)[num]; \
+ static structure MEMB_CONCAT(name,_memb_mem)[num]; \
+ static struct memb_blocks name = {sizeof(structure), num, MEMB_CONCAT(name,_memb_count), (void *)MEMB_CONCAT(name,_memb_mem) }
+
+
+
+struct memb_blocks {
+ unsigned short size;
+ unsigned short num;
+ char *count;
+ void *mem;
+};
+
+/**
+ * Initialize a memory block that was declared with MEMB().
+ *
+ * \param m A memory block previosly declared with MEMB().
+ */
+void memb_init(struct memb_blocks *m);
+
+/**
+ * Allocate a memory block from a block of memory declared with MEMB().
+ *
+ * \param m A memory block previosly declared with MEMB().
+ */
+void *memb_alloc(struct memb_blocks *m);
+
+/**
+ * Deallocate a memory block from a memory block previously declared
+ * with MEMB().
+ *
+ * \param m m A memory block previosly declared with MEMB().
+ *
+ * \param ptr A pointer to the memory block that is to be deallocated.
+ *
+ * \return The new reference count for the memory block (should be 0
+ * if successfully deallocated) or -1 if the pointer "ptr" did not
+ * point to a legal memory block.
+ */
+char memb_free(struct memb_blocks *m, void *ptr);
+
+/** @} */
+
+#endif /* __MEMB_H__ */
View
228 src/libs/Network/uip/sftp/sftpd.cpp
@@ -0,0 +1,228 @@
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+
+#include "sftpd.h"
+#include "string.h"
+#include "stdlib.h"
+
+extern "C" {
+#include "uip.h"
+}
+
+#define ISO_nl 0x0a
+#define ISO_cr 0x0d
+#define ISO_sp 0x20
+
+#define DEBUG_PRINTF(...)
+
+Sftpd::Sftpd()
+{
+ fd = NULL;
+ state = STATE_NORMAL;
+ outbuf = NULL;
+ filename= NULL;
+}
+
+Sftpd::~Sftpd()
+{
+ if (fd != NULL) {
+ fclose(fd);
+ }
+}
+
+int Sftpd::senddata()
+{
+ if (outbuf != NULL) {
+ DEBUG_PRINTF("sftp: senddata %s\n", outbuf);
+ strcpy((char *)uip_appdata, outbuf);
+ uip_send(uip_appdata, strlen(outbuf));
+ }
+ return 0;
+}
+
+int Sftpd::handle_command()
+{
+ PSOCK_BEGIN(&sin);
+
+ do {
+ PSOCK_READTO(&sin, ISO_nl);
+ buf[PSOCK_DATALEN(&sin) - 1] = 0;
+ int len = PSOCK_DATALEN(&sin) - 1;
+ DEBUG_PRINTF("sftp: got command: %s, %d\n", buf, len);
+
+ if (state == STATE_CONNECTED) {
+ if (strncmp(buf, "USER", 4) == 0) {
+ outbuf = "!user logged in\n";
+
+ } else if (strncmp(buf, "KILL", 4) == 0) {
+ if (len < 6) {
+ outbuf = "- incomplete KILL command\n";
+ } else {
+ char *fn = &buf[5];
+ int s = remove(fn);
+ if (s == 0) outbuf = "+ deleted\n";
+ else outbuf = "- delete failed\n";
+ }
+
+ } else if (strncmp(buf, "DONE", 4) == 0) {
+ outbuf = "+ exit\n";
+ state = STATE_CLOSE;
+
+ } else if (strncmp(buf, "STOR", 4) == 0) {
+ if (len < 11) {
+ outbuf = "- incomplete STOR command\n";
+ } else {
+ char *fn = &buf[9];
+ if(this->filename != NULL) free(this->filename);
+ this->filename= strdup(fn); // REMOVE when bug fixed
+ // get { NEW|OLD|APP }
+ if (strncmp(&buf[5], "OLD", 3) == 0) {
+ DEBUG_PRINTF("sftp: Opening file: %s\n", fn);
+ fd = fopen(fn, "w");
+ if (fd != NULL) {
+ outbuf = "+ new file\n";
+ state = STATE_GET_LENGTH;
+ } else {
+ outbuf = "- failed\n";
+ }
+ } else if (strncmp(&buf[5], "APP", 3) == 0) {
+ fd = fopen(fn, "a");
+ if (fd != NULL) {
+ outbuf = "+ append file\n";
+ state = STATE_GET_LENGTH;
+ } else {
+ outbuf = "- failed\n";
+ }
+ } else {
+ outbuf = "- Only OLD|APP supported\n";
+ }
+ }
+
+ } else {
+ outbuf = "- Unknown command\n";
+ }
+
+ } else if (state == STATE_GET_LENGTH) {
+ if (len < 6 || strncmp(buf, "SIZE", 4) != 0) {
+ fclose(fd);
+ fd = NULL;
+ outbuf = "- Expected size\n";
+ state = STATE_CONNECTED;
+
+ } else {
+ filesize = atoi(&buf[5]);
+ if (filesize > 0) {
+ outbuf = "+ ok, waiting for file\n";
+ state = STATE_DOWNLOAD;
+ } else {
+ fclose(fd);
+ fd = NULL;
+ outbuf = "- bad filesize\n";
+ state = STATE_CONNECTED;
+ }
+ }
+
+ } else {
+ DEBUG_PRINTF("WTF state: %d\n", state);
+ }
+
+ } while(state == STATE_CONNECTED || state == STATE_GET_LENGTH);
+
+ PSOCK_END(&sin);
+}
+
+int Sftpd::handle_download()
+{
+ // Note this is not using PSOCK and it consumes all read data
+ char *readptr = (char *)uip_appdata;
+ unsigned int readlen = uip_datalen();
+ DEBUG_PRINTF("sftp: starting download, expecting %d bytes, read %d\n", filesize, readlen);
+
+ if (filesize > 0 && readlen > 0) {
+ if (readlen > filesize) readlen = filesize;
+ if (fwrite(readptr, 1, readlen, fd) != readlen) {
+ DEBUG_PRINTF("sftp: Error writing file\n");
+ fclose(fd);
+ fd = NULL;
+ outbuf = "- Error saving file\n";
+ state = STATE_CONNECTED;
+ return 0;
+ }
+ filesize -= readlen;
+ DEBUG_PRINTF("sftp: saved %d bytes %d left\n", readlen, filesize);
+ // HACK ALERT... to work around the fwrite/filesystem bug where writing large amounts of data corrupts the file
+ // we workaround by closing the file, the reopening for append until we are done
+ fclose(fd);
+ fd = fopen(this->filename, "a");
+ }
+ if (filesize == 0) {
+ DEBUG_PRINTF("sftp: download complete\n");
+ fclose(fd);
+ fd = NULL;
+ outbuf = "+ Saved file\n";
+ state = STATE_CONNECTED;
+ return 0;
+ }
+ return 1;
+}
+
+int Sftpd::acked()
+{
+ outbuf= NULL;
+ return 0;
+}
+
+
+void Sftpd::appcall(void)
+{
+ if (uip_connected()) {
+ // TODO check for other connections
+ PSOCK_INIT(&sin, buf, sizeof(buf));
+ state = STATE_CONNECTED;
+ outbuf = "+Smoothie SFTP Service\n";
+ }
+
+ if (state == STATE_CLOSE) {
+ DEBUG_PRINTF("sftp: state close\n");
+ state = STATE_NORMAL;
+ uip_close();
+ return;
+ }
+
+ if (uip_closed() || uip_aborted() || uip_timedout()) {
+ DEBUG_PRINTF("sftp: closed\n");
+ if (fd != NULL)
+ fclose(fd);
+ fd = NULL;
+ state = STATE_NORMAL;
+ return;
+ }
+
+ if (uip_acked()) {
+ DEBUG_PRINTF("sftp: acked\n");
+ this->acked();
+ }
+
+ if (uip_newdata()) {
+ DEBUG_PRINTF("sftp: newdata\n");
+ if (state == STATE_DOWNLOAD) {
+ if(handle_download() == 0) {
+ // we need to reset the input PSOCK again before using it after using the raw input buffer
+ PSOCK_INIT(&sin, buf, sizeof(buf));
+ }
+ } else {
+ handle_command();
+ }
+ }
+
+ if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) {
+ this->senddata();
+ }
+
+}
+
+void Sftpd::init(void)
+{
+
+}
+
+
View
39 src/libs/Network/uip/sftp/sftpd.h
@@ -0,0 +1,39 @@
+#ifndef __SFTPD_H__
+#define __SFTPD_H__
+
+/*
+ * Implement RFC913 Simple File Transfer
+ */
+
+
+#include <stdio.h>
+extern "C" {
+#include "psock.h"
+}
+
+class Sftpd
+{
+public:
+ Sftpd();
+ virtual ~Sftpd();
+
+ void appcall(void);
+ void init(void);
+
+private:
+ FILE *fd;
+ enum STATES { STATE_NORMAL, STATE_CONNECTED, STATE_GET_LENGTH, STATE_DOWNLOAD, STATE_CLOSE };
+ STATES state;
+ int acked();
+ int handle_command();
+ int handle_download();
+ int senddata();
+
+ struct psock sin;
+ char buf[80];
+ const char *outbuf;
+ unsigned int filesize;
+ char *filename;
+};
+
+#endif /* __sftpd_H__ */
View
280 src/libs/Network/uip/telnetd/shell.cpp
@@ -0,0 +1,280 @@
+/*
+* Copyright (c) 2003, Adam Dunkels.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* 3. The name of the author may not be used to endorse or promote
+* products derived from this software without specific prior
+* written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* This file is part of the uIP TCP/IP stack.
+*
+* $Id: shell.c,v 1.1 2006/06/07 09:43:54 adam Exp $
+*
+*/
+
+#include "stdlib.h"
+#include "shell.h"
+#include "uip.h"
+#include <string.h>
+#include "checksumm.h"
+#include "utils.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "telnetd.h"
+#include "CallbackStream.h"
+#include "Kernel.h"
+
+//#define DEBUG_PRINTF(...)
+#define DEBUG_PRINTF printf
+
+struct ptentry {
+ uint16_t command_cs;
+ void (* pfunc)(char *str, Shell *sh);
+};
+
+#define SHELL_PROMPT "> "
+
+/*---------------------------------------------------------------------------*/
+bool Shell::parse(register char *str, struct ptentry *t)
+{
+ struct ptentry *p;
+ for (p = t; p->command_cs != 0; ++p) {
+ if (get_checksum(str) == p->command_cs) {
+ break;
+ }
+ }
+
+ p->pfunc(str, this);
+
+ return p->command_cs != 0;
+}
+/*---------------------------------------------------------------------------*/
+static void help(char *str, Shell *sh)
+{
+ sh->output("Available commands: All others are passed on\n");
+ sh->output("netstat - show network info\n");
+ sh->output("? - show network help\n");
+ sh->output("help - show command help\n");
+ sh->output("exit, quit - exit shell\n");
+}
+
+/*---------------------------------------------------------------------------*/
+static const char *states[] = {
+ "CLOSED",
+ "SYN_RCVD",
+ "SYN_SENT",
+ "ESTABLISHED",
+ "FIN_WAIT_1",
+ "FIN_WAIT_2",
+ "CLOSING",
+ "TIME_WAIT",
+ "LAST_ACK",
+ "NONE",
+ "RUNNING",
+ "CALLED"
+};
+static void connections(char *str, Shell *sh)
+{
+ char istr[128];
+ struct uip_conn *connr;
+ snprintf(istr, sizeof(istr), "Initial MSS: %d, MSS: %d\n", uip_initialmss(), uip_mss());
+ sh->output(istr);
+ sh->output("Current connections: \n");
+
+ for (connr = &uip_conns[0]; connr <= &uip_conns[UIP_CONNS - 1]; ++connr) {
+ if(connr->tcpstateflags != UIP_CLOSED) {
+ snprintf(istr, sizeof(istr), "%d, %u.%u.%u.%u:%u, %s, %u, %u, %c %c\n",
+ HTONS(connr->lport),
+ uip_ipaddr1(connr->ripaddr), uip_ipaddr2(connr->ripaddr), uip_ipaddr3(connr->ripaddr), uip_ipaddr4(connr->ripaddr),
+ HTONS(connr->rport),
+ states[connr->tcpstateflags & UIP_TS_MASK],
+ connr->nrtx,
+ connr->timer,
+ (uip_outstanding(connr)) ? '*' : ' ',
+ (uip_stopped(connr)) ? '!' : ' ');
+
+ sh->output(istr);
+ }
+ }
+}
+
+static void quit(char *str, Shell *sh)
+{
+ sh->close();
+}
+
+//#include "clock.h"
+static void test(char *str, Shell *sh)
+{
+ printf("In Test\n");
+
+ // struct timer t;
+ // u16_t ticks= CLOCK_SECOND*5;
+ // timer_set(&t, ticks);
+ // printf("Wait....\n");
+ // while(!timer_expired(&t)) {
+
+ // }
+ // printf("Done\n");
+ /*
+ const char *fn= "/sd/test6.txt";
+ uint16_t *buf= (uint16_t *)malloc(200*2);
+ int cnt= 0;
+ FILE *fp;
+ for(int i=0;i<10;i++) {
+ fp= fopen(fn, i == 0 ? "w" : "a");
+ if(fp == NULL) {
+ printf("failed to open file\n");
+ return;
+ }
+ for (int x = 0; x < 200; ++x) {
+ buf[x]= x+cnt;
+ }
+ cnt+=200;
+ int n= fwrite(buf, 2, 200, fp);
+ printf("wrote %d, %d\n", i, n);
+ fclose(fp);
+ }
+
+ fp= fopen(fn, "r");
+ if(fp == NULL) {
+ printf("failed to open file for read\n");
+ return;
+ }
+ printf("Opened file %s for read\n", fn);
+ do {
+ int n= fread(buf, 2, 200, fp);
+ if(n <= 0) break;
+ for(int x=0;x<n;x++) {
+ printf("%04X, ", buf[x]);
+ }
+ }while(1);
+ fclose(fp);
+ free(buf);
+ */
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void unknown(char *str, Shell *sh)
+{
+ // its some other command, so queue it for mainloop to find
+ if (strlen(str) > 0) {
+ CommandQueue::getInstance()->add(str, sh->getStream());
+ }
+}
+/*---------------------------------------------------------------------------*/
+static struct ptentry parsetab[] = {
+ {CHECKSUM("netstat"), connections},
+ {CHECKSUM("exit"), quit},
+ {CHECKSUM("quit"), quit},
+ {CHECKSUM("test"), test},
+ {CHECKSUM("?"), help},
+
+ /* Default action */
+ {0, unknown}
+};
+/*---------------------------------------------------------------------------*/
+// this callback gets the results of a command, line by line
+// NULL means command completed
+// static
+int Shell::command_result(const char *str, void *p)
+{
+ // FIXME problem when shell is deleted and this gets called from slow command
+ // need a way to know this shell was closed or deleted
+ Shell *sh = (Shell *)p;
+ if (str == NULL) {
+ // indicates command is complete
+ // only prompt when command is completed
+ sh->telnet->output_prompt(SHELL_PROMPT);
+ return 0;
+
+ } else {
+ if (sh->telnet->can_output()) {
+ if (sh->telnet->output(str) == -1) return -1; // connection was closed
+ return 1;
+ }
+ // we are stalled
+ return 0;
+ }
+}
+
+/*---------------------------------------------------------------------------*/
+void Shell::start()
+{
+ telnet->output("Smoothie command shell\r\n> ");
+}
+
+int Shell::queue_size()
+{
+ return CommandQueue::getInstance()->size();
+}
+/*---------------------------------------------------------------------------*/
+void Shell::input(char *cmd)
+{
+ if (parse(cmd, parsetab)) {
+ telnet->output_prompt(SHELL_PROMPT);
+ }
+}
+/*---------------------------------------------------------------------------*/
+
+int Shell::output(const char *str)
+{
+ return telnet->output(str);
+}
+
+void Shell::close()
+{
+ telnet->close();
+}
+
+void Shell::setConsole()
+{
+ // add it to the kernels output stream if we are a console
+ // TODO do we do this for all connections? so pronterface will get file done when playing from M24?
+ // then we need to turn it off for the streaming app
+ DEBUG_PRINTF("Shell: Adding stream to kernel streams\n");
+ THEKERNEL->streams->append_stream(pstream);
+ isConsole= true;
+}
+
+Shell::Shell(Telnetd *telnet)
+{
+ DEBUG_PRINTF("Shell: ctor %p - %p\n", this, telnet);
+ this->telnet= telnet;
+ // create a callback StreamOutput for this connection
+ pstream = new CallbackStream(command_result, this);
+ isConsole= false;
+}
+
+Shell::~Shell()
+{
+ if(isConsole) {
+ DEBUG_PRINTF("Shell: Removing stream from kernel streams\n");
+ THEKERNEL->streams->remove_stream(pstream);
+ }
+ // we cannot delete this stream until it is no longer in any command queue entries
+ // so mark it as closed, and allow it to delete itself when it is no longer being used
+ static_cast<CallbackStream*>(pstream)->mark_closed(); // mark the stream as closed so we do not get any callbacks
+ DEBUG_PRINTF("Shell: dtor %p\n", this);
+}
View
104 src/libs/Network/uip/telnetd/shell.h
@@ -0,0 +1,104 @@
+/**
+ * \file
+ * Interface for the Contiki shell.
+ * \author Adam Dunkels <adam@dunkels.com>
+ *
+ * Some of the functions declared in this file must be implemented as
+ * a shell back-end in the architecture specific files of a Contiki
+ * port.
+ */
+
+
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the Contiki desktop OS.
+ *
+ * $Id: shell.h,v 1.1 2006/06/07 09:43:54 adam Exp $
+ *
+ */
+#ifndef __SHELL_H__
+#define __SHELL_H__
+
+#include "telnetd.h"
+#include "CommandQueue.h"
+
+class Telnetd;
+
+class Shell
+{
+public:
+ Shell(Telnetd *telnet);
+ ~Shell();
+
+ /**
+ * Start the shell back-end.
+ *
+ * Called by the front-end when a new shell is started.
+ */
+ void start(void);
+
+ /**
+ * Process a shell command.
+ *
+ * This function will be called by the shell GUI / telnet server whan
+ * a command has been entered that should be processed by the shell
+ * back-end.
+ *
+ * \param command The command to be processed.
+ */
+ void input(char *command);
+
+ int output(const char *str);
+ void close();
+
+ /**
+ * Print a prompt to the shell window.
+ *
+ * This function can be used by the shell back-end to print out a
+ * prompt to the shell window.
+ *
+ * \param prompt The prompt to be printed.
+ *
+ */
+ void prompt(const char *prompt);
+
+ int queue_size();
+ int can_output();
+ static int command_result(const char *str, void *ti);
+ StreamOutput *getStream() { return pstream; }
+ void setConsole();
+
+private:
+ bool parse(register char *str, struct ptentry *t);
+ Telnetd *telnet; // telnet instance we are connected to
+ StreamOutput *pstream;
+ bool isConsole;
+};
+
+#endif /* __SHELL_H__ */
View
413 src/libs/Network/uip/telnetd/telnetd.cpp
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: telnetd.c,v 1.2 2006/06/07 09:43:54 adam Exp $
+ *
+ */
+
+#include "uip.h"
+#include "telnetd.h"
+#include "shell.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define ISO_nl 0x0a
+#define ISO_cr 0x0d
+
+#define STATE_NORMAL 0
+#define STATE_IAC 1
+#define STATE_WILL 2
+#define STATE_WONT 3
+#define STATE_DO 4
+#define STATE_DONT 5
+#define STATE_CLOSE 6
+
+#define TELNET_IAC 255
+#define TELNET_WILL 251
+#define TELNET_WONT 252
+#define TELNET_DO 253
+#define TELNET_DONT 254
+
+#define TELNET_LINEMODE 0x22
+#define TELNET_GA 0x03
+#define TELNET_X_PROMPT 0x55
+
+//#define DEBUG_PRINTF(...)
+#define DEBUG_PRINTF printf
+
+static char *alloc_line(int size)
+{
+ return (char *)malloc(size);
+}
+
+static void dealloc_line(char *line)
+{
+ free(line);
+}
+
+void Telnetd::close()
+{
+ state = STATE_CLOSE;
+}
+
+int Telnetd::sendline(char *line)
+{
+ int i;
+ for (i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+ if (lines[i] == NULL) {
+ lines[i] = line;
+ return i;
+ }
+ }
+ if (i == TELNETD_CONF_NUMLINES) {
+ dealloc_line(line);
+ }
+ return TELNETD_CONF_NUMLINES;
+}
+
+void Telnetd::output_prompt(const char *str)
+{
+ if(prompt) output(str);
+}
+
+int Telnetd::output(const char *str)
+{
+ if(state == STATE_CLOSE) return -1;
+
+ unsigned chunk = 256; // small chunk size so we don't allocate huge blocks, and must be less than mss
+ unsigned len = strlen(str);
+ char *line;
+ if (len < chunk) {
+ // can be sent in one tcp buffer
+ line = alloc_line(len + 1);
+ if (line != NULL) {
+ strcpy(line, str);
+ return sendline(line);
+ }else{
+ // out of memory treat like full
+ return TELNETD_CONF_NUMLINES;
+ }
+ } else {
+ // need to split line over multiple send lines
+ int size = chunk; // size to copy
+ int off = 0;
+ int n= 0;
+ while (len >= chunk) {
+ line = alloc_line(chunk + 1);
+ if (line != NULL) {
+ memcpy(line, str + off, size);
+ line[size] = 0;
+ n= sendline(line);
+ len -= size;
+ off += size;
+ }else{
+ // out of memory treat like full
+ return TELNETD_CONF_NUMLINES;
+ }
+ }
+ if (len > 0) {
+ // send rest
+ line = alloc_line(len + 1);
+ if (line != NULL) {
+ strcpy(line, str + off);
+ n= sendline(line);
+ }else{
+ // out of memory treat like full
+ return TELNETD_CONF_NUMLINES;
+ }
+ }
+ return n;
+ }
+}
+
+// check if we can queue or if queue is full
+int Telnetd::can_output()
+{
+ if(state == STATE_CLOSE) return -1;
+
+ int i;
+ int cnt = 0;
+ for (i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+ if (lines[i] == NULL) cnt++;
+ }
+ return cnt < 4 ? 0 : 1;
+}
+
+void Telnetd::acked(void)
+{
+ while (numsent > 0) {
+ dealloc_line(lines[0]);
+ for (int i = 1; i < TELNETD_CONF_NUMLINES; ++i) {
+ lines[i - 1] = lines[i];
+ }
+ lines[TELNETD_CONF_NUMLINES - 1] = NULL;
+ --numsent;
+ }
+}
+
+void Telnetd::senddata(void)
+{
+ // NOTE this sends as many lines as it can fit in one tcp frame
+ // we need to keep the lines under the size of the tcp frame
+ char *bufptr, *lineptr;
+ int buflen, linelen;
+
+ bufptr = (char *)uip_appdata;
+ buflen = 0;
+ for (numsent = 0; numsent < TELNETD_CONF_NUMLINES && lines[numsent] != NULL ; ++numsent) {
+ lineptr = lines[numsent];
+ linelen = strlen(lineptr);
+ if (buflen + linelen < uip_mss()) {
+ memcpy(bufptr, lineptr, linelen);
+ bufptr += linelen;
+ buflen += linelen;
+ } else {
+ break;
+ }
+ }
+ uip_send(uip_appdata, buflen);
+}
+
+void Telnetd::get_char(u8_t c)
+{
+ if (c == ISO_cr) {
+ return;
+ }
+
+ buf[(int)bufptr] = c;
+ if (buf[(int)bufptr] == ISO_nl || bufptr == sizeof(buf) - 1) {
+ if (bufptr > 0) {
+ buf[(int)bufptr] = 0;
+ }
+ shell->input(buf);
+ bufptr = 0;
+
+ } else {
+ ++bufptr;
+ }
+}
+
+// static void sendopt(u8_t option, u8_t value)
+// {
+// char *line;
+// line = alloc_line(4);
+// if (line != NULL) {
+// line[0] = TELNET_IAC;
+// line[1] = option;
+// line[2] = value;
+// line[3] = 0;
+// sendline(line);
+// }
+// }
+
+void Telnetd::newdata(void)
+{
+ u16_t len;
+ u8_t c;
+ char *dataptr;
+
+ len = uip_datalen();
+ dataptr = (char *)uip_appdata;
+
+ while (len > 0 && bufptr < sizeof(buf)) {
+ c = *dataptr;
+ ++dataptr;
+ --len;
+ switch (state) {
+ case STATE_IAC:
+ if (c == TELNET_IAC) {
+ get_char(c);
+ state = STATE_NORMAL;
+ } else {
+ switch (c) {
+ case TELNET_WILL:
+ state = STATE_WILL;
+ break;
+ case TELNET_WONT:
+ state = STATE_WONT;
+ break;
+ case TELNET_DO:
+ state = STATE_DO;
+ break;
+ case TELNET_DONT:
+ state = STATE_DONT;
+ break;
+ default:
+ state = STATE_NORMAL;
+ break;
+ }
+ }
+ break;
+ case STATE_WILL:
+ if (c == TELNET_LINEMODE) {
+ //sendopt(TELNET_DO, c);
+ }
+ state = STATE_NORMAL;
+ break;
+
+ case STATE_WONT:
+ /* Reply with a DONT */
+ //sendopt(TELNET_DONT, c);
+ state = STATE_NORMAL;
+ break;
+ case STATE_DO:
+ if (c == TELNET_X_PROMPT) {
+ prompt= true;
+ }else if (c == TELNET_GA) {
+ // enable prompt if telnet client running
+ prompt= true;
+ shell->setConsole(); // tell shell we are a console, as this is sent be telnet clients
+ }else{
+ /* Reply with a WONT */
+ //sendopt(TELNET_WONT, c);
+ }
+ state = STATE_NORMAL;
+ break;
+ case STATE_DONT:
+ if (c == TELNET_X_PROMPT) {
+ prompt= false;
+ }else{
+ /* Reply with a WONT */
+ //sendopt(TELNET_WONT, c);
+ }
+ state = STATE_NORMAL;
+ break;
+ case STATE_NORMAL:
+ if (c == TELNET_IAC) {
+ state = STATE_IAC;
+ } else {
+ get_char(c);
+ }
+ break;
+ }
+ }
+
+ // if the command queue is getting too big we stop TCP
+ if(shell->queue_size() > 20) {
+ DEBUG_PRINTF("Telnet: stopped: %d\n", shell->queue_size());
+ uip_stop();
+ }
+}
+
+void Telnetd::poll()
+{
+ if(first_time) {
+ first_time= false;
+ shell->start();
+ senddata();
+ }
+}
+
+Telnetd::Telnetd()
+{
+ DEBUG_PRINTF("Telnetd: ctor %p\n", this);
+ for (int i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+ lines[i] = NULL;
+ }
+
+ first_time= true;
+ bufptr = 0;
+ state = STATE_NORMAL;
+ prompt= false;
+ shell= new Shell(this);
+}
+
+Telnetd::~Telnetd()
+{
+ DEBUG_PRINTF("Telnetd: dtor %p\n", this);
+ for (int i = 0; i < TELNETD_CONF_NUMLINES; ++i) {
+ if (lines[i] != NULL) dealloc_line(lines[i]);
+ }
+ delete shell;
+}
+
+// static
+void Telnetd::appcall(void)
+{
+ Telnetd *instance= reinterpret_cast<Telnetd *>(uip_conn->appstate);
+
+ if (uip_connected()) {
+ // create a new telnet class instance
+ instance= new Telnetd;
+ DEBUG_PRINTF("Telnetd new instance: %p\n", instance);
+ uip_conn->appstate= instance; // and store it in the appstate of the connection
+ instance->rport= uip_conn->rport;
+ }
+
+ if (uip_closed() || uip_aborted() || uip_timedout()) {
+ DEBUG_PRINTF("Telnetd: closed: %p\n", instance);
+ if(instance != NULL) {
+ delete instance;
+ uip_conn->appstate= NULL;
+ }
+ return;
+ }
+
+ // sanity check
+ if(instance == NULL || instance->rport != uip_conn->rport) {
+ DEBUG_PRINTF("Telnetd: ERROR Null instance or rport is wrong: %p - %u, %d\n", instance, HTONS(uip_conn->rport), uip_flags);
+ uip_abort();
+ return;
+ }
+
+ if (instance->state == STATE_CLOSE) {
+ uip_close();
+ }
+
+
+ if (uip_acked()) {
+ instance->acked();
+ }
+
+ if (uip_newdata()) {
+ instance->newdata();
+ }
+
+ if (uip_rexmit() || uip_newdata() || uip_acked() || uip_connected() || uip_poll()) {
+ instance->senddata();
+ }
+
+ if(uip_poll() && uip_stopped(uip_conn) && instance->shell->queue_size() < 5) {
+ DEBUG_PRINTF("restarted %d - %p\n", instance->shell->queue_size(), instance);
+ uip_restart();
+ }
+
+ if(uip_poll()) {
+ instance->poll();
+ }
+}
+
+// static
+void Telnetd::init(void)
+{
+ uip_listen(HTONS(23));
+}
View
84 src/libs/Network/uip/telnetd/telnetd.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: telnetd.h,v 1.2 2006/06/07 09:43:54 adam Exp $
+ *
+ */
+#ifndef __TELNETD_H__
+#define __TELNETD_H__
+
+#include "shell.h"
+#include "stdint.h"
+
+class Shell;
+
+class Telnetd
+{
+public:
+ Telnetd();
+ ~Telnetd();
+
+ static void init(void);
+ static void appcall(void);
+
+ void output_prompt(const char *str);
+ int output(const char *str);
+ int can_output();
+ void close();
+
+private:
+ static const int TELNETD_CONF_MAXCOMMANDLENGTH= 132;
+ static const int TELNETD_CONF_NUMLINES= 32;
+
+ Shell *shell;
+
+ // FIXME this needs to be a FIFO
+ char *lines[TELNETD_CONF_NUMLINES];
+ char buf[TELNETD_CONF_MAXCOMMANDLENGTH];
+ char bufptr;
+ uint8_t numsent;
+ uint8_t state;
+ uint16_t rport;
+
+ bool prompt;
+
+ bool first_time;
+
+ int sendline(char *line);
+ void acked(void);
+ void senddata(void);
+ void get_char(uint8_t c);
+ void newdata(void);
+ void poll(void);
+
+};
+
+#endif /* __TELNETD_H__ */
View
168 src/libs/Network/uip/uip-conf.h
@@ -0,0 +1,168 @@
+/**
+ * \addtogroup uipopt
+ * @{
+ */
+
+/**
+ * \name Project-specific configuration options
+ * @{
+ *
+ * uIP has a number of configuration options that can be overridden
+ * for each project. These are kept in a project-specific uip-conf.h
+ * file and all configuration names have the prefix UIP_CONF.
+ */
+
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uip-conf.h,v 1.6 2006/06/12 08:00:31 adam Exp $
+ */
+
+/**
+ * \file
+ * An example uIP configuration file
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+#ifndef __UIP_CONF_H__
+#define __UIP_CONF_H__
+
+#include <inttypes.h>
+
+/**
+ * 8 bit datatype
+ *
+ * This typedef defines the 8-bit type used throughout uIP.
+ *
+ * \hideinitializer
+ */
+typedef uint8_t u8_t;
+
+/**
+ * 16 bit datatype
+ *
+ * This typedef defines the 16-bit type used throughout uIP.
+ *
+ * \hideinitializer
+ */
+typedef uint16_t u16_t;
+
+/**
+ * Statistics datatype
+ *
+ * This typedef defines the dataype used for keeping statistics in
+ * uIP.
+ *
+ * \hideinitializer
+ */
+typedef unsigned short uip_stats_t;
+
+/**
+ * Maximum number of TCP connections.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_MAX_CONNECTIONS 6
+
+/**
+ * Maximum number of listening TCP ports.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_MAX_LISTENPORTS 6
+
+/**
+ * uIP buffer size.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_BUFFER_SIZE 400
+
+#define UIP_CONF_BROADCAST 1
+
+/**
+ * CPU byte order.
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_BYTE_ORDER LITTLE_ENDIAN
+
+/**
+ * Logging on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_LOGGING 1
+
+/**
+ * UDP support on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_UDP 1
+#define UIP_CONF_UDP_CONNS 4
+/**
+ * UDP checksums on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_UDP_CHECKSUMS 0
+
+/**
+ * uIP statistics on or off
+ *
+ * \hideinitializer
+ */
+#define UIP_CONF_STATISTICS 0
+
+#ifdef __cplusplus
+extern "C" void app_select_appcall(void);
+#else
+extern void app_select_appcall(void);
+#endif
+
+#define UIP_APPCALL app_select_appcall
+typedef void* uip_tcp_appstate_t;
+
+/* Here we include the header file for the application(s) we use in
+ our project. */
+/*#include "smtp.h"*/
+//#include "hello-world.h"
+// #include "telnetd.h"
+// #include "webserver.h"
+#include "dhcpc.h"
+/*#include "resolv.h"*/
+/*#include "webclient.h"*/
+
+#endif /* __UIP_CONF_H__ */
+
+/** @} */
+/** @} */
View
95 src/libs/Network/uip/uip/clock.h
@@ -0,0 +1,95 @@
+/**
+ * \defgroup clock Clock interface
+ *
+ * The clock interface is the interface between the \ref timer "timer library"
+ * and the platform specific clock functionality. The clock
+ * interface must be implemented for each platform that uses the \ref
+ * timer "timer library".
+ *
+ * The clock interface does only one this: it measures time. The clock
+ * interface provides a macro, CLOCK_SECOND, which corresponds to one
+ * second of system time.
+ *
+ * \sa \ref timer "Timer library"
+ *
+ * @{
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: clock.h,v 1.3 2006/06/11 21:46:39 adam Exp $
+ */
+#ifndef __CLOCK_H__
+#define __CLOCK_H__
+
+#include "clock-arch.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize the clock library.
+ *
+ * This function initializes the clock library and should be called
+ * from the main() function of the system.
+ *
+ */
+void clock_init(void);
+
+/**
+ * Get the current clock time.
+ *
+ * This function returns the current system clock time.
+ *
+ * \return The current clock time, measured in system ticks.
+ */
+clock_time_t clock_time(void);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * A second, measured in system clock time.
+ *
+ * \hideinitializer
+ */
+#ifdef CLOCK_CONF_SECOND
+#define CLOCK_SECOND CLOCK_CONF_SECOND
+#else
+#define CLOCK_SECOND (clock_time_t)32
+#endif
+
+#endif /* __CLOCK_H__ */
+
+/** @} */
View
83 src/libs/Network/uip/uip/lc-addrlabels.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-addrlabels.h,v 1.3 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on the "Labels as
+ * values" feature of gcc
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations is based on a special
+ * feature of the GCC C compiler called "labels as values". This
+ * feature allows assigning pointers with the address of the code
+ * corresponding to a particular C label.
+ *
+ * For more information, see the GCC documentation:
+ * http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+ *
+ * Thanks to dividuum for finding the nice local scope label
+ * implementation.
+ */
+
+#ifndef __LC_ADDRLABELS_H__
+#define __LC_ADDRLABELS_H__
+
+/** \hideinitializer */
+typedef void * lc_t;
+
+#define LC_INIT(s) s = NULL
+
+
+#define LC_RESUME(s) \
+ do { \
+ if(s != NULL) { \
+ goto *s; \
+ } \
+ } while(0)
+
+#define LC_SET(s) \
+ do { ({ __label__ resume; resume: (s) = &&resume; }); }while(0)
+
+#define LC_END(s)
+
+#endif /* __LC_ADDRLABELS_H__ */
+
+/** @} */
View
76 src/libs/Network/uip/uip/lc-switch.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc-switch.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup lc
+ * @{
+ */
+
+/**
+ * \file
+ * Implementation of local continuations based on switch() statment
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This implementation of local continuations uses the C switch()
+ * statement to resume execution of a function somewhere inside the
+ * function's body. The implementation is based on the fact that
+ * switch() statements are able to jump directly into the bodies of
+ * control structures such as if() or while() statmenets.
+ *
+ * This implementation borrows heavily from Simon Tatham's coroutines
+ * implementation in C:
+ * http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ */
+
+#ifndef __LC_SWITCH_H__
+#define __LC_SWTICH_H__
+
+/* WARNING! lc implementation using switch() does not work if an
+ LC_SET() is done within another switch() statement! */
+
+/** \hideinitializer */
+typedef unsigned short lc_t;
+
+#define LC_INIT(s) s = 0;
+
+#define LC_RESUME(s) switch(s) { case 0:
+
+#define LC_SET(s) s = __LINE__; case __LINE__:
+
+#define LC_END(s) }
+
+#endif /* __LC_SWITCH_H__ */
+
+/** @} */
View
131 src/libs/Network/uip/uip/lc.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: lc.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \defgroup lc Local continuations
+ * @{
+ *
+ * Local continuations form the basis for implementing protothreads. A
+ * local continuation can be <i>set</i> in a specific function to
+ * capture the state of the function. After a local continuation has
+ * been set can be <i>resumed</i> in order to restore the state of the
+ * function at the point where the local continuation was set.
+ *
+ *
+ */
+
+/**
+ * \file lc.h
+ * Local continuations
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifdef DOXYGEN
+/**
+ * Initialize a local continuation.
+ *
+ * This operation initializes the local continuation, thereby
+ * unsetting any previously set continuation state.
+ *
+ * \hideinitializer
+ */
+#define LC_INIT(lc)
+
+/**
+ * Set a local continuation.
+ *
+ * The set operation saves the state of the function at the point
+ * where the operation is executed. As far as the set operation is
+ * concerned, the state of the function does <b>not</b> include the
+ * call-stack or local (automatic) variables, but only the program
+ * counter and such CPU registers that needs to be saved.
+ *
+ * \hideinitializer
+ */
+#define LC_SET(lc)
+
+/**
+ * Resume a local continuation.
+ *
+ * The resume operation resumes a previously set local continuation, thus
+ * restoring the state in which the function was when the local
+ * continuation was set. If the local continuation has not been
+ * previously set, the resume operation does nothing.
+ *
+ * \hideinitializer
+ */
+#define LC_RESUME(lc)
+
+/**
+ * Mark the end of local continuation usage.
+ *
+ * The end operation signifies that local continuations should not be
+ * used any more in the function. This operation is not needed for
+ * most implementations of local continuation, but is required by a
+ * few implementations.
+ *
+ * \hideinitializer
+ */
+#define LC_END(lc)
+
+/**
+ * \var typedef lc_t;
+ *
+ * The local continuation type.
+ *
+ * \hideinitializer
+ */
+#endif /* DOXYGEN */
+
+#ifndef __LC_H__
+#define __LC_H__
+
+#ifdef LC_CONF_INCLUDE
+#include LC_CONF_INCLUDE
+#else
+#include "lc-switch.h"
+#endif /* LC_CONF_INCLUDE */
+
+#endif /* __LC_H__ */
+
+/** @} */
+/** @} */
View
373 src/libs/Network/uip/uip/psock.c
@@ -0,0 +1,373 @@
+#pragma GCC diagnostic ignored "-Wpointer-sign"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: psock.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "uipopt.h"
+#include "psock.h"
+#include "uip.h"
+
+#define STATE_NONE 0
+#define STATE_ACKED 1
+#define STATE_READ 2
+#define STATE_BLOCKED_NEWDATA 3
+#define STATE_BLOCKED_CLOSE 4
+#define STATE_BLOCKED_SEND 5
+#define STATE_DATA_SENT 6
+
+/*
+ * Return value of the buffering functions that indicates that a
+ * buffer was not filled by incoming data.
+ *
+ */
+#define BUF_NOT_FULL 0
+#define BUF_NOT_FOUND 0
+
+/*
+ * Return value of the buffering functions that indicates that a
+ * buffer was completely filled by incoming data.
+ *
+ */
+#define BUF_FULL 1
+
+/*
+ * Return value of the buffering functions that indicates that an
+ * end-marker byte was found.
+ *
+ */
+#define BUF_FOUND 2
+
+/*---------------------------------------------------------------------------*/
+static void
+buf_setup(struct psock_buf *buf,
+ u8_t *bufptr, u16_t bufsize)
+{
+ buf->ptr = bufptr;
+ buf->left = bufsize;
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+buf_bufdata(struct psock_buf *buf, u16_t len,
+ u8_t **dataptr, u16_t *datalen)
+{
+ if (*datalen < buf->left) {
+ memcpy(buf->ptr, *dataptr, *datalen);
+ buf->ptr += *datalen;
+ buf->left -= *datalen;
+ *dataptr += *datalen;
+ *datalen = 0;
+ return BUF_NOT_FULL;
+ } else if (*datalen == buf->left) {
+ memcpy(buf->ptr, *dataptr, *datalen);
+ buf->ptr += *datalen;
+ buf->left = 0;
+ *dataptr += *datalen;
+ *datalen = 0;
+ return BUF_FULL;
+ } else {
+ memcpy(buf->ptr, *dataptr, buf->left);
+ buf->ptr += buf->left;
+ *datalen -= buf->left;
+ *dataptr += buf->left;
+ buf->left = 0;
+ return BUF_FULL;
+ }
+}
+/*---------------------------------------------------------------------------*/
+static u8_t
+buf_bufto(register struct psock_buf *buf, u8_t endmarker,
+ register u8_t **dataptr, register u16_t *datalen)
+{
+ u8_t c;
+ while (buf->left > 0 && *datalen > 0) {
+ c = *buf->ptr = **dataptr;
+ ++*dataptr;
+ ++buf->ptr;
+ --*datalen;
+ --buf->left;
+
+ if (c == endmarker) {
+ return BUF_FOUND;
+ }
+ }
+
+ if (*datalen == 0) {
+ return BUF_NOT_FOUND;
+ }
+
+ while (*datalen > 0) {
+ c = **dataptr;
+ --*datalen;
+ ++*dataptr;
+
+ if (c == endmarker) {
+ return BUF_FOUND | BUF_FULL;
+ }
+ }
+
+ return BUF_FULL;
+}
+/*---------------------------------------------------------------------------*/
+static char
+send_data(register struct psock *s)
+{
+ if (s->state != STATE_DATA_SENT || uip_rexmit()) {
+ if (s->sendlen > uip_mss()) {
+ uip_send(s->sendptr, uip_mss());
+ } else {
+ uip_send(s->sendptr, s->sendlen);
+ }
+ s->state = STATE_DATA_SENT;
+ return 1;
+ }
+ return 0;
+}
+/*---------------------------------------------------------------------------*/
+static char
+data_acked(register struct psock *s)
+{
+ if (s->state == STATE_DATA_SENT && uip_acked()) {
+ if (s->sendlen > uip_mss()) {
+ s->sendlen -= uip_mss();
+ s->sendptr += uip_mss();
+ } else {
+ s->sendptr += s->sendlen;
+ s->sendlen = 0;
+ }
+ s->state = STATE_ACKED;
+ return 1;
+ }
+ return 0;
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_send(register struct psock *s, const char *buf,
+ unsigned int len))
+{
+ PT_BEGIN(&s->psockpt);
+
+ /* If there is no data to send, we exit immediately. */
+ if (len == 0) {
+ PT_EXIT(&s->psockpt);
+ }
+
+ /* Save the length of and a pointer to the data that is to be
+ sent. */
+ s->sendptr = buf;
+ s->sendlen = len;
+
+ s->state = STATE_NONE;
+
+ /* We loop here until all data is sent. The s->sendlen variable is
+ updated by the data_sent() function. */
+ while (s->sendlen > 0) {
+
+ /*
+ * The condition for this PT_WAIT_UNTIL is a little tricky: the
+ * protothread will wait here until all data has been acknowledged
+ * (data_acked() returns true) and until all data has been sent
+ * (send_data() returns true). The two functions data_acked() and
+ * send_data() must be called in succession to ensure that all
+ * data is sent. Therefore the & operator is used instead of the
+ * && operator, which would cause only the data_acked() function
+ * to be called when it returns false.
+ */
+ PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+ }
+
+ s->state = STATE_NONE;
+
+ PT_END(&s->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_generator_send(register struct psock *s,
+ unsigned short (*generate)(void *), void *arg))
+{
+ PT_BEGIN(&s->psockpt);
+
+ /* Ensure that there is a generator function to call. */
+ if (generate == NULL) {
+ PT_EXIT(&s->psockpt);
+ }
+
+ /* Call the generator function to generate the data in the
+ uip_appdata buffer. */
+ s->sendlen = generate(arg);
+ s->sendptr = uip_appdata;
+
+ s->state = STATE_NONE;
+ do {
+ /* Call the generator function again if we are called to perform a
+ retransmission. */
+ if (uip_rexmit()) {
+ generate(arg);
+ }
+ /* Wait until all data is sent and acknowledged. */
+ PT_WAIT_UNTIL(&s->psockpt, data_acked(s) & send_data(s));
+ } while (s->sendlen > 0);
+
+ s->state = STATE_NONE;
+
+ PT_END(&s->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+u16_t
+psock_datalen(struct psock *psock)
+{
+ return psock->bufsize - psock->buf.left;
+}
+/*---------------------------------------------------------------------------*/
+char
+psock_newdata(struct psock *s)
+{
+ if (s->readlen > 0) {
+ /* There is data in the uip_appdata buffer that has not yet been
+ read with the PSOCK_READ functions. */
+ return 1;
+ } else if (s->state == STATE_READ) {
+ /* All data in uip_appdata buffer already consumed. */
+ s->state = STATE_BLOCKED_NEWDATA;
+ return 0;
+ } else if (uip_newdata()) {
+ /* There is new data that has not been consumed. */
+ return 1;
+ } else {
+ /* There is no new data. */
+ return 0;
+ }
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readto(register struct psock *psock, unsigned char c))
+{
+ PT_BEGIN(&psock->psockpt);
+
+ buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+
+ /* XXX: Should add buf_checkmarker() before do{} loop, if
+ incoming data has been handled while waiting for a write. */
+
+ do {
+ if (psock->readlen == 0) {
+ PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+ psock->state = STATE_READ;
+ psock->readptr = (u8_t *)uip_appdata;
+ psock->readlen = uip_datalen();
+ }
+ } while ((buf_bufto(&psock->buf, c,
+ &psock->readptr,
+ &psock->readlen) & BUF_FOUND) == 0);
+
+ if (psock_datalen(psock) == 0) {
+ psock->state = STATE_NONE;
+ PT_RESTART(&psock->psockpt);
+ }
+ PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readbuf(register struct psock *psock))
+{
+ PT_BEGIN(&psock->psockpt);
+
+ buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
+
+ /* XXX: Should add buf_checkmarker() before do{} loop, if
+ incoming data has been handled while waiting for a write. */
+
+ do {
+ if (psock->readlen == 0) {
+ PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+ //printf("Waited for newdata\n");
+ psock->state = STATE_READ;
+ psock->readptr = (u8_t *)uip_appdata;
+ psock->readlen = uip_datalen();
+ }
+ } while (buf_bufdata(&psock->buf, psock->bufsize,
+ &psock->readptr,
+ &psock->readlen) != BUF_FULL);
+
+ if (psock_datalen(psock) == 0) {
+ psock->state = STATE_NONE;
+ PT_RESTART(&psock->psockpt);
+ }
+ PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+PT_THREAD(psock_readbuf_len(register struct psock *psock, uint16_t len))
+{
+ PT_BEGIN(&psock->psockpt);
+
+ // setup to read the smaller of buffer size or len
+ if(len > psock->bufsize) len= psock->bufsize;
+ buf_setup(&psock->buf, psock->bufptr, len);
+
+ /* XXX: Should add buf_checkmarker() before do{} loop, if
+ incoming data has been handled while waiting for a write. */
+
+ /* read len bytes or to end of data */
+ do {
+ if (psock->readlen == 0) {
+ PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
+ psock->state = STATE_READ;
+ psock->readptr = (uint8_t *)uip_appdata;
+ psock->readlen = uip_datalen();
+ }
+ } while (buf_bufdata(&psock->buf, psock->bufsize,
+ &psock->readptr, &psock->readlen) != BUF_FULL);
+
+ if (psock_datalen(psock) == 0) {
+ psock->state = STATE_NONE;
+ PT_RESTART(&psock->psockpt);
+ }
+ PT_END(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
+void
+psock_init(register struct psock *psock, char *buffer, unsigned int buffersize)
+{
+ psock->state = STATE_NONE;
+ psock->readlen = 0;
+ psock->bufptr = buffer;
+ psock->bufsize = buffersize;
+ buf_setup(&psock->buf, buffer, buffersize);
+ PT_INIT(&psock->pt);
+ PT_INIT(&psock->psockpt);
+}
+/*---------------------------------------------------------------------------*/
View
409 src/libs/Network/uip/uip/psock.h
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: psock.h,v 1.3 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \defgroup psock Protosockets library
+ * @{
+ *
+ * The protosocket library provides an interface to the uIP stack that is
+ * similar to the traditional BSD socket interface. Unlike programs
+ * written for the ordinary uIP event-driven interface, programs
+ * written with the protosocket library are executed in a sequential
+ * fashion and does not have to be implemented as explicit state
+ * machines.
+ *
+ * Protosockets only work with TCP connections.
+ *
+ * The protosocket library uses \ref pt protothreads to provide
+ * sequential control flow. This makes the protosockets lightweight in
+ * terms of memory, but also means that protosockets inherits the
+ * functional limitations of protothreads. Each protosocket lives only
+ * within a single function. Automatic variables (stack variables) are
+ * not retained across a protosocket library function call.
+ *
+ * \note Because the protosocket library uses protothreads, local
+ * variables will not always be saved across a call to a protosocket
+ * library function. It is therefore advised that local variables are
+ * used with extreme care.
+ *
+ * The protosocket library provides functions for sending data without
+ * having to deal with retransmissions and acknowledgements, as well
+ * as functions for reading data without having to deal with data
+ * being split across more than one TCP segment.
+ *
+ * Because each protosocket runs as a protothread, the protosocket has to be
+ * started with a call to PSOCK_BEGIN() at the start of the function
+ * in which the protosocket is used. Similarly, the protosocket protothread can
+ * be terminated by a call to PSOCK_EXIT().
+ *
+ */
+
+/**
+ * \file
+ * Protosocket library header file
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PSOCK_H__
+#define __PSOCK_H__
+
+#include "uipopt.h"
+#include "pt.h"
+
+ /*
+ * The structure that holds the state of a buffer.
+ *
+ * This structure holds the state of a uIP buffer. The structure has
+ * no user-visible elements, but is used through the functions
+ * provided by the library.
+ *
+ */
+struct psock_buf {
+ u8_t *ptr;
+ unsigned short left;
+};
+
+/**
+ * The representation of a protosocket.
+ *
+ * The protosocket structrure is an opaque structure with no user-visible
+ * elements.
+ */
+struct psock {
+ struct pt pt, psockpt; /* Protothreads - one that's using the psock
+ functions, and one that runs inside the
+ psock functions. */
+ const u8_t *sendptr; /* Pointer to the next data to be sent. */
+ u8_t *readptr; /* Pointer to the next data to be read. */
+
+ char *bufptr; /* Pointer to the buffer used for buffering
+ incoming data. */
+
+ u16_t sendlen; /* The number of bytes left to be sent. */
+ u16_t readlen; /* The number of bytes left to be read. */
+
+ struct psock_buf buf; /* The structure holding the state of the
+ input buffer. */
+ unsigned int bufsize; /* The size of the input buffer. */
+
+ unsigned char state; /* The state of the protosocket. */
+};
+
+void psock_init(struct psock *psock, char *buffer, unsigned int buffersize);
+/**
+ * Initialize a protosocket.
+ *
+ * This macro initializes a protosocket and must be called before the
+ * protosocket is used. The initialization also specifies the input buffer
+ * for the protosocket.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket to be
+ * initialized
+ *
+ * \param buffer (char *) A pointer to the input buffer for the
+ * protosocket.
+ *
+ * \param buffersize (unsigned int) The size of the input buffer.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_INIT(psock, buffer, buffersize) \
+ psock_init(psock, buffer, buffersize)
+
+/**
+ * Start the protosocket protothread in a function.
+ *
+ * This macro starts the protothread associated with the protosocket and
+ * must come before other protosocket calls in the function it is used.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket to be
+ * started.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
+
+PT_THREAD(psock_send(struct psock *psock, const char *buf, unsigned int len));
+/**
+ * Send data.
+ *
+ * This macro sends data over a protosocket. The protosocket protothread blocks
+ * until all data has been sent and is known to have been received by
+ * the remote end of the TCP connection.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket over which
+ * data is to be sent.
+ *
+ * \param data (char *) A pointer to the data that is to be sent.
+ *
+ * \param datalen (unsigned int) The length of the data that is to be
+ * sent.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_SEND(psock, data, datalen) \
+ PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, data, datalen))
+
+/**
+ * \brief Send a null-terminated string.
+ * \param psock Pointer to the protosocket.
+ * \param str The string to be sent.
+ *
+ * This function sends a null-terminated string over the
+ * protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_SEND_STR(psock, str) \
+ PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, str, strlen(str)))
+
+PT_THREAD(psock_generator_send(struct psock *psock,
+ unsigned short (*f)(void *), void *arg));
+
+/**
+ * \brief Generate data with a function and send it
+ * \param psock Pointer to the protosocket.
+ * \param generator Pointer to the generator function
+ * \param arg Argument to the generator function
+ *
+ * This function generates data and sends it over the
+ * protosocket. This can be used to dynamically generate
+ * data for a transmission, instead of generating the data
+ * in a buffer beforehand. This function reduces the need for
+ * buffer memory. The generator function is implemented by
+ * the application, and a pointer to the function is given
+ * as an argument with the call to PSOCK_GENERATOR_SEND().
+ *
+ * The generator function should place the generated data
+ * directly in the uip_appdata buffer, and return the
+ * length of the generated data. The generator function is
+ * called by the protosocket layer when the data first is
+ * sent, and once for every retransmission that is needed.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_GENERATOR_SEND(psock, generator, arg) \
+ PT_WAIT_THREAD(&((psock)->pt), \
+ psock_generator_send(psock, generator, arg))
+
+
+/**
+ * Close a protosocket.
+ *
+ * This macro closes a protosocket and can only be called from within the
+ * protothread in which the protosocket lives.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket that is to
+ * be closed.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_CLOSE(psock) uip_close()
+
+PT_THREAD(psock_readbuf(struct psock *psock));
+/**
+ * Read data until the buffer is full.
+ *
+ * This macro will block waiting for data and read the data into the
+ * input buffer specified with the call to PSOCK_INIT(). Data is read
+ * until the buffer is full..
+ *
+ * \param psock (struct psock *) A pointer to the protosocket from which
+ * data should be read.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_READBUF(psock) \
+ PT_WAIT_THREAD(&((psock)->pt), psock_readbuf(psock))
+
+PT_THREAD(psock_readbuf_len(struct psock *psock, uint16_t len));
+
+/**
+ * Read n bytes of data where n is the smaller of the buffer size or len
+ *
+ * This macro will block waiting for data and read the data into the
+ * input buffer specified with the call to PSOCK_INIT(). Data is read
+ * until either len bytes are read or size of the buffer, note len should
+ * be smaller or equel to the buffer size
+ *
+ * \param psock (struct psock *) A pointer to the protosocket from which
+ * data should be read.
+ *
+ * \param len (int) The number of bytes to be read.
+ * \hideinitializer
+ */
+#define PSOCK_READBUF_LEN(psock, len) \
+PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len))
+
+
+PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
+/**
+ * Read data up to a specified character.
+ *
+ * This macro will block waiting for data and read the data into the
+ * input buffer specified with the call to PSOCK_INIT(). Data is only
+ * read until the specifieed character appears in the data stream.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket from which
+ * data should be read.
+ *
+ * \param c (char) The character at which to stop reading.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_READTO(psock, c) \
+ PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))
+
+/**
+ * The length of the data that was previously read.
+ *
+ * This macro returns the length of the data that was previously read
+ * using PSOCK_READTO() or PSOCK_READ().
+ *
+ * \param psock (struct psock *) A pointer to the protosocket holding the data.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_DATALEN(psock) psock_datalen(psock)
+
+u16_t psock_datalen(struct psock *psock);
+
+/**
+ * Exit the protosocket's protothread.
+ *
+ * This macro terminates the protothread of the protosocket and should
+ * almost always be used in conjunction with PSOCK_CLOSE().
+ *
+ * \sa PSOCK_CLOSE_EXIT()
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))
+
+/**
+ * Close a protosocket and exit the protosocket's protothread.
+ *
+ * This macro closes a protosocket and exits the protosocket's protothread.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_CLOSE_EXIT(psock) \
+ do { \
+ PSOCK_CLOSE(psock); \
+ PSOCK_EXIT(psock); \
+ } while(0)
+
+/**
+ * Declare the end of a protosocket's protothread.
+ *
+ * This macro is used for declaring that the protosocket's protothread
+ * ends. It must always be used together with a matching PSOCK_BEGIN()
+ * macro.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_END(psock) PT_END(&((psock)->pt))
+
+char psock_newdata(struct psock *s);
+
+/**
+ * Check if new data has arrived on a protosocket.
+ *
+ * This macro is used in conjunction with the PSOCK_WAIT_UNTIL()
+ * macro to check if data has arrived on a protosocket.
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_NEWDATA(psock) psock_newdata(psock)
+
+/**
+ * Wait until a condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true. The macro PSOCK_NEWDATA() can be used to check if new data
+ * arrives when the protosocket is waiting.
+ *
+ * Typically, this macro is used as follows:
+ *
+ \code
+ PT_THREAD(thread(struct psock *s, struct timer *t))
+ {
+ PSOCK_BEGIN(s);
+
+ PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t));
+
+ if(PSOCK_NEWDATA(s)) {
+ PSOCK_READTO(s, '\n');
+ } else {
+ handle_timed_out(s);
+ }
+
+ PSOCK_END(s);
+ }
+ \endcode
+ *
+ * \param psock (struct psock *) A pointer to the protosocket.
+ * \param condition The condition to wait for.
+ *
+ * \hideinitializer
+ */
+#define PSOCK_WAIT_UNTIL(psock, condition) \
+ PT_WAIT_UNTIL(&((psock)->pt), (condition));
+
+#define PSOCK_WAIT_THREAD(psock, condition) \
+ PT_WAIT_THREAD(&((psock)->pt), (condition))
+
+
+/**
+ * return a pointer and length of whatever is left in the uip_appdata buffer
+ * after previous use of PSOCK_READTO() and mark the internal buffer as fully read
+ */
+#define PSOCK_GET_LENGTH_OF_REST_OF_BUFFER(psock) (psock)->readlen
+#define PSOCK_GET_START_OF_REST_OF_BUFFER(psock) (psock)->readptr
+#define PSOCK_MARK_BUFFER_READ(psock) do { (psock)->readlen= 0; (psock)->state = 0; } while(0)
+
+#endif /* __PSOCK_H__ */
+
+/** @} */
View
323 src/libs/Network/uip/uip/pt.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: pt.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \addtogroup pt
+ * @{
+ */
+
+/**
+ * \file
+ * Protothreads implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __PT_H__
+#define __PT_H__
+
+#include "lc.h"
+
+struct pt {
+ lc_t lc;
+};
+
+#define PT_WAITING 0
+#define PT_EXITED 1
+#define PT_ENDED 2
+#define PT_YIELDED 3
+
+/**
+ * \name Initialization
+ * @{
+ */
+
+/**
+ * Initialize a protothread.
+ *
+ * Initializes a protothread. Initialization must be done prior to
+ * starting to execute the protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_INIT(pt) LC_INIT((pt)->lc)
+
+/** @} */
+
+/**
+ * \name Declaration and definition
+ * @{
+ */
+
+/**
+ * Declaration of a protothread.
+ *
+ * This macro is used to declare a protothread. All protothreads must
+ * be declared with this macro.
+ *
+ * \param name_args The name and arguments of the C function
+ * implementing the protothread.
+ *
+ * \hideinitializer
+ */
+#define PT_THREAD(name_args) char name_args
+
+/**
+ * Declare the start of a protothread inside the C function
+ * implementing the protothread.
+ *
+ * This macro is used to declare the starting point of a
+ * protothread. It should be placed at the start of the function in
+ * which the protothread runs. All C statements above the PT_BEGIN()
+ * invokation will be executed each time the protothread is scheduled.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_BEGIN(pt) { char PT_YIELD_FLAG = 1; LC_RESUME((pt)->lc)
+
+/**
+ * Declare the end of a protothread.
+ *
+ * This macro is used for declaring that a protothread ends. It must
+ * always be used together with a matching PT_BEGIN() macro.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_END(pt) LC_END((pt)->lc); PT_YIELD_FLAG = 0; \
+ PT_INIT(pt); return PT_ENDED; }
+
+/** @} */
+
+/**
+ * \name Blocked wait
+ * @{
+ */
+
+/**
+ * Block and wait until condition is true.
+ *
+ * This macro blocks the protothread until the specified condition is
+ * true.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param condition The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_UNTIL(pt, condition) \
+ do { \
+ LC_SET((pt)->lc); \
+ if(!(condition)) { \
+ return PT_WAITING; \
+ } \
+ } while(0)
+
+/**
+ * Block and wait while condition is true.
+ *
+ * This function blocks and waits while condition is true. See
+ * PT_WAIT_UNTIL().
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_WHILE(pt, cond) PT_WAIT_UNTIL((pt), !(cond))
+
+/** @} */
+
+/**
+ * \name Hierarchical protothreads
+ * @{
+ */
+
+/**
+ * Block and wait until a child protothread completes.
+ *
+ * This macro schedules a child protothread. The current protothread
+ * will block until the child protothread completes.
+ *
+ * \note The child protothread must be manually initialized with the
+ * PT_INIT() function before this function is used.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \sa PT_SPAWN()
+ *
+ * \hideinitializer
+ */
+#define PT_WAIT_THREAD(pt, thread) PT_WAIT_WHILE((pt), PT_SCHEDULE(thread))
+
+/**
+ * Spawn a child protothread and wait until it exits.
+ *
+ * This macro spawns a child protothread and waits until it exits. The
+ * macro can only be used within a protothread.
+ *
+ * \param pt A pointer to the protothread control structure.
+ * \param child A pointer to the child protothread's control structure.
+ * \param thread The child protothread with arguments
+ *
+ * \hideinitializer
+ */
+#define PT_SPAWN(pt, child, thread) \
+ do { \
+ PT_INIT((child)); \
+ PT_WAIT_THREAD((pt), (thread)); \
+ } while(0)
+
+/** @} */
+
+/**
+ * \name Exiting and restarting
+ * @{
+ */
+
+/**
+ * Restart the protothread.
+ *
+ * This macro will block and cause the running protothread to restart
+ * its execution at the place of the PT_BEGIN() call.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_RESTART(pt) \
+ do { \
+ PT_INIT(pt); \
+ return PT_WAITING; \
+ } while(0)
+
+/**
+ * Exit the protothread.
+ *
+ * This macro causes the protothread to exit. If the protothread was
+ * spawned by another protothread, the parent protothread will become
+ * unblocked and can continue to run.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_EXIT(pt) \
+ do { \
+ PT_INIT(pt); \
+ return PT_EXITED; \
+ } while(0)
+
+/** @} */
+
+/**
+ * \name Calling a protothread
+ * @{
+ */
+
+/**
+ * Schedule a protothread.
+ *
+ * This function shedules a protothread. The return value of the
+ * function is non-zero if the protothread is running or zero if the
+ * protothread has exited.
+ *
+ * \param f The call to the C function implementing the protothread to
+ * be scheduled
+ *
+ * \hideinitializer
+ */
+#define PT_SCHEDULE(f) ((f) == PT_WAITING)
+
+/** @} */
+
+/**
+ * \name Yielding from a protothread
+ * @{
+ */
+
+/**
+ * Yield from the current protothread.
+ *
+ * This function will yield the protothread, thereby allowing other
+ * processing to take place in the system.
+ *
+ * \param pt A pointer to the protothread control structure.
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD(pt) \
+ do { \
+ PT_YIELD_FLAG = 0; \
+ LC_SET((pt)->lc); \
+ if(PT_YIELD_FLAG == 0) { \
+ return PT_YIELDED; \
+ } \
+ } while(0)
+
+/**
+ * \brief Yield from the protothread until a condition occurs.
+ * \param pt A pointer to the protothread control structure.
+ * \param cond The condition.
+ *
+ * This function will yield the protothread, until the
+ * specified condition evaluates to true.
+ *
+ *
+ * \hideinitializer
+ */
+#define PT_YIELD_UNTIL(pt, cond) \
+ do { \
+ PT_YIELD_FLAG = 0; \
+ LC_SET((pt)->lc); \
+ if((PT_YIELD_FLAG == 0) || !(cond)) { \
+ return PT_YIELDED; \
+ } \
+ } while(0)
+
+/** @} */
+
+#endif /* __PT_H__ */
+
+/** @} */
View
127 src/libs/Network/uip/uip/timer.c
@@ -0,0 +1,127 @@
+/**
+ * \addtogroup timer
+ * @{
+ */
+
+/**
+ * \file
+ * Timer library implementation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: timer.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include "clock.h"
+#include "timer.h"
+
+/*---------------------------------------------------------------------------*/
+/**
+ * Set a timer.
+ *
+ * This function is used to set a timer for a time sometime in the
+ * future. The function timer_expired() will evaluate to true after
+ * the timer has expired.
+ *
+ * \param t A pointer to the timer
+ * \param interval The interval before the timer expires.
+ *
+ */
+void
+timer_set(struct timer *t, clock_time_t interval)
+{
+ t->interval = interval;
+ t->start = clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Reset the timer with the same interval.
+ *
+ * This function resets the timer with the same interval that was
+ * given to the timer_set() function. The start point of the interval
+ * is the exact time that the timer last expired. Therefore, this
+ * function will cause the timer to be stable over time, unlike the
+ * timer_rester() function.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_restart()
+ */
+void
+timer_reset(struct timer *t)
+{
+ t->start += t->interval;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Restart the timer from the current point in time
+ *
+ * This function restarts a timer with the same interval that was
+ * given to the timer_set() function. The timer will start at the
+ * current time.
+ *
+ * \note A periodic timer will drift if this function is used to reset
+ * it. For preioric timers, use the timer_reset() function instead.
+ *
+ * \param t A pointer to the timer.
+ *
+ * \sa timer_reset()
+ */
+void
+timer_restart(struct timer *t)
+{
+ t->start = clock_time();
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * Check if a timer has expired.
+ *
+ * This function tests if a timer has expired and returns true or
+ * false depending on its status.
+ *
+ * \param t A pointer to the timer
+ *
+ * \return Non-zero if the timer has expired, zero otherwise.
+ *
+ */
+int
+timer_expired(struct timer *t)
+{
+ return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
+}
+/*---------------------------------------------------------------------------*/
+
+/** @} */
View
94 src/libs/Network/uip/uip/timer.h
@@ -0,0 +1,94 @@
+/**
+ * \defgroup timer Timer library
+ *
+ * The timer library provides functions for setting, resetting and
+ * restarting timers, and for checking if a timer has expired. An
+ * application must "manually" check if its timers have expired; this
+ * is not done automatically.
+ *
+ * A timer is declared as a \c struct \c timer and all access to the
+ * timer is made by a pointer to the declared timer.
+ *
+ * \note The timer library uses the \ref clock "Clock library" to
+ * measure time. Intervals should be specified in the format used by
+ * the clock library.
+ *
+ * @{
+ */
+
+
+/**
+ * \file
+ * Timer library header file.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: timer.h,v 1.3 2006/06/11 21:46:39 adam Exp $
+ */
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+#include "clock.h"
+
+/**
+ * A timer.
+ *
+ * This structure is used for declaring a timer. The timer must be set
+ * with timer_set() before it can be used.
+ *
+ * \hideinitializer
+ */
+struct timer {
+ clock_time_t start;
+ clock_time_t interval;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void timer_set(struct timer *t, clock_time_t interval);
+void timer_reset(struct timer *t);
+void timer_restart(struct timer *t);
+int timer_expired(struct timer *t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIMER_H__ */
+
+/** @} */
View
537 src/libs/Network/uip/uip/uip-fw.c
@@ -0,0 +1,537 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-fw.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \defgroup uipfw uIP packet forwarding
+ * @{
+ *
+ */
+
+/**
+ * \file
+ * uIP packet forwarding.
+ * \author Adam Dunkels <adam@sics.se>
+ *
+ * This file implements a number of simple functions which do packet
+ * forwarding over multiple network interfaces with uIP.
+ *
+ */
+
+#include "uip.h"
+#include "uip_arch.h"
+#include "uip-fw.h"
+
+#include <string.h> /* for memcpy() */
+
+/*
+ * The list of registered network interfaces.
+ */
+static struct uip_fw_netif *netifs = NULL;
+
+/*
+ * A pointer to the default network interface.
+ */
+static struct uip_fw_netif *defaultnetif = NULL;
+
+struct tcpip_hdr {
+ /* IP header. */
+ u8_t vhl,
+ tos;
+ u16_t len,
+ ipid,
+ ipoffset;
+ u8_t ttl,
+ proto;
+ u16_t ipchksum;
+ u16_t srcipaddr[2],
+ destipaddr[2];
+
+ /* TCP header. */
+ u16_t srcport,
+ destport;
+ u8_t seqno[4],
+ ackno[4],
+ tcpoffset,
+ flags,
+ wnd[2];
+ u16_t tcpchksum;
+ u8_t urgp[2];
+ u8_t optdata[4];
+};
+
+struct icmpip_hdr {
+ /* IP header. */
+ u8_t vhl,
+ tos,
+ len[2],
+ ipid[2],
+ ipoffset[2],
+ ttl,
+ proto;
+ u16_t ipchksum;
+ u16_t srcipaddr[2],
+ destipaddr[2];
+ /* ICMP (echo) header. */
+ u8_t type, icode;
+ u16_t icmpchksum;
+ u16_t id, seqno;
+ u8_t payload[1];
+};
+
+/* ICMP ECHO. */
+#define ICMP_ECHO 8
+
+/* ICMP TIME-EXCEEDED. */
+#define ICMP_TE 11
+
+/*
+ * Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
+ */
+#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+/*
+ * Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
+ */
+#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+/*
+ * Certain fields of an IP packet that are used for identifying
+ * duplicate packets.
+ */
+struct fwcache_entry {
+ u16_t timer;
+
+ u16_t srcipaddr[2];
+ u16_t destipaddr[2];
+ u16_t ipid;
+ u8_t proto;
+ u8_t unused;
+
+#if notdef
+ u16_t payload[2];
+#endif
+
+#if UIP_REASSEMBLY > 0
+ u16_t len, offset;
+#endif
+};
+
+/*
+ * The number of packets to remember when looking for duplicates.
+ */
+#ifdef UIP_CONF_FWCACHE_SIZE
+#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
+#else
+#define FWCACHE_SIZE 2
+#endif
+
+
+/*
+ * A cache of packet header fields which are used for
+ * identifying duplicate packets.
+ */
+static struct fwcache_entry fwcache[FWCACHE_SIZE];
+
+/**
+ * \internal
+ * The time that a packet cache is active.
+ */
+#define FW_TIME 20
+
+/*------------------------------------------------------------------------------*/
+/**
+ * Initialize the uIP packet forwarding module.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_init(void)
+{
+ struct uip_fw_netif *t;
+ defaultnetif = NULL;
+ while(netifs != NULL) {
+ t = netifs;
+ netifs = netifs->next;
+ t->next = NULL;
+ }
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Check if an IP address is within the network defined by an IP
+ * address and a netmask.
+ *
+ * \param ipaddr The IP address to be checked.
+ * \param netipaddr The IP address of the network.
+ * \param netmask The netmask of the network.
+ *
+ * \return Non-zero if IP address is in network, zero otherwise.
+ */
+/*------------------------------------------------------------------------------*/
+static unsigned char
+ipaddr_maskcmp(u16_t *ipaddr, u16_t *netipaddr, u16_t *netmask)
+{
+ return (ipaddr[0] & netmask [0]) == (netipaddr[0] & netmask[0]) &&
+ (ipaddr[1] & netmask[1]) == (netipaddr[1] & netmask[1]);
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Send out an ICMP TIME-EXCEEDED message.
+ *
+ * This function replaces the packet in the uip_buf buffer with the
+ * ICMP packet.
+ */
+/*------------------------------------------------------------------------------*/
+static void
+time_exceeded(void)
+{
+ u16_t tmp16;
+
+ /* We don't send out ICMP errors for ICMP messages. */
+ if(ICMPBUF->proto == UIP_PROTO_ICMP) {
+ uip_len = 0;
+ return;
+ }
+ /* Copy fields from packet header into payload of this ICMP packet. */
+ memcpy(&(ICMPBUF->payload[0]), ICMPBUF, 28);
+
+ /* Set the ICMP type and code. */
+ ICMPBUF->type = ICMP_TE;
+ ICMPBUF->icode = 0;
+
+ /* Calculate the ICMP checksum. */
+ ICMPBUF->icmpchksum = 0;
+ ICMPBUF->icmpchksum = ~uip_chksum((u16_t *)&(ICMPBUF->type), 36);
+
+ /* Set the IP destination address to be the source address of the
+ original packet. */
+ tmp16= BUF->destipaddr[0];
+ BUF->destipaddr[0] = BUF->srcipaddr[0];
+ BUF->srcipaddr[0] = tmp16;
+ tmp16 = BUF->destipaddr[1];
+ BUF->destipaddr[1] = BUF->srcipaddr[1];
+ BUF->srcipaddr[1] = tmp16;
+
+ /* Set our IP address as the source address. */
+ BUF->srcipaddr[0] = uip_hostaddr[0];
+ BUF->srcipaddr[1] = uip_hostaddr[1];
+
+ /* The size of the ICMP time exceeded packet is 36 + the size of the
+ IP header (20) = 56. */
+ uip_len = 56;
+ ICMPBUF->len[0] = 0;
+ ICMPBUF->len[1] = uip_len;
+
+ /* Fill in the other fields in the IP header. */
+ ICMPBUF->vhl = 0x45;
+ ICMPBUF->tos = 0;
+ ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
+ ICMPBUF->ttl = UIP_TTL;
+ ICMPBUF->proto = UIP_PROTO_ICMP;
+
+ /* Calculate IP checksum. */
+ ICMPBUF->ipchksum = 0;
+ ICMPBUF->ipchksum = ~(uip_ipchksum());
+
+
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Register a packet in the forwarding cache so that it won't be
+ * forwarded again.
+ */
+/*------------------------------------------------------------------------------*/
+static void
+fwcache_register(void)
+{
+ struct fwcache_entry *fw;
+ int i, oldest;
+
+ oldest = FW_TIME;
+ fw = NULL;
+
+ /* Find the oldest entry in the cache. */
+ for(i = 0; i < FWCACHE_SIZE; ++i) {
+ if(fwcache[i].timer == 0) {
+ fw = &fwcache[i];
+ break;
+ } else if(fwcache[i].timer <= oldest) {
+ fw = &fwcache[i];
+ oldest = fwcache[i].timer;
+ }
+ }
+
+ fw->timer = FW_TIME;
+ fw->ipid = BUF->ipid;
+ fw->srcipaddr[0] = BUF->srcipaddr[0];
+ fw->srcipaddr[1] = BUF->srcipaddr[1];
+ fw->destipaddr[0] = BUF->destipaddr[0];
+ fw->destipaddr[1] = BUF->destipaddr[1];
+ fw->proto = BUF->proto;
+#if notdef
+ fw->payload[0] = BUF->srcport;
+ fw->payload[1] = BUF->destport;
+#endif
+#if UIP_REASSEMBLY > 0
+ fw->len = BUF->len;
+ fw->offset = BUF->ipoffset;
+#endif
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * \internal
+ * Find a network interface for the IP packet in uip_buf.
+ */
+/*------------------------------------------------------------------------------*/
+static struct uip_fw_netif *
+find_netif(void)
+{
+ struct uip_fw_netif *netif;
+
+ /* Walk through every network interface to check for a match. */
+ for(netif = netifs; netif != NULL; netif = netif->next) {
+ if(ipaddr_maskcmp(BUF->destipaddr, netif->ipaddr,
+ netif->netmask)) {
+ /* If there was a match, we break the loop. */
+ return netif;
+ }
+ }
+
+ /* If no matching netif was found, we use default netif. */
+ return defaultnetif;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Output an IP packet on the correct network interface.
+ *
+ * The IP packet should be present in the uip_buf buffer and its
+ * length in the global uip_len variable.
+ *
+ * \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
+ * transmission was attempted and that no packet was sent.
+ *
+ * \retval UIP_FW_NOROUTE No suitable network interface could be found
+ * for the outbound packet, and the packet was not sent.
+ *
+ * \return The return value from the actual network interface output
+ * function is passed unmodified as a return value.
+ */
+/*------------------------------------------------------------------------------*/
+u8_t
+uip_fw_output(void)
+{
+ struct uip_fw_netif *netif;
+
+ if(uip_len == 0) {
+ return UIP_FW_ZEROLEN;
+ }
+
+ fwcache_register();
+
+#if UIP_BROADCAST
+ /* Link local broadcasts go out on all interfaces. */
+ if(/*BUF->proto == UIP_PROTO_UDP &&*/
+ BUF->destipaddr[0] == 0xffff &&
+ BUF->destipaddr[1] == 0xffff) {
+ if(defaultnetif != NULL) {
+ defaultnetif->output();
+ }
+ for(netif = netifs; netif != NULL; netif = netif->next) {
+ netif->output();
+ }
+ return UIP_FW_OK;
+ }
+#endif /* UIP_BROADCAST */
+
+ netif = find_netif();
+ /* printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
+ netif->output,
+ uip_len);*/
+
+ if(netif == NULL) {
+ return UIP_FW_NOROUTE;
+ }
+ /* If we now have found a suitable network interface, we call its
+ output function to send out the packet. */
+ return netif->output();
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Forward an IP packet in the uip_buf buffer.
+ *
+ *
+ *
+ * \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
+ * the packet should be processed locally.
+ */
+/*------------------------------------------------------------------------------*/
+u8_t
+uip_fw_forward(void)
+{
+ struct fwcache_entry *fw;
+
+ /* First check if the packet is destined for ourselves and return 0
+ to indicate that the packet should be processed locally. */
+ if(BUF->destipaddr[0] == uip_hostaddr[0] &&
+ BUF->destipaddr[1] == uip_hostaddr[1]) {
+ return UIP_FW_LOCAL;
+ }
+
+ /* If we use ping IP address configuration, and our IP address is
+ not yet configured, we should intercept all ICMP echo packets. */
+#if UIP_PINGADDRCONF
+ if((uip_hostaddr[0] | uip_hostaddr[1]) == 0 &&
+ BUF->proto == UIP_PROTO_ICMP &&
+ ICMPBUF->type == ICMP_ECHO) {
+ return UIP_FW_LOCAL;
+ }
+#endif /* UIP_PINGADDRCONF */
+
+ /* Check if the packet is in the forwarding cache already, and if so
+ we drop it. */
+
+ for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
+ if(fw->timer != 0 &&
+#if UIP_REASSEMBLY > 0
+ fw->len == BUF->len &&
+ fw->offset == BUF->ipoffset &&
+#endif
+ fw->ipid == BUF->ipid &&
+ fw->srcipaddr[0] == BUF->srcipaddr[0] &&
+ fw->srcipaddr[1] == BUF->srcipaddr[1] &&
+ fw->destipaddr[0] == BUF->destipaddr[0] &&
+ fw->destipaddr[1] == BUF->destipaddr[1] &&
+#if notdef
+ fw->payload[0] == BUF->srcport &&
+ fw->payload[1] == BUF->destport &&
+#endif
+ fw->proto == BUF->proto) {
+ /* Drop packet. */
+ return UIP_FW_FORWARDED;
+ }
+ }
+
+ /* If the TTL reaches zero we produce an ICMP time exceeded message
+ in the uip_buf buffer and forward that packet back to the sender
+ of the packet. */
+ if(BUF->ttl <= 1) {
+ /* No time exceeded for broadcasts and multicasts! */
+ if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
+ return UIP_FW_LOCAL;
+ }
+ time_exceeded();
+ }
+
+ /* Decrement the TTL (time-to-live) value in the IP header */
+ BUF->ttl = BUF->ttl - 1;
+
+ /* Update the IP checksum. */
+ if(BUF->ipchksum >= HTONS(0xffff - 0x0100)) {
+ BUF->ipchksum = BUF->ipchksum + HTONS(0x0100) + 1;
+ } else {
+ BUF->ipchksum = BUF->ipchksum + HTONS(0x0100);
+ }
+
+ if(uip_len > 0) {
+ uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
+ uip_fw_output();
+ }
+
+#if UIP_BROADCAST
+ if(BUF->destipaddr[0] == 0xffff && BUF->destipaddr[1] == 0xffff) {
+ return UIP_FW_LOCAL;
+ }
+#endif /* UIP_BROADCAST */
+
+ /* Return non-zero to indicate that the packet was forwarded and that no
+ other processing should be made. */
+ return UIP_FW_FORWARDED;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Register a network interface with the forwarding module.
+ *
+ * \param netif A pointer to the network interface that is to be
+ * registered.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_register(struct uip_fw_netif *netif)
+{
+ netif->next = netifs;
+ netifs = netif;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Register a default network interface.
+ *
+ * All packets that don't go out on any of the other interfaces will
+ * be routed to the default interface.
+ *
+ * \param netif A pointer to the network interface that is to be
+ * registered.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_default(struct uip_fw_netif *netif)
+{
+ defaultnetif = netif;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Perform periodic processing.
+ */
+/*------------------------------------------------------------------------------*/
+void
+uip_fw_periodic(void)
+{
+ struct fwcache_entry *fw;
+ for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
+ if(fw->timer > 0) {
+ --fw->timer;
+ }
+ }
+}
+/*------------------------------------------------------------------------------*/
View
176 src/libs/Network/uip/uip/uip-fw.h
@@ -0,0 +1,176 @@
+/**
+ * \addtogroup uipfw
+ * @{
+ */
+
+/**
+ * \file
+ * uIP packet forwarding header file.
+ * \author Adam Dunkels <adam@sics.se>
+ */
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-fw.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+#ifndef __UIP_FW_H__
+#define __UIP_FW_H__
+
+#include "uip.h"
+
+/**
+ * Representation of a uIP network interface.
+ */
+struct uip_fw_netif {
+ struct uip_fw_netif *next; /**< Pointer to the next interface when
+ linked in a list. */
+ u16_t ipaddr[2]; /**< The IP address of this interface. */
+ u16_t netmask[2]; /**< The netmask of the interface. */
+ u8_t (* output)(void);
+ /**< A pointer to the function that
+ sends a packet. */
+};
+
+/**
+ * Intantiating macro for a uIP network interface.
+ *
+ * Example:
+ \code
+ struct uip_fw_netif slipnetif =
+ {UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
+ \endcode
+ * \param ip1,ip2,ip3,ip4 The IP address of the network interface.
+ *
+ * \param nm1,nm2,nm3,nm4 The netmask of the network interface.
+ *
+ * \param outputfunc A pointer to the output function of the network interface.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
+ NULL, \
+ {HTONS((ip1 << 8) | ip2), HTONS((ip3 << 8) | ip4)}, \
+ {HTONS((nm1 << 8) | nm2), HTONS((nm3 << 8) | nm4)}, \
+ outputfunc
+
+/**
+ * Set the IP address of a network interface.
+ *
+ * \param netif A pointer to the uip_fw_netif structure for the network interface.
+ *
+ * \param addr A pointer to an IP address.
+ *
+ * \hideinitializer
+ */
+#define uip_fw_setipaddr(netif, addr) \
+ do { (netif)->ipaddr[0] = ((u16_t *)(addr))[0]; \
+ (netif)->ipaddr[1] = ((u16_t *)(addr))[1]; } while(0)
+/**
+ * Set the netmask of a network interface.
+ *
+ * \param netif A pointer to the uip_fw_netif structure for the network interface.
+ *
+ * \param addr A pointer to an IP address representing the netmask.
+ *
+ * \hideinitializer
+ */
+#define uip_fw_setnetmask(netif, addr) \
+ do { (netif)->netmask[0] = ((u16_t *)(addr))[0]; \
+ (netif)->netmask[1] = ((u16_t *)(addr))[1]; } while(0)
+
+void uip_fw_init(void);
+u8_t uip_fw_forward(void);
+u8_t uip_fw_output(void);
+void uip_fw_register(struct uip_fw_netif *netif);
+void uip_fw_default(struct uip_fw_netif *netif);
+void uip_fw_periodic(void);
+
+
+/**
+ * A non-error message that indicates that a packet should be
+ * processed locally.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_LOCAL 0
+
+/**
+ * A non-error message that indicates that something went OK.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_OK 0
+
+/**
+ * A non-error message that indicates that a packet was forwarded.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_FORWARDED 1
+
+/**
+ * A non-error message that indicates that a zero-length packet
+ * transmission was attempted, and that no packet was sent.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_ZEROLEN 2
+
+/**
+ * An error message that indicates that a packet that was too large
+ * for the outbound network interface was detected.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_TOOLARGE 3
+
+/**
+ * An error message that indicates that no suitable interface could be
+ * found for an outbound packet.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_NOROUTE 4
+
+/**
+ * An error message that indicates that a packet that should be
+ * forwarded or output was dropped.
+ *
+ * \hideinitializer
+ */
+#define UIP_FW_DROPPED 5
+
+
+#endif /* __UIP_FW_H__ */
+
+/** @} */
View
164 src/libs/Network/uip/uip/uip-neighbor.c
@@ -0,0 +1,164 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uip-neighbor.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \file
+ * Database of link-local neighbors, used by IPv6 code and
+ * to be used by a future ARP code rewrite.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+#include "uip-neighbor.h"
+
+#include "stdio.h"
+#include <string.h>
+
+#define MAX_TIME 128
+
+#ifdef UIP_NEIGHBOR_CONF_ENTRIES
+#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES
+#else /* UIP_NEIGHBOR_CONF_ENTRIES */
+#define ENTRIES 8
+#endif /* UIP_NEIGHBOR_CONF_ENTRIES */
+
+struct neighbor_entry {
+ uip_ipaddr_t ipaddr;
+ struct uip_neighbor_addr addr;
+ u8_t time;
+};
+static struct neighbor_entry entries[ENTRIES];
+
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_init(void)
+{
+ int i;
+
+ for(i = 0; i < ENTRIES; ++i) {
+ entries[i].time = MAX_TIME;
+ }
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_periodic(void)
+{
+ int i;
+
+ for(i = 0; i < ENTRIES; ++i) {
+ if(entries[i].time < MAX_TIME) {
+ entries[i].time++;
+ }
+ }
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr)
+{
+ int i, oldest;
+ u8_t oldest_time;
+
+ printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
+ addr->addr.addr[4], addr->addr.addr[5]);
+
+ /* Find the first unused entry or the oldest used entry. */
+ oldest_time = 0;
+ oldest = 0;
+ for(i = 0; i < ENTRIES; ++i) {
+ if(entries[i].time == MAX_TIME) {
+ oldest = i;
+ break;
+ }
+ if(uip_ipaddr_cmp(entries[i].ipaddr, addr)) {
+ oldest = i;
+ break;
+ }
+ if(entries[i].time > oldest_time) {
+ oldest = i;
+ oldest_time = entries[i].time;
+ }
+ }
+
+ /* Use the oldest or first free entry (either pointed to by the
+ "oldest" variable). */
+ entries[oldest].time = 0;
+ uip_ipaddr_copy(entries[oldest].ipaddr, ipaddr);
+ memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
+}
+/*---------------------------------------------------------------------------*/
+static struct neighbor_entry *
+find_entry(uip_ipaddr_t ipaddr)
+{
+ int i;
+
+ for(i = 0; i < ENTRIES; ++i) {
+ if(uip_ipaddr_cmp(entries[i].ipaddr, ipaddr)) {
+ return &entries[i];
+ }
+ }
+ return NULL;
+}
+/*---------------------------------------------------------------------------*/
+void
+uip_neighbor_update(uip_ipaddr_t ipaddr)
+{
+ struct neighbor_entry *e;
+
+ e = find_entry(ipaddr);
+ if(e != NULL) {
+ e->time = 0;
+ }
+}
+/*---------------------------------------------------------------------------*/
+struct uip_neighbor_addr *
+uip_neighbor_lookup(uip_ipaddr_t ipaddr)
+{
+ struct neighbor_entry *e;
+
+ e = find_entry(ipaddr);
+ if(e != NULL) {
+ /* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3],
+ e->addr.addr.addr[4], e->addr.addr.addr[5]);*/
+
+ return &e->addr;
+ }
+ return NULL;
+}
+/*---------------------------------------------------------------------------*/
View
61 src/libs/Network/uip/uip/uip-neighbor.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uip-neighbor.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+/**
+ * \file
+ * Header file for database of link-local neighbors, used by
+ * IPv6 code and to be used by future ARP code.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ */
+
+#ifndef __UIP_NEIGHBOR_H__
+#define __UIP_NEIGHBOR_H__
+
+#include "uip.h"
+
+struct uip_neighbor_addr {
+#if UIP_NEIGHBOR_CONF_ADDRTYPE
+ UIP_NEIGHBOR_CONF_ADDRTYPE addr;
+#else
+ struct uip_eth_addr addr;
+#endif
+};
+
+void uip_neighbor_init(void);
+void uip_neighbor_add(uip_ipaddr_t ipaddr, struct uip_neighbor_addr *addr);
+void uip_neighbor_update(uip_ipaddr_t ipaddr);
+struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t ipaddr);
+void uip_neighbor_periodic(void);
+
+#endif /* __UIP-NEIGHBOR_H__ */
View
152 src/libs/Network/uip/uip/uip-split.c
@@ -0,0 +1,152 @@
+//#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-split.c,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+
+#include "stdio.h"
+#include <string.h>
+
+#include "uip-split.h"
+#include "uip.h"
+//#include "uip-fw.h"
+//#include "uip_arch.h"
+
+void uip_add32(u8_t *op32, u16_t op16);
+void tcpip_output();
+
+#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
+
+#ifdef UIP_SPLIT_CONF_SIZE
+#define UIP_SPLIT_SIZE UIP_SPLIT_CONF_SIZE
+#else /* UIP_SPLIT_CONF_SIZE */
+#define UIP_SPLIT_SIZE UIP_TCP_MSS
+#endif /* UIP_SPLIT_CONF_SIZE */
+
+/*-----------------------------------------------------------------------------*/
+void uip_split_output(void)
+{
+ u16_t tcplen, len1, len2;
+
+
+ /* We only try to split maximum sized TCP segments. */
+ if (BUF->proto == UIP_PROTO_TCP &&
+ uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {
+
+ tcplen = uip_len - UIP_TCPIP_HLEN - UIP_LLH_LEN;
+ /* Split the segment in two. If the original packet length was
+ odd, we make the second packet one byte larger. */
+ len1 = len2 = tcplen / 2;
+ if (len1 + len2 < tcplen) {
+ ++len2;
+ }
+
+ /* Create the first packet. This is done by altering the length
+ field of the IP header and updating the checksums. */
+ uip_len = len1 + UIP_TCPIP_HLEN;
+#if UIP_CONF_IPV6
+ /* For IPv6, the IP length field does not include the IPv6 IP header
+ length. */
+ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+ BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+ BUF->len[0] = uip_len >> 8;
+ BUF->len[1] = uip_len & 0xff;
+#endif /* UIP_CONF_IPV6 */
+
+ /* Recalculate the TCP checksum. */
+ BUF->tcpchksum = 0;
+ BUF->tcpchksum = ~(uip_tcpchksum());
+
+#if !UIP_CONF_IPV6
+ /* Recalculate the IP checksum. */
+ BUF->ipchksum = 0;
+ BUF->ipchksum = ~(uip_ipchksum());
+#endif /* UIP_CONF_IPV6 */
+
+ uip_len += UIP_LLH_LEN;
+
+ /* Transmit the first packet. */
+ /* uip_fw_output();*/
+ tcpip_output();
+
+ /* Now, create the second packet. To do this, it is not enough to
+ just alter the length field, but we must also update the TCP
+ sequence number and point the uip_appdata to a new place in
+ memory. This place is detemined by the length of the first
+ packet (len1). */
+ uip_len = len2 + UIP_TCPIP_HLEN;
+#if UIP_CONF_IPV6
+ /* For IPv6, the IP length field does not include the IPv6 IP header
+ length. */
+ BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
+ BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
+#else /* UIP_CONF_IPV6 */
+ BUF->len[0] = uip_len >> 8;
+ BUF->len[1] = uip_len & 0xff;
+#endif /* UIP_CONF_IPV6 */
+
+ /* uip_appdata += len1;*/
+ memcpy(uip_appdata, (u8_t *)uip_appdata + len1, len2);
+
+ uip_add32(BUF->seqno, len1);
+ BUF->seqno[0] = uip_acc32[0];
+ BUF->seqno[1] = uip_acc32[1];
+ BUF->seqno[2] = uip_acc32[2];
+ BUF->seqno[3] = uip_acc32[3];
+
+ /* Recalculate the TCP checksum. */
+ BUF->tcpchksum = 0;
+ BUF->tcpchksum = ~(uip_tcpchksum());
+
+#if !UIP_CONF_IPV6
+ /* Recalculate the IP checksum. */
+ BUF->ipchksum = 0;
+ BUF->ipchksum = ~(uip_ipchksum());
+#endif /* UIP_CONF_IPV6 */
+
+ uip_len += UIP_LLH_LEN;
+ /* Transmit the second packet. */
+ /* uip_fw_output();*/
+ tcpip_output();
+ } else {
+ /* uip_fw_output();*/
+ tcpip_output();
+ }
+
+}
+/*-----------------------------------------------------------------------------*/
View
96 src/libs/Network/uip/uip/uip-split.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2004, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: uip-split.h,v 1.2 2006/06/12 08:00:30 adam Exp $
+ */
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \defgroup uipsplit uIP TCP throughput booster hack
+ * @{
+ *
+ * The basic uIP TCP implementation only allows each TCP connection to
+ * have a single TCP segment in flight at any given time. Because of
+ * the delayed ACK algorithm employed by most TCP receivers, uIP's
+ * limit on the amount of in-flight TCP segments seriously reduces the
+ * maximum achievable throughput for sending data from uIP.
+ *
+ * The uip-split module is a hack which tries to remedy this
+ * situation. By splitting maximum sized outgoing TCP segments into
+ * two, the delayed ACK algorithm is not invoked at TCP
+ * receivers. This improves the throughput when sending data from uIP
+ * by orders of magnitude.
+ *
+ * The uip-split module uses the uip-fw module (uIP IP packet
+ * forwarding) for sending packets. Therefore, the uip-fw module must
+ * be set up with the appropriate network interfaces for this module
+ * to work.
+ */
+
+
+/**
+ * \file
+ * Module for splitting outbound TCP segments in two to avoid the
+ * delayed ACK throughput degradation.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+#ifndef __UIP_SPLIT_H__
+#define __UIP_SPLIT_H__
+
+/**
+ * Handle outgoing packets.
+ *
+ * This function inspects an outgoing packet in the uip_buf buffer and
+ * sends it out using the uip_fw_output() function. If the packet is a
+ * full-sized TCP segment it will be split into two segments and
+ * transmitted separately. This function should be called instead of
+ * the actual device driver output function, or the uip_fw_output()
+ * function.
+ *
+ * The headers of the outgoing packet is assumed to be in the uip_buf
+ * buffer and the payload is assumed to be wherever uip_appdata
+ * points. The length of the outgoing packet is assumed to be in the
+ * uip_len variable.
+ *
+ */
+void uip_split_output(void);
+
+#endif /* __UIP_SPLIT_H__ */
+
+/** @} */
+/** @} */
View
1,923 src/libs/Network/uip/uip/uip.c
1,923 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
1,638 src/libs/Network/uip/uip/uip.h
1,638 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
138 src/libs/Network/uip/uip/uip_arch.h
@@ -0,0 +1,138 @@
+/**
+ * \addtogroup uip
+ * {@
+ */
+
+/**
+ * \defgroup uiparch Architecture specific uIP functions
+ * @{
+ *
+ * The functions in the architecture specific module implement the IP
+ * check sum and 32-bit additions.
+ *
+ * The IP checksum calculation is the most computationally expensive
+ * operation in the TCP/IP stack and it therefore pays off to
+ * implement this in efficient assembler. The purpose of the uip-arch
+ * module is to let the checksum functions to be implemented in
+ * architecture specific assembler.
+ *
+ */
+
+/**
+ * \file
+ * Declarations of architecture specific functions.
+ * \author Adam Dunkels <adam@dunkels.com>
+ */
+
+/*
+ * Copyright (c) 2001, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip_arch.h,v 1.2 2006/06/07 09:15:19 adam Exp $
+ *
+ */
+
+#ifndef __UIP_ARCH_H__
+#define __UIP_ARCH_H__
+
+#include "uip.h"
+
+/**
+ * Carry out a 32-bit addition.
+ *
+ * Because not all architectures for which uIP is intended has native
+ * 32-bit arithmetic, uIP uses an external C function for doing the
+ * required 32-bit additions in the TCP protocol processing. This
+ * function should add the two arguments and place the result in the
+ * global variable uip_acc32.
+ *
+ * \note The 32-bit integer pointed to by the op32 parameter and the
+ * result in the uip_acc32 variable are in network byte order (big
+ * endian).
+ *
+ * \param op32 A pointer to a 4-byte array representing a 32-bit
+ * integer in network byte order (big endian).
+ *
+ * \param op16 A 16-bit integer in host byte order.
+ */
+void uip_add32(u8_t *op32, u16_t op16);
+
+/**
+ * Calculate the Internet checksum over a buffer.
+ *
+ * The Internet checksum is the one's complement of the one's
+ * complement sum of all 16-bit words in the buffer.
+ *
+ * See RFC1071.
+ *
+ * \note This function is not called in the current version of uIP,
+ * but future versions might make use of it.
+ *
+ * \param buf A pointer to the buffer over which the checksum is to be
+ * computed.
+ *
+ * \param len The length of the buffer over which the checksum is to
+ * be computed.
+ *
+ * \return The Internet checksum of the buffer.
+ */
+u16_t uip_chksum(u16_t *buf, u16_t len);
+
+/**
+ * Calculate the IP header checksum of the packet header in uip_buf.
+ *
+ * The IP header checksum is the Internet checksum of the 20 bytes of
+ * the IP header.
+ *
+ * \return The IP header checksum of the IP header in the uip_buf
+ * buffer.
+ */
+u16_t uip_ipchksum(void);
+
+/**
+ * Calculate the TCP checksum of the packet in uip_buf and uip_appdata.
+ *
+ * The TCP checksum is the Internet checksum of data contents of the
+ * TCP segment, and a pseudo-header as defined in RFC793.
+ *
+ * \note The uip_appdata pointer that points to the packet data may
+ * point anywhere in memory, so it is not possible to simply calculate
+ * the Internet checksum of the contents of the uip_buf buffer.
+ *
+ * \return The TCP checksum of the TCP segment in uip_buf and pointed
+ * to by uip_appdata.
+ */
+u16_t uip_tcpchksum(void);
+
+u16_t uip_udpchksum(void);
+
+/** @} */
+/** @} */
+
+#endif /* __UIP_ARCH_H__ */
View
428 src/libs/Network/uip/uip/uip_arp.c
@@ -0,0 +1,428 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \defgroup uiparp uIP Address Resolution Protocol
+ * @{
+ *
+ * The Address Resolution Protocol ARP is used for mapping between IP
+ * addresses and link level addresses such as the Ethernet MAC
+ * addresses. ARP uses broadcast queries to ask for the link level
+ * address of a known IP address and the host which is configured with
+ * the IP address for which the query was meant, will respond with its
+ * link level address.
+ *
+ * \note This ARP implementation only supports Ethernet.
+ */
+
+/**
+ * \file
+ * Implementation of the ARP Address Resolution Protocol.
+ * \author Adam Dunkels <adam@dunkels.com>
+ *
+ */
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
+ *
+ */
+
+
+#include "uip_arp.h"
+
+#include <string.h>
+
+struct arp_hdr {
+ struct uip_eth_hdr ethhdr;
+ u16_t hwtype;
+ u16_t protocol;
+ u8_t hwlen;
+ u8_t protolen;
+ u16_t opcode;
+ struct uip_eth_addr shwaddr;
+ u16_t sipaddr[2];
+ struct uip_eth_addr dhwaddr;
+ u16_t dipaddr[2];
+};
+
+struct ethip_hdr {
+ struct uip_eth_hdr ethhdr;
+ /* IP header. */
+ u8_t vhl,
+ tos,
+ len[2],
+ ipid[2],
+ ipoffset[2],
+ ttl,
+ proto;
+ u16_t ipchksum;
+ u16_t srcipaddr[2],
+ destipaddr[2];
+};
+
+#define ARP_REQUEST 1
+#define ARP_REPLY 2
+
+#define ARP_HWTYPE_ETH 1
+
+struct arp_entry {
+ u16_t ipaddr[2];
+ struct uip_eth_addr ethaddr;
+ u8_t time;
+};
+
+static const struct uip_eth_addr broadcast_ethaddr =
+ {{0xff,0xff,0xff,0xff,0xff,0xff}};
+static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
+
+static struct arp_entry arp_table[UIP_ARPTAB_SIZE] __attribute__ ((section ("AHBSRAM1")));
+static u16_t ipaddr[2];
+static u8_t i, c;
+
+static u8_t arptime;
+static u8_t tmpage;
+
+#define BUF ((struct arp_hdr *)&uip_buf[0])
+#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
+/*-----------------------------------------------------------------------------------*/
+/**
+ * Initialize the ARP module.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_init(void)
+{
+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+ memset(arp_table[i].ipaddr, 0, 4);
+ }
+}
+/*-----------------------------------------------------------------------------------*/
+/**
+ * Periodic ARP processing function.
+ *
+ * This function performs periodic timer processing in the ARP module
+ * and should be called at regular intervals. The recommended interval
+ * is 10 seconds between the calls.
+ *
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_timer(void)
+{
+ struct arp_entry *tabptr;
+
+ ++arptime;
+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+ tabptr = &arp_table[i];
+ if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
+ arptime - tabptr->time >= UIP_ARP_MAXAGE) {
+ memset(tabptr->ipaddr, 0, 4);
+ }
+ }
+
+}
+/*-----------------------------------------------------------------------------------*/
+static void
+uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
+{
+ register struct arp_entry *tabptr;
+ /* Walk through the ARP mapping table and try to find an entry to
+ update. If none is found, the IP -> MAC address mapping is
+ inserted in the ARP table. */
+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+
+ tabptr = &arp_table[i];
+ /* Only check those entries that are actually in use. */
+ if(tabptr->ipaddr[0] != 0 &&
+ tabptr->ipaddr[1] != 0) {
+
+ /* Check if the source IP address of the incoming packet matches
+ the IP address in this ARP table entry. */
+ if(ipaddr[0] == tabptr->ipaddr[0] &&
+ ipaddr[1] == tabptr->ipaddr[1]) {
+
+ /* An old entry found, update this and return. */
+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+ tabptr->time = arptime;
+
+ return;
+ }
+ }
+ }
+
+ /* If we get here, no existing ARP table entry was found, so we
+ create one. */
+
+ /* First, we try to find an unused entry in the ARP table. */
+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+ tabptr = &arp_table[i];
+ if(tabptr->ipaddr[0] == 0 &&
+ tabptr->ipaddr[1] == 0) {
+ break;
+ }
+ }
+
+ /* If no unused entry is found, we try to find the oldest entry and
+ throw it away. */
+ if(i == UIP_ARPTAB_SIZE) {
+ tmpage = 0;
+ c = 0;
+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+ tabptr = &arp_table[i];
+ if(arptime - tabptr->time > tmpage) {
+ tmpage = arptime - tabptr->time;
+ c = i;
+ }
+ }
+ i = c;
+ tabptr = &arp_table[i];
+ }
+
+ /* Now, i is the ARP table entry which we will fill with the new
+ information. */
+ memcpy(tabptr->ipaddr, ipaddr, 4);
+ memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+ tabptr->time = arptime;
+}
+/*-----------------------------------------------------------------------------------*/
+/**
+ * ARP processing for incoming IP packets
+ *
+ * This function should be called by the device driver when an IP
+ * packet has been received. The function will check if the address is
+ * in the ARP cache, and if so the ARP cache entry will be
+ * refreshed. If no ARP cache entry was found, a new one is created.
+ *
+ * This function expects an IP packet with a prepended Ethernet header
+ * in the uip_buf[] buffer, and the length of the packet in the global
+ * variable uip_len.
+ */
+/*-----------------------------------------------------------------------------------*/
+#if 0
+void
+uip_arp_ipin(void)
+{
+ uip_len -= sizeof(struct uip_eth_hdr);
+
+ /* Only insert/update an entry if the source IP address of the
+ incoming IP packet comes from a host on the local network. */
+ if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
+ (uip_hostaddr[0] & uip_netmask[0])) {
+ return;
+ }
+ if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
+ (uip_hostaddr[1] & uip_netmask[1])) {
+ return;
+ }
+ uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
+
+ return;
+}
+#endif /* 0 */
+/*-----------------------------------------------------------------------------------*/
+/**
+ * ARP processing for incoming ARP packets.
+ *
+ * This function should be called by the device driver when an ARP
+ * packet has been received. The function will act differently
+ * depending on the ARP packet type: if it is a reply for a request
+ * that we previously sent out, the ARP cache will be filled in with
+ * the values from the ARP reply. If the incoming ARP packet is an ARP
+ * request for our IP address, an ARP reply packet is created and put
+ * into the uip_buf[] buffer.
+ *
+ * When the function returns, the value of the global variable uip_len
+ * indicates whether the device driver should send out a packet or
+ * not. If uip_len is zero, no packet should be sent. If uip_len is
+ * non-zero, it contains the length of the outbound packet that is
+ * present in the uip_buf[] buffer.
+ *
+ * This function expects an ARP packet with a prepended Ethernet
+ * header in the uip_buf[] buffer, and the length of the packet in the
+ * global variable uip_len.
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_arpin(void)
+{
+
+ if(uip_len < sizeof(struct arp_hdr)) {
+ uip_len = 0;
+ return;
+ }
+ uip_len = 0;
+
+ switch(BUF->opcode) {
+ case HTONS(ARP_REQUEST):
+ /* ARP request. If it asked for our address, we send out a
+ reply. */
+ if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+ /* First, we register the one who made the request in our ARP
+ table, since it is likely that we will do more communication
+ with this host in the future. */
+ uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+
+ /* The reply opcode is 2. */
+ BUF->opcode = HTONS(2);
+
+ memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
+ memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+ memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+ memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
+
+ BUF->dipaddr[0] = BUF->sipaddr[0];
+ BUF->dipaddr[1] = BUF->sipaddr[1];
+ BUF->sipaddr[0] = uip_hostaddr[0];
+ BUF->sipaddr[1] = uip_hostaddr[1];
+
+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+ uip_len = sizeof(struct arp_hdr);
+ }
+ break;
+ case HTONS(ARP_REPLY):
+ /* ARP reply. We insert or update the ARP table if it was meant
+ for us. */
+ if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+ uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+ }
+ break;
+ }
+
+ return;
+}
+/*-----------------------------------------------------------------------------------*/
+/**
+ * Prepend Ethernet header to an outbound IP packet and see if we need
+ * to send out an ARP request.
+ *
+ * This function should be called before sending out an IP packet. The
+ * function checks the destination IP address of the IP packet to see
+ * what Ethernet MAC address that should be used as a destination MAC
+ * address on the Ethernet.
+ *
+ * If the destination IP address is in the local network (determined
+ * by logical ANDing of netmask and our IP address), the function
+ * checks the ARP cache to see if an entry for the destination IP
+ * address is found. If so, an Ethernet header is prepended and the
+ * function returns. If no ARP cache entry is found for the
+ * destination IP address, the packet in the uip_buf[] is replaced by
+ * an ARP request packet for the IP address. The IP packet is dropped
+ * and it is assumed that they higher level protocols (e.g., TCP)
+ * eventually will retransmit the dropped packet.
+ *
+ * If the destination IP address is not on the local network, the IP
+ * address of the default router is used instead.
+ *
+ * When the function returns, a packet is present in the uip_buf[]
+ * buffer, and the length of the packet is in the global variable
+ * uip_len.
+ */
+/*-----------------------------------------------------------------------------------*/
+void
+uip_arp_out(void)
+{
+ struct arp_entry *tabptr;
+
+ /* Find the destination IP address in the ARP table and construct
+ the Ethernet header. If the destination IP addres isn't on the
+ local network, we use the default router's IP address instead.
+
+ If not ARP table entry is found, we overwrite the original IP
+ packet with an ARP request for the IP address. */
+
+ /* First check if destination is a local broadcast. */
+ if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
+ memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
+ } else {
+ /* Check if the destination address is on the local network. */
+ if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
+ /* Destination address was not on the local network, so we need to
+ use the default router's IP address instead of the destination
+ address when determining the MAC address. */
+ uip_ipaddr_copy(ipaddr, uip_draddr);
+ } else {
+ /* Else, we use the destination IP address. */
+ uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
+ }
+
+ for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+ tabptr = &arp_table[i];
+ if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
+ break;
+ }
+ }
+
+ if(i == UIP_ARPTAB_SIZE) {
+ /* The destination address was not in our ARP table, so we
+ overwrite the IP packet with an ARP request. */
+
+ memset(BUF->ethhdr.dest.addr, 0xff, 6);
+ memset(BUF->dhwaddr.addr, 0x00, 6);
+ memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+ memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+
+ uip_ipaddr_copy(BUF->dipaddr, ipaddr);
+ uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
+ BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
+ BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
+ BUF->protocol = HTONS(UIP_ETHTYPE_IP);
+ BUF->hwlen = 6;
+ BUF->protolen = 4;
+ BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+
+ uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
+
+ uip_len = sizeof(struct arp_hdr);
+ return;
+ }
+
+ /* Build an ethernet header. */
+ memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
+ }
+ memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+
+ IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
+
+ uip_len += sizeof(struct uip_eth_hdr);
+}
+/*-----------------------------------------------------------------------------------*/
+
+/** @} */
+/** @} */
View
150 src/libs/Network/uip/uip/uip_arp.h
@@ -0,0 +1,150 @@
+/**
+ * \addtogroup uip
+ * @{
+ */
+
+/**
+ * \addtogroup uiparp
+ * @{
+ */
+
+/**
+ * \file
+ * Macros and definitions for the ARP module.
+ * \author Adam Dunkels <adam@dunkels.com>
+ */
+
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uip_arp.h,v 1.5 2006/06/11 21:46:39 adam Exp $
+ *
+ */
+
+#ifndef __UIP_ARP_H__
+#define __UIP_ARP_H__
+
+#include "uip.h"
+
+
+extern struct uip_eth_addr uip_ethaddr;
+
+/**
+ * The Ethernet header.
+ */
+struct uip_eth_hdr {
+ struct uip_eth_addr dest;
+ struct uip_eth_addr src;
+ u16_t type;
+};
+
+#define UIP_ETHTYPE_ARP 0x0806
+#define UIP_ETHTYPE_IP 0x0800
+#define UIP_ETHTYPE_IP6 0x86dd
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The uip_arp_init() function must be called before any of the other
+ ARP functions. */
+void uip_arp_init(void);
+
+/* The uip_arp_ipin() function should be called whenever an IP packet
+ arrives from the Ethernet. This function refreshes the ARP table or
+ inserts a new mapping if none exists. The function assumes that an
+ IP packet with an Ethernet header is present in the uip_buf buffer
+ and that the length of the packet is in the uip_len variable. */
+/*void uip_arp_ipin(void);*/
+#define uip_arp_ipin()
+
+/* The uip_arp_arpin() should be called when an ARP packet is received
+ by the Ethernet driver. This function also assumes that the
+ Ethernet frame is present in the uip_buf buffer. When the
+ uip_arp_arpin() function returns, the contents of the uip_buf
+ buffer should be sent out on the Ethernet if the uip_len variable
+ is > 0. */
+void uip_arp_arpin(void);
+
+/* The uip_arp_out() function should be called when an IP packet
+ should be sent out on the Ethernet. This function creates an
+ Ethernet header before the IP header in the uip_buf buffer. The
+ Ethernet header will have the correct Ethernet MAC destination
+ address filled in if an ARP table entry for the destination IP
+ address (or the IP address of the default router) is present. If no
+ such table entry is found, the IP packet is overwritten with an ARP
+ request and we rely on TCP to retransmit the packet that was
+ overwritten. In any case, the uip_len variable holds the length of
+ the Ethernet frame that should be transmitted. */
+void uip_arp_out(void);
+
+/* The uip_arp_timer() function should be called every ten seconds. It
+ is responsible for flushing old entries in the ARP table. */
+void uip_arp_timer(void);
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+/**
+ * \addtogroup uipconffunc
+ * @{
+ */
+
+
+/**
+ * Specifiy the Ethernet MAC address.
+ *
+ * The ARP code needs to know the MAC address of the Ethernet card in
+ * order to be able to respond to ARP queries and to generate working
+ * Ethernet headers.
+ *
+ * \note This macro only specifies the Ethernet MAC address to the ARP
+ * code. It cannot be used to change the MAC address of the Ethernet
+ * card.
+ *
+ * \param eaddr A pointer to a struct uip_eth_addr containing the
+ * Ethernet MAC address of the Ethernet card.
+ *
+ * \hideinitializer
+ */
+#define uip_setethaddr(eaddr) do {uip_ethaddr.addr[0] = eaddr[0]; \
+ uip_ethaddr.addr[1] = eaddr[1];\
+ uip_ethaddr.addr[2] = eaddr[2];\
+ uip_ethaddr.addr[3] = eaddr[3];\
+ uip_ethaddr.addr[4] = eaddr[4];\
+ uip_ethaddr.addr[5] = eaddr[5];} while(0)
+
+/** @} */
+/** @} */
+
+#endif /* __UIP_ARP_H__ */
View
74 src/libs/Network/uip/uip/uiplib.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2004, Adam Dunkels and the Swedish Institute of
+ * Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uiplib.c,v 1.2 2006/06/12 08:00:31 adam Exp $
+ *
+ */
+
+
+#include "uip.h"
+#include "uiplib.h"
+
+
+/*-----------------------------------------------------------------------------------*/
+unsigned char
+uiplib_ipaddrconv(char *addrstr, unsigned char *ipaddr)
+{
+ unsigned char tmp;
+ char c;
+ unsigned char i, j;
+
+ tmp = 0;
+
+ for(i = 0; i < 4; ++i) {
+ j = 0;
+ do {
+ c = *addrstr;
+ ++j;
+ if(j > 4) {
+ return 0;
+ }
+ if(c == '.' || c == 0) {
+ *ipaddr = tmp;
+ ++ipaddr;
+ tmp = 0;
+ } else if(c >= '0' && c <= '9') {
+ tmp = (tmp * 10) + (c - '0');
+ } else {
+ return 0;
+ }
+ ++addrstr;
+ } while(c != '.' && c != 0);
+ }
+ return 1;
+}
+
+/*-----------------------------------------------------------------------------------*/
View
71 src/libs/Network/uip/uip/uiplib.h
@@ -0,0 +1,71 @@
+/**
+ * \file
+ * Various uIP library functions.
+ * \author
+ * Adam Dunkels <adam@sics.se>
+ *
+ */
+
+/*
+ * Copyright (c) 2002, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack
+ *
+ * $Id: uiplib.h,v 1.1 2006/06/07 09:15:19 adam Exp $
+ *
+ */
+#ifndef __UIPLIB_H__
+#define __UIPLIB_H__
+
+/**
+ * \addtogroup uipconvfunc
+ * @{
+ */
+
+/**
+ * Convert a textual representation of an IP address to a numerical representation.
+ *
+ * This function takes a textual representation of an IP address in
+ * the form a.b.c.d and converts it into a 4-byte array that can be
+ * used by other uIP functions.
+ *
+ * \param addrstr A pointer to a string containing the IP address in
+ * textual form.
+ *
+ * \param addr A pointer to a 4-byte array that will be filled in with
+ * the numerical representation of the address.
+ *
+ * \retval 0 If the IP address could not be parsed.
+ * \retval Non-zero If the IP address was parsed.
+ */
+unsigned char uiplib_ipaddrconv(char *addrstr, unsigned char *addr);
+
+/** @} */
+
+#endif /* __UIPLIB_H__ */
View
546 src/libs/Network/uip/uip/uipopt.h
@@ -0,0 +1,546 @@
+/**
+ * \defgroup uipopt Configuration options for uIP
+ * @{
+ *
+ * uIP is configured using the per-project configuration file
+ * uipopt.h. This file contains all compile-time options for uIP and
+ * should be tweaked to match each specific project. The uIP
+ * distribution contains a documented example "uipopt.h" that can be
+ * copied and modified for each project.
+ *
+ * \note Most of the configuration options in the uipopt.h should not
+ * be changed, but rather the per-project uip-conf.h file.
+ */
+
+/**
+ * \file
+ * Configuration options for uIP.
+ * \author Adam Dunkels <adam@dunkels.com>
+ *
+ * This file is used for tweaking various configuration options for
+ * uIP. You should make a copy of this file into one of your project's
+ * directories instead of editing this example "uipopt.h" file that
+ * comes with the uIP distribution.
+ */
+
+/*
+ * Copyright (c) 2001-2003, Adam Dunkels.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This file is part of the uIP TCP/IP stack.
+ *
+ * $Id: uipopt.h,v 1.4 2006/06/12 08:00:31 adam Exp $
+ *
+ */
+
+#ifndef __UIPOPT_H__
+#define __UIPOPT_H__
+
+#ifndef UIP_LITTLE_ENDIAN
+#define UIP_LITTLE_ENDIAN 3412
+#endif /* UIP_LITTLE_ENDIAN */
+#ifndef UIP_BIG_ENDIAN
+#define UIP_BIG_ENDIAN 1234
+#endif /* UIP_BIG_ENDIAN */
+
+#include "uip-conf.h"
+
+/*------------------------------------------------------------------------------*/
+
+/**
+ * \name Static configuration options
+ * @{
+ *
+ * These configuration options can be used for setting the IP address
+ * settings statically, but only if UIP_FIXEDADDR is set to 1. The
+ * configuration options for a specific node includes IP address,
+ * netmask and default router as well as the Ethernet address. The
+ * netmask, default router and Ethernet address are appliciable only
+ * if uIP should be run over Ethernet.
+ *
+ * All of these should be changed to suit your project.
+*/
+
+/**
+ * Determines if uIP should use a fixed IP address or not.
+ *
+ * If uIP should use a fixed IP address, the settings are set in the
+ * uipopt.h file. If not, the macros uip_sethostaddr(),
+ * uip_setdraddr() and uip_setnetmask() should be used instead.
+ *
+ * \hideinitializer
+ */
+#define UIP_FIXEDADDR 0
+
+/**
+ * Ping IP address asignment.
+ *
+ * uIP uses a "ping" packets for setting its own IP address if this
+ * option is set. If so, uIP will start with an empty IP address and
+ * the destination IP address of the first incoming "ping" (ICMP echo)
+ * packet will be used for setting the hosts IP address.
+ *
+ * \note This works only if UIP_FIXEDADDR is 0.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_PINGADDRCONF
+#define UIP_PINGADDRCONF UIP_CONF_PINGADDRCONF
+#else /* UIP_CONF_PINGADDRCONF */
+#define UIP_PINGADDRCONF 0
+#endif /* UIP_CONF_PINGADDRCONF */
+
+
+/**
+ * Specifies if the uIP ARP module should be compiled with a fixed
+ * Ethernet MAC address or not.
+ *
+ * If this configuration option is 0, the macro uip_setethaddr() can
+ * be used to specify the Ethernet address at run-time.
+ *
+ * \hideinitializer
+ */
+#define UIP_FIXEDETHADDR 0
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name IP configuration options
+ * @{
+ *
+ */
+/**
+ * The IP TTL (time to live) of IP packets sent by uIP.
+ *
+ * This should normally not be changed.
+ */
+#define UIP_TTL 64
+
+/**
+ * Turn on support for IP packet reassembly.
+ *
+ * uIP supports reassembly of fragmented IP packets. This features
+ * requires an additonal amount of RAM to hold the reassembly buffer
+ * and the reassembly code size is approximately 700 bytes. The
+ * reassembly buffer is of the same size as the uip_buf buffer
+ * (configured by UIP_BUFSIZE).
+ *
+ * \note IP packet reassembly is not heavily tested.
+ *
+ * \hideinitializer
+ */
+#define UIP_REASSEMBLY 0
+
+/**
+ * The maximum time an IP fragment should wait in the reassembly
+ * buffer before it is dropped.
+ *
+ */
+#define UIP_REASS_MAXAGE 40
+
+/** @} */
+
+/*------------------------------------------------------------------------------*/
+/**
+ * \name UDP configuration options
+ * @{
+ */
+
+/**
+ * Toggles wether UDP support should be compiled in or not.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_UDP
+#define UIP_UDP UIP_CONF_UDP
+#else /* UIP_CONF_UDP */
+#define UIP_UDP 0
+#endif /* UIP_CONF_UDP */
+
+/**
+ * Toggles if UDP checksums should be used or not.
+ *
+ * \note Support for UDP checksums is currently not included in uIP,
+ * so this option has no function.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_UDP_CHECKSUMS
+#define UIP_UDP_CHECKSUMS UIP_CONF_UDP_CHECKSUMS
+#else
+#define UIP_UDP_CHECKSUMS 0
+#endif
+
+/**
+ * The maximum amount of concurrent UDP connections.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_UDP_CONNS
+#define UIP_UDP_CONNS UIP_CONF_UDP_CONNS
+#else /* UIP_CONF_UDP_CONNS */
+#define UIP_UDP_CONNS 10
+#endif /* UIP_CONF_UDP_CONNS */
+
+/**
+ * The name of the function that should be called when UDP datagrams arrive.
+ *
+ * \hideinitializer
+ */
+
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name TCP configuration options
+ * @{
+ */
+
+/**
+ * Determines if support for opening connections from uIP should be
+ * compiled in.
+ *
+ * If the applications that are running on top of uIP for this project
+ * do not need to open outgoing TCP connections, this configration
+ * option can be turned off to reduce the code size of uIP.
+ *
+ * \hideinitializer
+ */
+#define UIP_ACTIVE_OPEN 1
+
+/**
+ * The maximum number of simultaneously open TCP connections.
+ *
+ * Since the TCP connections are statically allocated, turning this
+ * configuration knob down results in less RAM used. Each TCP
+ * connection requires approximatly 30 bytes of memory.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_MAX_CONNECTIONS
+#define UIP_CONNS 10
+#else /* UIP_CONF_MAX_CONNECTIONS */
+#define UIP_CONNS UIP_CONF_MAX_CONNECTIONS
+#endif /* UIP_CONF_MAX_CONNECTIONS */
+
+
+/**
+ * The maximum number of simultaneously listening TCP ports.
+ *
+ * Each listening TCP port requires 2 bytes of memory.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_MAX_LISTENPORTS
+#define UIP_LISTENPORTS 20
+#else /* UIP_CONF_MAX_LISTENPORTS */
+#define UIP_LISTENPORTS UIP_CONF_MAX_LISTENPORTS
+#endif /* UIP_CONF_MAX_LISTENPORTS */
+
+/**
+ * Determines if support for TCP urgent data notification should be
+ * compiled in.
+ *
+ * Urgent data (out-of-band data) is a rarely used TCP feature that
+ * very seldom would be required.
+ *
+ * \hideinitializer
+ */
+#define UIP_URGDATA 0
+
+/**
+ * The initial retransmission timeout counted in timer pulses.
+ *
+ * This should not be changed.
+ */
+#define UIP_RTO 3
+
+/**
+ * The maximum number of times a segment should be retransmitted
+ * before the connection should be aborted.
+ *
+ * This should not be changed.
+ */
+#define UIP_MAXRTX 8
+
+/**
+ * The maximum number of times a SYN segment should be retransmitted
+ * before a connection request should be deemed to have been
+ * unsuccessful.
+ *
+ * This should not need to be changed.
+ */
+#define UIP_MAXSYNRTX 5
+
+/**
+ * The TCP maximum segment size.
+ *
+ * This is should not be to set to more than
+ * UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
+ */
+#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
+
+/**
+ * The size of the advertised receiver's window.
+ *
+ * Should be set low (i.e., to the size of the uip_buf buffer) is the
+ * application is slow to process incoming data, or high (32768 bytes)
+ * if the application processes data quickly.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_RECEIVE_WINDOW
+#define UIP_RECEIVE_WINDOW UIP_TCP_MSS
+#else
+#define UIP_RECEIVE_WINDOW UIP_CONF_RECEIVE_WINDOW
+#endif
+
+/**
+ * How long a connection should stay in the TIME_WAIT state.
+ *
+ * This configiration option has no real implication, and it should be
+ * left untouched.
+ */
+#define UIP_TIME_WAIT_TIMEOUT 120
+
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name ARP configuration options
+ * @{
+ */
+
+/**
+ * The size of the ARP table.
+ *
+ * This option should be set to a larger value if this uIP node will
+ * have many connections from the local network.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_ARPTAB_SIZE
+#define UIP_ARPTAB_SIZE UIP_CONF_ARPTAB_SIZE
+#else
+#define UIP_ARPTAB_SIZE 8
+#endif
+
+/**
+ * The maxium age of ARP table entries measured in 10ths of seconds.
+ *
+ * An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
+ * default).
+ */
+#define UIP_ARP_MAXAGE 120
+
+/** @} */
+
+/*------------------------------------------------------------------------------*/
+
+/**
+ * \name General configuration options
+ * @{
+ */
+
+/**
+ * The size of the uIP packet buffer.
+ *
+ * The uIP packet buffer should not be smaller than 60 bytes, and does
+ * not need to be larger than 1500 bytes. Lower size results in lower
+ * TCP throughput, larger size results in higher TCP throughput.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_BUFFER_SIZE
+#define UIP_BUFSIZE 400
+#else /* UIP_CONF_BUFFER_SIZE */
+#define UIP_BUFSIZE UIP_CONF_BUFFER_SIZE
+#endif /* UIP_CONF_BUFFER_SIZE */
+
+
+/**
+ * Determines if statistics support should be compiled in.
+ *
+ * The statistics is useful for debugging and to show the user.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_STATISTICS
+#define UIP_STATISTICS 0
+#else /* UIP_CONF_STATISTICS */
+#define UIP_STATISTICS UIP_CONF_STATISTICS
+#endif /* UIP_CONF_STATISTICS */
+
+/**
+ * Determines if logging of certain events should be compiled in.
+ *
+ * This is useful mostly for debugging. The function uip_log()
+ * must be implemented to suit the architecture of the project, if
+ * logging is turned on.
+ *
+ * \hideinitializer
+ */
+#ifndef UIP_CONF_LOGGING
+#define UIP_LOGGING 0
+#else /* UIP_CONF_LOGGING */
+#define UIP_LOGGING UIP_CONF_LOGGING
+#endif /* UIP_CONF_LOGGING */
+
+/**
+ * Broadcast support.
+ *
+ * This flag configures IP broadcast support. This is useful only
+ * together with UDP.
+ *
+ * \hideinitializer
+ *
+ */
+#ifndef UIP_CONF_BROADCAST
+#define UIP_BROADCAST 0
+#else /* UIP_CONF_BROADCAST */
+#define UIP_BROADCAST UIP_CONF_BROADCAST
+#endif /* UIP_CONF_BROADCAST */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print out a uIP log message.
+ *
+ * This function must be implemented by the module that uses uIP, and
+ * is called by uIP whenever a log message is generated.
+ */
+void uip_log(char *msg);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+ * The link level header length.
+ *
+ * This is the offset into the uip_buf where the IP header can be
+ * found. For Ethernet, this should be set to 14. For SLIP, this
+ * should be set to 0.
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_LLH_LEN
+#define UIP_LLH_LEN UIP_CONF_LLH_LEN
+#else /* UIP_CONF_LLH_LEN */
+#define UIP_LLH_LEN 14
+#endif /* UIP_CONF_LLH_LEN */
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+/**
+ * \name CPU architecture configuration
+ * @{
+ *
+ * The CPU architecture configuration is where the endianess of the
+ * CPU on which uIP is to be run is specified. Most CPUs today are
+ * little endian, and the most notable exception are the Motorolas
+ * which are big endian. The BYTE_ORDER macro should be changed to
+ * reflect the CPU architecture on which uIP is to be run.
+ */
+
+/**
+ * The byte order of the CPU architecture on which uIP is to be run.
+ *
+ * This option can be either BIG_ENDIAN (Motorola byte order) or
+ * LITTLE_ENDIAN (Intel byte order).
+ *
+ * \hideinitializer
+ */
+#ifdef UIP_CONF_BYTE_ORDER
+#define UIP_BYTE_ORDER UIP_CONF_BYTE_ORDER
+#else /* UIP_CONF_BYTE_ORDER */
+#define UIP_BYTE_ORDER UIP_LITTLE_ENDIAN
+#endif /* UIP_CONF_BYTE_ORDER */
+
+/** @} */
+/*------------------------------------------------------------------------------*/
+
+/**
+ * \name Appication specific configurations
+ * @{
+ *
+ * An uIP application is implemented using a single application
+ * function that is called by uIP whenever a TCP/IP event occurs. The
+ * name of this function must be registered with uIP at compile time
+ * using the UIP_APPCALL definition.
+ *
+ * uIP applications can store the application state within the
+ * uip_conn structure by specifying the type of the application
+ * structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
+ *
+ * The file containing the definitions must be included in the
+ * uipopt.h file.
+ *
+ * The following example illustrates how this can look.
+ \code
+
+void httpd_appcall(void);
+#define UIP_APPCALL httpd_appcall
+
+struct httpd_state {
+ u8_t state;
+ u16_t count;
+ char *dataptr;
+ char *script;
+};
+typedef struct httpd_state uip_tcp_appstate_t
+ \endcode
+ */
+
+/**
+ * \var #define UIP_APPCALL
+ *
+ * The name of the application function that uIP should call in
+ * response to TCP/IP events.
+ *
+ */
+
+/**
+ * \var typedef uip_tcp_appstate_t
+ *
+ * The type of the application state that is to be stored in the
+ * uip_conn structure. This usually is typedef:ed to a struct holding
+ * application state information.
+ */
+
+/**
+ * \var typedef uip_udp_appstate_t
+ *
+ * The type of the application state that is to be stored in the
+ * uip_conn structure. This usually is typedef:ed to a struct holding
+ * application state information.
+ */
+/** @} */
+/** @} */
+
+#endif /* __UIPOPT_H__ */
View
41 src/libs/Network/uip/webserver/http-strings
@@ -0,0 +1,41 @@
+http_http "http://"
+http_200 "200 "
+http_301 "301 "
+http_302 "302 "
+http_get "GET "
+http_post "POST "
+http_10 "HTTP/1.0"
+http_11 "HTTP/1.1"
+http_content_type "content-type: "
+http_content_length "Content-Length: "
+http_cache_control "Cache-Control: "
+http_no_cache "no-cache"
+http_texthtml "text/html"
+http_location "location: "
+http_host "host: "
+http_crnl "\r\n"
+http_index_html "/index.html"
+http_404_html "/404.html"
+http_referer "Referer:"
+http_header_200 "HTTP/1.0 200 OK\r\nServer: uIP/1.0\r\nConnection: close\r\n"
+http_header_304 "HTTP/1.0 304 Not Modified\r\nServer: uIP/1.0\r\nConnection: close\r\nExpires: Thu, 31 Dec 2037 23:55:55 GMT\r\nCache-Control: max-age=315360000\r\nX-Cache: HIT\r\n"
+http_header_404 "HTTP/1.0 404 Not found\r\nServer: uIP/1.0\r\nConnection: close\r\n"
+http_header_503 "HTTP/1.0 503 Failed\r\nServer: uIP/1.0\r\nConnection: close\r\n"
+http_content_type_plain "Content-type: text/plain\r\n\r\n"
+http_content_type_html "Content-type: text/html\r\n\r\n"
+http_content_type_css "Content-type: text/css\r\n\r\n"
+http_content_type_text "Content-type: text/text\r\n\r\n"
+http_content_type_png "Content-type: image/png\r\n\r\n"
+http_content_type_gif "Content-type: image/gif\r\n\r\n"
+http_content_type_jpg "Content-type: image/jpeg\r\n\r\n"
+http_content_type_binary "Content-type: application/octet-stream\r\n\r\n"
+http_html ".html"
+http_shtml ".shtml"
+http_htm ".htm"
+http_css ".css"
+http_png ".png"
+http_gif ".gif"
+http_jpg ".jpg"
+http_text ".txt"
+http_txt ".txt"
+
View
120 src/libs/Network/uip/webserver/http-strings.c
@@ -0,0 +1,120 @@
+const char http_http[8] =
+/* "http://" */
+{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
+const char http_200[5] =
+/* "200 " */
+{0x32, 0x30, 0x30, 0x20, };
+const char http_301[5] =
+/* "301 " */
+{0x33, 0x30, 0x31, 0x20, };
+const char http_302[5] =
+/* "302 " */
+{0x33, 0x30, 0x32, 0x20, };
+const char http_get[5] =
+/* "GET " */
+{0x47, 0x45, 0x54, 0x20, };
+const char http_post[6] =
+/* "POST " */
+{0x50, 0x4f, 0x53, 0x54, 0x20, };
+const char http_10[9] =
+/* "HTTP/1.0" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, };
+const char http_11[9] =
+/* "HTTP/1.1" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, };
+const char http_content_type[15] =
+/* "content-type: " */
+{0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, };
+const char http_content_length[17] =
+/* "Content-Length: " */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, };
+const char http_cache_control[16] =
+/* "Cache-Control: " */
+{0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x20, };
+const char http_no_cache[9] =
+/* "no-cache" */
+{0x6e, 0x6f, 0x2d, 0x63, 0x61, 0x63, 0x68, 0x65, };
+const char http_texthtml[10] =
+/* "text/html" */
+{0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_location[11] =
+/* "location: " */
+{0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, };
+const char http_host[7] =
+/* "host: " */
+{0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, };
+const char http_crnl[3] =
+/* "\r\n" */
+{0xd, 0xa, };
+const char http_index_html[12] =
+/* "/index.html" */
+{0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_404_html[10] =
+/* "/404.html" */
+{0x2f, 0x34, 0x30, 0x34, 0x2e, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_referer[9] =
+/* "Referer:" */
+{0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x72, 0x3a, };
+const char http_header_200[54] =
+/* "HTTP/1.0 200 OK\r\nServer: uIP/1.0\r\nConnection: close\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
+const char http_header_304[152] =
+/* "HTTP/1.0 304 Not Modified\r\nServer: uIP/1.0\r\nConnection: close\r\nExpires: Thu, 31 Dec 2037 23:55:55 GMT\r\nCache-Control: max-age=315360000\r\nX-Cache: HIT\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x33, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, 0x45, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x3a, 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x33, 0x31, 0x20, 0x44, 0x65, 0x63, 0x20, 0x32, 0x30, 0x33, 0x37, 0x20, 0x32, 0x33, 0x3a, 0x35, 0x35, 0x3a, 0x35, 0x35, 0x20, 0x47, 0x4d, 0x54, 0xd, 0xa, 0x43, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x20, 0x6d, 0x61, 0x78, 0x2d, 0x61, 0x67, 0x65, 0x3d, 0x33, 0x31, 0x35, 0x33, 0x36, 0x30, 0x30, 0x30, 0x30, 0xd, 0xa, 0x58, 0x2d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x3a, 0x20, 0x48, 0x49, 0x54, 0xd, 0xa, };
+const char http_header_404[61] =
+/* "HTTP/1.0 404 Not found\r\nServer: uIP/1.0\r\nConnection: close\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x34, 0x30, 0x34, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
+const char http_header_503[58] =
+/* "HTTP/1.0 503 Failed\r\nServer: uIP/1.0\r\nConnection: close\r\n" */
+{0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0x20, 0x35, 0x30, 0x33, 0x20, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0xd, 0xa, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x75, 0x49, 0x50, 0x2f, 0x31, 0x2e, 0x30, 0xd, 0xa, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0xd, 0xa, };
+const char http_content_type_plain[29] =
+/* "Content-type: text/plain\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x70, 0x6c, 0x61, 0x69, 0x6e, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_html[28] =
+/* "Content-type: text/html\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_css [27] =
+/* "Content-type: text/css\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x63, 0x73, 0x73, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_text[28] =
+/* "Content-type: text/text\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x78, 0x74, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_png [28] =
+/* "Content-type: image/png\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x70, 0x6e, 0x67, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_gif [28] =
+/* "Content-type: image/gif\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_jpg [29] =
+/* "Content-type: image/jpeg\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x6a, 0x70, 0x65, 0x67, 0xd, 0xa, 0xd, 0xa, };
+const char http_content_type_binary[43] =
+/* "Content-type: application/octet-stream\r\n\r\n" */
+{0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0xd, 0xa, 0xd, 0xa, };
+const char http_html[6] =
+/* ".html" */
+{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_shtml[7] =
+/* ".shtml" */
+{0x2e, 0x73, 0x68, 0x74, 0x6d, 0x6c, };
+const char http_htm[5] =
+/* ".htm" */
+{0x2e, 0x68, 0x74, 0x6d, };
+const char http_css[5] =
+/* ".css" */
+{0x2e, 0x63, 0x73, 0x73, };
+const char http_png[5] =
+/* ".png" */
+{0x2e, 0x70, 0x6e, 0x67, };
+const char http_gif[5] =
+/* ".gif" */
+{0x2e, 0x67, 0x69, 0x66, };
+const char http_jpg[5] =
+/* ".jpg" */
+{0x2e, 0x6a, 0x70, 0x67, };
+const char http_text[5] =
+/* ".txt" */
+{0x2e, 0x74, 0x78, 0x74, };
+const char http_txt[5] =
+/* ".txt" */
+{0x2e, 0x74, 0x78, 0x74, };
View
40 src/libs/Network/uip/webserver/http-strings.h
@@ -0,0 +1,40 @@
+extern const char http_http[8];
+extern const char http_200[5];
+extern const char http_301[5];
+extern const char http_302[5];
+extern const char http_get[5];
+extern const char http_post[6];
+extern const char http_10[9];
+extern const char http_11[9];
+extern const char http_content_type[15];
+extern const char http_content_length[17];
+extern const char http_cache_control[16];
+extern const char http_no_cache[9];
+extern const char http_texthtml[10];
+extern const char http_location[11];
+extern const char http_host[7];
+extern const char http_crnl[3];
+extern const char http_index_html[12];
+extern const char http_404_html[10];
+extern const char http_referer[9];
+extern const char http_header_200[54];
+extern const char http_header_304[152];
+extern const char http_header_404[61];
+extern const char http_header_503[58];
+extern const char http_content_type_plain[29];
+extern const char http_content_type_html[28];
+extern const char http_content_type_css [27];
+extern const char http_content_type_text[28];
+extern const char http_content_type_png [28];
+extern const char http_content_type_gif [28];
+extern const char http_content_type_jpg [29];
+extern const char http_content_type_binary[43];
+extern const char http_html[6];
+extern const char http_shtml[7];
+extern const char http_htm[5];
+extern const char http_css[5];
+extern const char http_png[5];
+extern const char http_gif[5];
+extern const char http_jpg[5];
+extern const char http_text[5];
+extern const char http_txt[5];
View
137 src/libs/Network/uip/webserver/httpd-fs.c
@@ -0,0 +1,137 @@
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+#pragma GCC diagnostic ignored "-Wstrict-aliasing"
+#pragma GCC diagnostic ignored "-Wcast-align"
+#pragma GCC diagnostic ignored "-Wcast-qual"
+
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: httpd-fs.c,v 1.1 2006/06/07 09:13:08 adam Exp $
+ */
+
+#include "httpd.h"
+#include "httpd-fs.h"
+#include "httpd-fsdata.h"
+
+#ifndef NULL
+#define NULL 0
+#endif /* NULL */
+
+#include "httpd-fsdata2.h"
+
+#if HTTPD_FS_STATISTICS
+static u16_t count[HTTPD_FS_NUMFILES];
+#endif /* HTTPD_FS_STATISTICS */
+
+/*-----------------------------------------------------------------------------------*/
+static u8_t
+httpd_fs_strcmp(const char *str1, const char *str2)
+{
+ u8_t i;
+ i = 0;
+ loop:
+
+ if(str2[i] == 0 ||
+ str1[i] == '\r' ||
+ str1[i] == '\n') {
+ return 0;
+ }
+
+ if(str1[i] != str2[i]) {
+ return 1;
+ }
+
+
+ ++i;
+ goto loop;
+}
+/*-----------------------------------------------------------------------------------*/
+int
+httpd_fs_open(const char *name, struct httpd_fs_file *file)
+{
+#if HTTPD_FS_STATISTICS
+ u16_t i = 0;
+#endif /* HTTPD_FS_STATISTICS */
+ struct httpd_fsdata_file_noconst *f;
+
+ for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;
+ f != NULL;
+ f = (struct httpd_fsdata_file_noconst *)f->next) {
+
+ if(httpd_fs_strcmp(name, f->name) == 0) {
+ file->data = f->data;
+ file->len = f->len;
+#if HTTPD_FS_STATISTICS
+ ++count[i];
+#endif /* HTTPD_FS_STATISTICS */
+ return 1;
+ }
+#if HTTPD_FS_STATISTICS
+ ++i;
+#endif /* HTTPD_FS_STATISTICS */
+
+ }
+ return 0;
+}
+/*-----------------------------------------------------------------------------------*/
+void
+httpd_fs_init(void)
+{
+#if HTTPD_FS_STATISTICS
+ u16_t i;
+ for(i = 0; i < HTTPD_FS_NUMFILES; i++) {
+ count[i] = 0;
+ }
+#endif /* HTTPD_FS_STATISTICS */
+}
+/*-----------------------------------------------------------------------------------*/
+#if HTTPD_FS_STATISTICS
+u16_t httpd_fs_count
+(char *name)
+{
+ struct httpd_fsdata_file_noconst *f;
+ u16_t i;
+
+ i = 0;
+ for(f = (struct httpd_fsdata_file_noconst *)HTTPD_FS_ROOT;
+ f != NULL;
+ f = (struct httpd_fsdata_file_noconst *)f->next) {
+
+ if(httpd_fs_strcmp(name, f->name) == 0) {
+ return count[i];
+ }
+ ++i;
+ }
+ return 0;
+}
+#endif /* HTTPD_FS_STATISTICS */
+/*-----------------------------------------------------------------------------------*/
View
57 src/libs/Network/uip/webserver/httpd-fs.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: httpd-fs.h,v 1.1 2006/06/07 09:13:08 adam Exp $
+ */
+#ifndef __HTTPD_FS_H__
+#define __HTTPD_FS_H__
+
+#define HTTPD_FS_STATISTICS 1
+
+struct httpd_fs_file {
+ char *data;
+ int len;
+};
+
+/* file must be allocated by caller and will be filled in
+ by the function. */
+int httpd_fs_open(const char *name, struct httpd_fs_file *file);
+
+#ifdef HTTPD_FS_STATISTICS
+#if HTTPD_FS_STATISTICS == 1
+u16_t httpd_fs_count(char *name);
+#endif /* HTTPD_FS_STATISTICS */
+#endif /* HTTPD_FS_STATISTICS */
+
+void httpd_fs_init(void);
+
+#endif /* __HTTPD_FS_H__ */
View
8 src/libs/Network/uip/webserver/httpd-fs/404.html
@@ -0,0 +1,8 @@
+<html>
+ <body bgcolor="white">
+ <center>
+ <h1>404 - file not found</h1>
+ <h3>Go <a href="/">here</a> instead.</h3>
+ </center>
+ </body>
+</html>
View
BIN src/libs/Network/uip/webserver/httpd-fs/img/control_xy.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN src/libs/Network/uip/webserver/httpd-fs/img/control_z.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
283 src/libs/Network/uip/webserver/httpd-fs/index.html
@@ -0,0 +1,283 @@
+<!doctype html>
+<head>
+ <meta charset="utf-8">
+ <title>Single Command</title>
+ <script src="http://code.jquery.com/jquery-1.9.1.js"></script>
+ <script type=text/javascript language=JavaScript>
+ var concentric_circle_radii = [11, 45, 69, 94, 115];
+ var center = [124, 121];
+ var spacer = 7;
+ var zbutton_ydistances = [7, 30, 55, 83];
+ var zcenter = [30, 118];
+
+function runCommand(cmd) {
+ // Get some values from elements on the page:
+ var $form = $( "#commandForm" );
+ cmd += "\n";
+ url = "/command_silent"; // $form.attr( "action" );
+ // Send the data using post
+ var posting = $.post( url, cmd );
+ // Put the results in a div
+ // posting.done(function( data ) {
+ // $( "#result" ).empty();
+ // $.each(data.split('\n'), function(index) {
+ // $( "#result" ).append( this + '<br/>' );
+ // });
+ // });
+}
+
+function lookupConcentric(radius){
+ var length = concentric_circle_radii.length;
+ for (i=0;i<=length;i++) {
+ if (radius < concentric_circle_radii[i]) return(i);
+ }
+ return(length);
+}
+
+function getQuadrantConcentricFromPosition(x,y) {
+ var rel_x = x - center[0]
+ var rel_y = y - center[1]
+ var radius = Math.sqrt(Math.pow(Math.abs(rel_x),2) + Math.pow(Math.abs(rel_y),2))
+ if (rel_x > rel_y && rel_x > -rel_y) {
+ quadrant = 0; // Right
+ } else if (rel_x <= rel_y && rel_x > -rel_y) {
+ quadrant = 3; // Down
+ } else if (rel_x > rel_y && rel_x < -rel_y) {
+ quadrant = 1; // Up
+ } else {
+ quadrant = 2; // Left
+ }
+ var idx = lookupConcentric(radius);
+ return [quadrant, idx]
+}
+
+function clickXY(event){
+ var pos_x = event.offsetX?(event.offsetX):event.pageX-document.getElementById("control_xy").offsetLeft;
+ var pos_y = event.offsetY?(event.offsetY):event.pageY-document.getElementById("control_xy").offsetTop;
+ var codes = getQuadrantConcentricFromPosition(pos_x,pos_y);
+ var quadrant = codes[0], concentric = codes[1];
+ if (concentric < 5) { // movement button pressed
+ var xdir = [1, 0, -1, 0, 0, 0][quadrant];
+ var ydir = [0, 1, 0, -1, 0, 0][quadrant];
+ var magnitude = Math.pow(10, concentric - 2);
+ if (xdir != 0) {
+ command = "G1 X" + (magnitude * xdir) + " F" + document.getElementById("xy_velocity").value;
+ } else {
+ command = "G1 Y" + (magnitude * ydir) + " F" + document.getElementById("xy_velocity").value;
+ }
+ runCommand("G91 " + command + " G90");
+ } else { // home button pressed
+ if (pos_x < 49 && pos_y < 49) { // home x button
+ command = "G28 X0";
+ } else if (pos_x > 200 && pos_y < 49) { //home y button
+ command = "G28 Y0";
+ } else if (pos_x < 49 && pos_y > 200) { // home all button
+ command = "G28";
+ } else { // home z button
+ command = "G28 Z0";
+ }
+ runCommand(command);
+ }
+}
+
+function lookupRange(ydist) {
+ var length = zbutton_ydistances.length;
+ for (i=0;i<length;i++) {
+ if (ydist < zbutton_ydistances[i]) return i;
+ }
+}
+
+function clickZ(event){
+ //var pos_x = event.offsetX?(event.offsetX):event.pageX-document.getElementById("control_z").offsetLeft;
+ var pos_y = event.offsetY?(event.offsetY):event.pageY-document.getElementById("control_z").offsetTop;
+ var ydelta = zcenter[1] - pos_y;
+ var range = lookupRange(Math.abs(ydelta));
+ var direction = (ydelta > 0)?1:-1;
+ if (range < 4) {
+ runCommand("G91 G1 Z" + (Math.pow(10,range-2) * direction) + " F" + document.getElementById("z_velocity").value + " G90");
+ }
+}
+
+function extrude(event,a,b) {
+ var length = document.getElementById("extrude_length").value;
+ var velocity = document.getElementById("extrude_velocity").value;
+ var direction = (event.currentTarget.id=='extrude')?1:-1;
+ runCommand("G91 G1 E" + (length * direction) + " F" + velocity + " G90");
+}
+
+function motorsOff(event) {
+ runCommand("M18");
+}
+
+function heatSet(event) {
+ var type = (event.currentTarget.id=='heat_set')?104:140;
+ var temperature = (type==104)?document.getElementById("heat_value").value:document.getElementById("bed_value").value;
+ runCommand("M" + type + " S" + temperature);
+}
+
+function heatOff(event) {
+ var type = (event.currentTarget.id=='heat_off')?104:140;
+ runCommand("M" + type + " S0");
+}
+
+</script>
+</head>
+
+<body>
+ <h1>Welcome to Smoothie web interface</h1>
+
+<button id=motors_off onclick=motorsOff(event)>Motors Off</button>
+XY:<input type=text id=xy_velocity size=4 value=3000 style=width:50px>mm/min
+Z:<input type=text id=z_velocity size=3 value=200 style=width:40px>
+<br>
+<img id=control_xy src=img/control_xy.png onclick=clickXY(event)>
+<img id=control_z src=img/control_z.png onclick=clickZ(event)>
+<br>
+<table><tr><td>
+<table>
+<tr>
+<td style=text-align:right>Heat:</td>
+<td><button id=heat_off onclick=heatOff(event)>Off</button></td>
+<td><input type=text id=heat_value size=3 style=width:40px value=0></td>
+<td><button id=heat_set onclick=heatSet(event)>Set</button></td>
+</tr>
+<tr>
+<td style=text-align:right>Bed:</td>
+<td><button id=bed_off onclick=heatOff(event)>Off</button></td>
+<td><input type=text id=bed_value size=3 style=width:40px value=0></td>
+<td><button id=bed_set onclick=heatSet(event)>Set</button></td>
+</tr>
+</table>
+</td><td valign=top>
+<button id=get_temperature onclick=runCommand("M105")>Get Temperature</button>
+</td></tr></table>
+<br>
+<button id=extrude onclick=extrude(event)>Extrude</button>
+<button id=reverse onclick=extrude(event)>Reverse</button><br>
+<input type=text id=extrude_length value=5 size=3 style=width:35px>
+mm @
+<input type=text id=extrude_velocity value=100 size=3 style=width:40px>
+mm/min
+
+ <h2>Commands</h2>
+ <form action="/command" id="commandForm">
+ <input type="text" name="commandText" placeholder="Send Command...">
+ <input type="submit" value="Send">
+ </form>
+ <!-- the result of the command will be rendered inside this div -->
+ <div id="result"></div>
+ <script>
+ // Attach a submit handler to the form
+ $( "#commandForm" ).submit(function( event ) {
+ // Stop form from submitting normally
+ event.preventDefault();
+ // Get some values from elements on the page:
+ var $form = $( this );
+ command = $form.find( "input[name='commandText']" ).val();
+ command += "\n";
+ url = $form.attr( "action" );
+ // Send the data using post
+ var posting = $.post( url, command );
+ // Put the results in a div
+ posting.done(function( data ) {
+ $( "#result" ).empty();
+ $.each(data.split('\n'), function(index) {
+ $( "#result" ).append( this + '<br/>' );
+ });
+ });
+ });
+ </script>
+
+ <h2> Upload File </h2>
+ <input type="file" id="files" name="files[]" onchange="upload();" />
+
+ <h3>Uploading file(s)</h3>
+ <output id="list"></output>
+ <div id="progress"></div>
+ <div id="uploadresult"></div>
+ <script>
+ function handleFileSelect(evt) {
+ var files = evt.target.files; // handleFileSelectist object
+
+ // files is a FileList of File objects. List some properties.
+ var output = [];
+ for (var i = 0, f; f = files[i]; i++) {
+ output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
+ f.size, ' bytes, last modified: ',
+ f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
+ '</li>');
+ }
+ document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
+ }
+
+ document.getElementById('files').addEventListener('change', handleFileSelect, false);
+
+
+ function upload() {
+ // take the file from the input
+ var file = document.getElementById('files').files[0];
+ var reader = new FileReader();
+ reader.readAsBinaryString(file); // alternatively you can use readAsDataURL
+ reader.onloadend = function(evt)
+ {
+ // create XHR instance
+ xhr = new XMLHttpRequest();
+
+ // send the file through POST
+ xhr.open("POST", 'upload', true);
+ xhr.setRequestHeader('X-Filename', file.name);
+
+ // make sure we have the sendAsBinary method on all browsers
+ XMLHttpRequest.prototype.mySendAsBinary = function(text){
+ var data = new ArrayBuffer(text.length);
+ var ui8a = new Uint8Array(data, 0);
+ for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
+
+ if(typeof window.Blob == "function")
+ {
+ var blob = new Blob([data]);
+ }else{
+ var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
+ bb.append(data);
+ var blob = bb.getBlob();
+ }
+
+ this.send(blob);
+ }
+
+ // let's track upload progress
+ var eventSource = xhr.upload || xhr;
+ eventSource.addEventListener("progress", function(e) {
+ // get percentage of how much of the current file has been sent
+ var position = e.position || e.loaded;
+ var total = e.totalSize || e.total;
+ var percentage = Math.round((position/total)*100);
+
+ // here you should write your own code how you wish to proces this
+ $( "#progress" ).empty().append('uploaded ' + percentage + '%');
+ });
+
+ // state change observer - we need to know when and if the file was successfully uploaded
+ xhr.onreadystatechange = function()
+ {
+ if(xhr.readyState == 4)
+ {
+ if(xhr.status == 200)
+ {
+ // process success
+ $( "#uploadresult" ).empty().append( 'Uploaded Ok');
+ }else{
+ // process error
+ $( "#uploadresult" ).empty().append( 'Uploaded Failed');
+ }
+ }
+ };
+
+ // start sending
+ xhr.mySendAsBinary(evt.target.result);
+ };
+ }
+ </script>
+
+</body>
+</html>
View
69 src/libs/Network/uip/webserver/httpd-fsdata.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001, Swedish Institute of Computer Science.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the lwIP TCP/IP stack.
+ *
+ * Author: Adam Dunkels <adam@sics.se>
+ *
+ * $Id: httpd-fsdata.h,v 1.1 2006/06/07 09:13:08 adam Exp $
+ */
+#ifndef __HTTPD_FSDATA_H__
+#define __HTTPD_FSDATA_H__
+
+#undef HTTPD_FS_STATISTICS
+
+#include "uip.h"
+
+
+struct httpd_fsdata_file {
+ const struct httpd_fsdata_file *next;
+// const char *name;
+// const char *data;
+ const unsigned char *name;
+ const unsigned char *data;
+ const int len;
+#ifdef HTTPD_FS_STATISTICS
+#if HTTPD_FS_STATISTICS == 1
+ u16_t count;
+#endif /* HTTPD_FS_STATISTICS */
+#endif /* HTTPD_FS_STATISTICS */
+};
+
+struct httpd_fsdata_file_noconst {
+ struct httpd_fsdata_file *next;
+ char *name;
+ char *data;
+ int len;
+#ifdef HTTPD_FS_STATISTICS
+#if HTTPD_FS_STATISTICS == 1
+ u16_t count;
+#endif /* HTTPD_FS_STATISTICS */
+#endif /* HTTPD_FS_STATISTICS */
+};
+
+#endif /* __HTTPD_FSDATA_H__ */
View
0 src/libs/Network/uip/webserver/httpd-fsdata2.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/Network/uip/webserver/httpd.c
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/Network/uip/webserver/httpd.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/Network/uip/webserver/makefsdata.pl
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/Network/uip/webserver/makestrings
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/Network/uip/webserver/webserver.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/Pin.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/Pin.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/RingBuffer.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/StreamOutputPool.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/libs/USBDevice/USBSerial/CircBuffer.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/main.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/robot/Conveyor.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/robot/Robot.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/tools/endstops/Endstops.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/utils/panel/panels/VikiLCD.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/utils/panel/screens/WatchScreen.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/utils/panel/screens/WatchScreen.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/utils/player/Player.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/utils/simpleshell/SimpleShell.cpp
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 src/modules/utils/simpleshell/SimpleShell.h
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/404.html
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/css/font-awesome-ie7.css
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/css/font-awesome.css
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/css/style.css
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/images/control_e.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 webif/images/control_xy.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 webif/images/control_z.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 webif/images/prusa_icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 webif/images/upload_stripe.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 webif/img/control_xy.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 webif/img/control_z.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 webif/index.html
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/js/boundvalue.js
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/js/jog.js
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/js/netrap.js
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/js/prototype.js
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/netrap.html
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
0 webif/netrap_old.html
Sorry, we could not display the changes to this file because there were too many other changes to display.

0 comments on commit d4ee6ee

Please sign in to comment.
Something went wrong with that request. Please try again.