Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

move a LOT around and fix the system broadcasting.

DHCP stil ldoesn't work.
  • Loading branch information...
commit 09ad7e6f4b6e0c624839b79c32ea15f7bd4d3e95 1 parent ce54dcd
@cnlohr authored
View
8 demo_mineandhttp/Makefile
@@ -2,6 +2,7 @@ all : program.hex burn program.lst
CC = avr-gcc
SRCS = test.c \
+ dumbgame.c \
../libs/avr_print.c \
../ipcore/enc424j600.c \
../ipcore/iparpetc.c \
@@ -15,15 +16,18 @@ SRCS = test.c \
PROCESSOR=atmega328
PROGRAMCODE=m328
+#CPUFREQ=28636363UL
+CPUFREQ=20000000UL
COMMON_FLAGS= -mmcu=$(PROCESSOR) -I. -I.. -I../http -I../microsd -I../libs -I../ipcore -I../dumbcraft
-CFLAGS = -std=gnu99 -Os $(COMMON_FLAGS) -DF_CPU=28636363UL -DNO_HTTP #-DMUTE_PRINTF #-DNO_HTTP #-Wall
+CFLAGS = -std=gnu99 -Os $(COMMON_FLAGS) -DF_CPU=$(CPUFREQ) -DNO_HTTP #-DMUTE_PRINTF #-DNO_HTTP #-Wall
+CFLAGS:=$(CFLAGS) --combine -fwhole-program
AS = avr-gcc
ASFLAGS = $(COMMON_FLAGS) -c
EXTRA_LD_FLAGS=-Wl,--relax -Wa,-a,-ad -mcall-prologues
program.elf : $(SRCS)
- avr-gcc --combine -fwhole-program -I -mmcu=$(PROCESSOR) $(CFLAGS) -o $@ $^ -L /usr/lib64/binutils/avr/2.19.1 $(EXTRA_LD_FLAGS) > program.lst
+ avr-gcc -I -mmcu=$(PROCESSOR) $(CFLAGS) -o $@ $^ -L /usr/lib64/binutils/avr/2.19.1 $(EXTRA_LD_FLAGS) > program.lst
avr-size -A $@
@echo "Total = .data + .text"
avr-objdump program.elf -t > program.map
View
32 demo_mineandhttp/dumbgame.h → demo_mineandhttp/dumbgame.c
@@ -42,13 +42,15 @@
// static void PlayerUpdate( uint8_t playerid );
// static void DoCustomPreloadStep( uint8_t playerid );
// static void InitDumbgame();
+// int ClientHandleChat( chat, chatlen ); //return 1 if you want the chat to propogate.
/* General notes for writing the game portion:
1) You have a limited send-size, it's around 512 bytes. Split up your commands among multiple packets.
2) Do not send when receiving. Add extra flags to the player structure to send when it's time to send.
*/
-
+#include "dumbcraft.h"
+#include <string.h>
uint8_t regaddr_set;
uint8_t regval_set;
@@ -59,12 +61,12 @@ volatile uint8_t regval_get;
uint8_t hasset_value;
uint8_t latch_setting_value;
-static void InitDumbgame()
+void InitDumbgame()
{
//no code.
}
-static void DoCustomPreloadStep( uint8_t playerid )
+void DoCustomPreloadStep( uint8_t playerid )
{
struct Player * p = &Players[playerid];
@@ -98,7 +100,7 @@ static void DoCustomPreloadStep( uint8_t playerid )
p->need_to_send_lookupdate = 1;
}
-static void PlayerTickUpdate( int playerid )
+void PlayerTickUpdate( int playerid )
{
//printf( "%f %f %f\n", SetDouble(p->x), SetDouble(p->y), SetDouble(p->z) );
struct Player * p = &Players[playerid];
@@ -117,7 +119,7 @@ static void PlayerTickUpdate( int playerid )
}
}
-static void PlayerClick( uint8_t playerid, uint8_t x, uint8_t y, uint8_t z )
+void PlayerClick( uint8_t playerid, uint8_t x, uint8_t y, uint8_t z )
{
struct Player * p = &Players[playerid];
@@ -168,7 +170,7 @@ static void PlayerClick( uint8_t playerid, uint8_t x, uint8_t y, uint8_t z )
}
-static void PlayerUpdate( uint8_t playerid )
+void PlayerUpdate( uint8_t playerid )
{
uint8_t i;
struct Player * p = &Players[playerid];
@@ -237,4 +239,22 @@ static void PlayerUpdate( uint8_t playerid )
}
}
+
+void SetServerName( const char * stname );
+
+uint8_t ClientHandleChat( char * chat, uint8_t chatlen )
+{
+ if( chat[0] == '/' )
+ {
+ if( strncmp( &chat[1], "title", 5 ) == 0 && chatlen > 8 )
+ {
+ chat[chatlen] = 0;
+ SetServerName( &chat[7] );
+ return 0;
+ }
+ }
+ return chatlen;
+}
+
+
#endif
View
8 demo_mineandhttp/eth_config.h
@@ -51,6 +51,11 @@
//Do this to disable printf's and save space
//#define MUTE_PRINTF
+
+//DHCP will allow your device to automatically acquire an IP address.
+#define ENABLE_DHCP_CLIENT
+
+
//UDP is pretty well tested. It takes up ~350 bytes
//If you use UDP, you will need to implement the following function:
// void HandleUDP( uint16_t len ) { ... }
@@ -86,10 +91,11 @@
//Additional applications
+#ifndef NO_HTTP
#define INCLUDE_HTTP_SERVER
#define HTTP_SERVER_TIMEOUT (10000)
#define HTTP_CONNECTIONS 6
-
+#endif
//Scratchpad for sending out packets like UDP, ICMP, ARP, etc.
#define TX_SCRATCHPAD_END 1024
View
18 demo_mineandhttp/test.c
@@ -14,6 +14,7 @@
#include <http.h>
#include <string.h>
#include <basicfat.h>
+#include <avr/eeprom.h>
/*
Useful ports:
@@ -53,6 +54,14 @@ unsigned char cc;
int8_t lastconnection = -1; //for dumbcraft
uint16_t bytespushed; //for dumbcraft
+uint8_t EEMEM my_server_name_eeprom[16];
+char my_server_name[16];
+
+void SetServerName( const char * stname )
+{
+ memcpy( my_server_name, stname, strlen( stname ) + 1 );
+ eeprom_write_block( stname, my_server_name_eeprom, strlen( stname ) + 1 );
+}
#ifdef NO_HTTP
#undef HTTP_CONNECTIONS
@@ -324,7 +333,7 @@ void HTTPCustomCallback( )
unsigned char MyIP[4] = { 192, 168, 0, 142 };
unsigned char MyMask[4] = { 255, 255, 255, 0 };
-
+unsigned char MyGateway[4] = { 192, 168, 0, 1 };
unsigned char MyMAC[6];
@@ -340,6 +349,10 @@ int main( void )
sendstr( "HELLO\n" );
setup_clock();
+ eeprom_read_block( &my_server_name[0], &my_server_name_eeprom[0], 16 );
+ if( my_server_name[0] == 0 || my_server_name[0] == (char)0xff )
+ SetServerName( "AVRCraft" );
+
//Configure T2 to "overflow" at 100 Hz, this lets us run the TCP clock
TCCR2A = _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21) | _BV(CS20);
@@ -375,6 +388,8 @@ int main( void )
}
sendstr( "OK.\n" );
+ SetupDHCPName( my_server_name );
+
InitDumbcraft();
while(1)
@@ -400,6 +415,7 @@ int main( void )
delayctr++;
if( delayctr==10 )
{
+ TickDHCP();
delayctr = 0;
TickServer();
}
View
123 dumbcraft/dumbcraft.c
@@ -48,6 +48,8 @@ const uint8_t mapdata[] PROGMEM = {
const uint8_t default_spawn_metadata[] PROGMEM = { 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x7F };
+uint8_t dumbcraft_playercount;
+
//////////////////////////////////////////READING UTILITIES////////////////////
//Read in a buffer from the current connection of specified size.
@@ -252,17 +254,14 @@ void UpdatePlayerSpeed( uint8_t playerno, uint8_t speed )
}
-#ifdef INCLUDE_BROADCAST_UTILS
+#ifdef INCLUDE_ANNOUNCE_UTILS
#ifndef INCLUDE_UDP
#error ERROR! You must include UDP if you want to have broadcast.
#endif
#include "iparpetc.h"
-void SendBroadcast( )
+void SendAnnounce( )
{
const char * sending;
-// char stt[12];
-puts( "Tick" );
-
/*
macfrom[0] = 0x01;
macfrom[1] = 0x00;
@@ -271,15 +270,7 @@ puts( "Tick" );
macfrom[4] = 0x02;
macfrom[5] = 0x3c;
*/
-// SwitchToBroadcast();
-
- macfrom[0] = 0xff;
- macfrom[1] = 0xff;
- macfrom[2] = 0xff;
- macfrom[3] = 0xff;
- macfrom[4] = 0xff;
- macfrom[5] = 0xff;
-
+ SwitchToBroadcast();
enc424j600_stopop();
enc424j600_startsend( 0 );
@@ -287,31 +278,23 @@ puts( "Tick" );
// send_ip_header( 0, "\xE0\x00\x02\x3c", 17 ); //UDP Packet to 224.0.2.60
send_ip_header( 0, "\xff\xff\xff\xff", 17 ); //UDP Packet to 255.255.255.255
- Sshort( MINECRAFT_PORT+1 );
- Sshort( 4445 );
- Sshort( 0 ); //length for later
- Sshort( 0 ); //csum for later
-
- Sbuffer( "[MOTD]", 6 );
- for( sending = SERVER_NAME; *sending; sending++ )
- Sbyte( *sending );
-// Sbuffer( SERVER_NAME, strlen( SERVER_NAME ) );
- Sbuffer( "[/MOTD][AD]", 11 );
-
- for( sending = MINECRAFT_PORT_STRING; *sending; sending++ )
- Sbyte( *sending );
-
-// Uint32To10Str( stt, #MINECRAFT_PORT );
-// Sbuffer( stt, strlen( stt ) );
-// Sbuffer( "192.168.0.143:33195", strlen( "192.168.0.143:33195" ) );
- Sbuffer( "[/AD]", 5 );
+ enc424j600_push16( MINECRAFT_PORT+1 );
+ enc424j600_push16( 4445 );
+ enc424j600_push16( 0 ); //length for later
+ enc424j600_push16( 0 ); //csum for later
+
+#ifdef STATIC_MOTD_NAME
+ enc424j600_pushpgmstr( PSTR( "[MOTD]"MOTD_NAME"[/MOTD][AD]"MINECRAFT_PORT_STRING"[/AD]" ) );
+#else
+ enc424j600_pushpgmstr( PSTR( "[MOTD]" ) );
+ enc424j600_pushstr( MOTD_NAME );
+ enc424j600_pushpgmstr( PSTR( "[/MOTD][AD]"MINECRAFT_PORT_STRING"[/AD]" ) );
+#endif
util_finish_udp_packet();
}
#endif
-#include "dumbgame.h"
-
void InitDumbcraft()
{
memset( &Players, 0, sizeof( Players ) );
@@ -325,10 +308,13 @@ void UpdateServer()
{
uint8_t player, i;
uint16_t i16;
+ uint8_t localplayercount;
for( player = 0; player < MAX_PLAYERS; player++ )
{
struct Player * p = &Players[player];
+ if( p->active ) localplayercount++;
+
if( !p->active || !CanSend( player ) ) continue;
p->update_number++;
@@ -477,21 +463,38 @@ void UpdateServer()
}
if( p->need_to_send_playerlist )
{
+
+#ifdef STATIC_SERVER_STAT_STRING
+#ifndef STATIC_MOTD_NAME
+#error Cannot make a dumb server response string if you have a dynamic server name.
+#endif
+#define VERSION_AND_STRING_AND_ALL "\xa7\x31\x00"PROTO_VERSION_STR"\x00"LONG_PROTO_VERSION"\x00"MOTD_NAME"\x000\x00"MAX_PLAYERS_STRING
+ uint8_t stt[sizeof( VERSION_AND_STRING_AND_ALL )];
+ memcpy_P( stt, PSTR( VERSION_AND_STRING_AND_ALL ), sizeof( VERSION_AND_STRING_AND_ALL ) );
+ Sbyte( 0xff );
+ Sstring( stt, sizeof( VERSION_AND_STRING_AND_ALL ) );
+
+#else
uint16_t optr = 0;
uint8_t stt[40];
- //XXX TODO: Rewrite this part! It's kind of nasty and we could make better use of program space.
- //It chews up extra stack, program AND .data space.
+#define VERSION_AND_STRING "\xa7\x31\x00"PROTO_VERSION_STR"\x00"LONG_PROTO_VERSION
+ memcpy_P( stt, PSTR( VERSION_AND_STRING ), sizeof( VERSION_AND_STRING ) );
+ optr = sizeof( VERSION_AND_STRING );
- StrTack( stt, &optr, "\xa7\x31" ); stt[optr++] = 0;
- StrTack( stt, &optr, PROTO_VERSION_STR ); stt[optr++] = 0;
- StrTack( stt, &optr, "\x32\x2e\x34\xe2\x32" ); stt[optr++] = 0;
- StrTack( stt, &optr, "dumbcraft" ); stt[optr++] = 0;
- StrTack( stt, &optr, "0" ); stt[optr++] = 0; //XXX FIXME
- StrTack( stt, &optr, "20" ); //XXX FIXME
- Sbyte( 0xff );
+#ifdef STATIC_MOTD_NAME
+
+ PgmStrTack( stt, &optr, PSTR( MOTD_NAME ) ); stt[optr++] = 0;
+#else
+ StrTack( stt, &optr, MOTD_NAME ); stt[optr++] = 0;
+#endif
+ Uint8To10Str( stt + optr, dumbcraft_playercount );
+ optr += 4;
+ PgmStrTack( stt, &optr, PSTR( MAX_PLAYERS_STRING ) );
+ Sbyte( 0xff );
Sstring( stt, optr );
+#endif
p->need_to_send_playerlist = 0;
}
@@ -521,6 +524,7 @@ void UpdateServer()
EndSend();
}
+ dumbcraft_playercount = localplayercount;
}
@@ -531,14 +535,13 @@ void TickServer()
dumbcraft_tick++;
#ifdef DEBUG_DUMBCRAFT
-// printf( "Tick.\n" );
+ puts( "Tick." );
#endif
-#ifdef INCLUDE_BROADCAST_UTILS
- printf( "%04x\n", dumbcraft_tick );
+#ifdef INCLUDE_ANNOUNCE_UTILS
if( ( dumbcraft_tick & 0xf ) == 0 )
{
- SendBroadcast( );
+ SendAnnounce( );
}
#endif
@@ -804,20 +807,24 @@ void GotData( uint8_t playerno )
{
uint8_t pll = strlen( p->playername );
- StartupBroadcast();
+ if( ClientHandleChat( chat, chatlen ) )
+ {
+
+ StartupBroadcast();
- Sbyte( 0x03 );
+ Sbyte( 0x03 );
- Sshort( chatlen + pll + 2 + 10 + 2 );
+ Sshort( chatlen + pll + 2 + 10 + 2 );
- SbufferWide( "{\"text\":\"<", 10 );
- SbufferWide( p->playername, pll );
- Sshort( '>' ) ;
- Sshort( ' ' ) ;
- SbufferWide( chat, chatlen );
- Sshort( '"' );
- Sshort( '}' );
- DoneBroadcast();
+ SbufferWide( "{\"text\":\"<", 10 );
+ SbufferWide( p->playername, pll );
+ Sshort( '>' ) ;
+ Sshort( ' ' ) ;
+ SbufferWide( chat, chatlen );
+ Sshort( '"' );
+ Sshort( '}' );
+ DoneBroadcast();
+ }
}
}
View
21 dumbcraft/dumbcraft.h
@@ -5,24 +5,16 @@
#define PROTO_VERSION 74
#define PROTO_VERSION_STR "74"
+#define LONG_PROTO_VERSION "1.6.2"
#define PLAYER_EID_BASE 0x20
#include "dumbconfig.h"
-//Overworld
-#define WORLDTYPE 0
-#define GAMEMODE 0
-
//For floating-point values when converting to int16's
//Smaller numbers yeild less accuracy, but bigger maximums
#define FIXEDPOINT 5
-#define MAPSIZECHUNKS 1
-
-#define RUNSPEED 5
-#define WALKSPEED 3
-
#include <stdint.h>
//Communications core section
@@ -88,6 +80,7 @@ struct Player
} Players[MAX_PLAYERS];
extern uint16_t dumbcraft_tick;
+extern uint8_t dumbcraft_playercount;
//Tools for the user:
void Rbuffer( uint8_t * buffer, uint8_t size );
@@ -109,5 +102,15 @@ void SblockInternal( uint8_t x, uint8_t y, uint8_t z, uint8_t bt, uint8_t meta )
void SSpawnPlayer( uint8_t pid );
void UpdatePlayerSpeed( uint8_t playerno, uint8_t speed );
+//You must write the following:
+uint8_t ClientHandleChat( char * chat, uint8_t chatlen );
+void PlayerUpdate( uint8_t playerid );
+void PlayerClick( uint8_t playerid, uint8_t x, uint8_t y, uint8_t z );
+void PlayerTickUpdate( int playerid );
+void DoCustomPreloadStep( uint8_t playerid );
+void InitDumbgame();
+
+
+
#endif
View
18 http/http.c
@@ -10,7 +10,10 @@
//Extra ~120 bytes of code, but ~30% overall performance boost!
#define FAST_SECTOR_TRANSFER
+#define PSTRx PSTR
+#define PushPGMStr enc424j600_pushpgmstr
#define POP enc424j600_pop8()
+
static void InternalStartHTTP( );
struct HTTPConnection * curhttp;
@@ -132,21 +135,6 @@ void HTTPTick()
}
-
-void PushPGMStr( const char * msg )
-{
- uint8_t r;
-
- do
- {
- r = pgm_read_byte(msg++);
- if( !r ) break;
- enc424j600_push8( r );
- } while( 1 );
-}
-
-#define PSTRx PSTR
-
void HTTPHandleInternalCallback( )
{
uint16_t i, bytestoread;
View
17 ipcore/enc424j600.c
@@ -53,6 +53,23 @@ void enc424j600_popblob( uint8_t * data, uint8_t len )
}
}
+void enc424j600_pushpgmstr( const char * msg )
+{
+ uint8_t r;
+ do
+ {
+ r = pgm_read_byte(msg++);
+ if( !r ) break;
+ enc424j600_push8( r );
+ } while( 1 );
+}
+
+void enc424j600_pushstr( const char * msg )
+{
+ for( ; *msg; msg++ )
+ enc424j600_push8( *msg );
+}
+
void enc424j600_pushblob( const uint8_t * data, uint8_t len )
{
while( len-- )
View
3  ipcore/enc424j600.h
@@ -57,8 +57,11 @@ uint16_t enc424j600_pop16();
#define enc424j600_pop8 espiR
//Raw, on-wire push. (assuming already in write)
+void enc424j600_pushpgmstr( const char * msg );
+void enc424j600_pushstr( const char * msg );
void enc424j600_pushblob( const uint8_t * data, uint8_t len );
#define enc424j600_push8 espiW
+void enc424j600_pushzeroes( uint8_t nrzeroes ) { while( nrzeroes-- ) enc424j600_push8(0); }
void enc424j600_push16( uint16_t v);
//XXX: Todo: see if we can find a faster way of invoking espiR.
View
292 ipcore/iparpetc.c
@@ -31,6 +31,258 @@ static unsigned short i; //For use within the scope of an in-file function, not
#include "tcp.h"
#endif
+
+#ifdef ENABLE_DHCP_CLIENT
+
+#ifndef INCLUDE_UDP
+#error ERROR: You must have UDP support for DHCP support.
+#endif
+
+void RequestNewIP(uint8_t mode);
+
+uint8_t dhcp_clocking = 1;
+uint16_t dhcp_seconds_remain = 0;
+uint8_t dhcp_ticks_in_sec = 0;
+uint8_t negotiating_ip[4];
+uint8_t dhcp_server[4];
+uint8_t current_dhcp_mode = 0;
+const char * DHCPName = 0;
+
+void HandleDHCP( uint16_t len )
+{
+ uint8_t tmpip[4];
+ uint8_t tmp[4];
+ uint8_t optionsleft = 48; //We only allow for up to 48 options
+ uint16_t first4, second4;
+
+ POP16; //Clear out checksum
+
+ //Process DHCP!
+ if( POP != 2 ) return; //Not a reply?
+ if( POP != 1 ) return; //Not Ethernet?
+ POP16; //size of packets + Hops
+
+ //Make sure transaction IDs match.
+// enc424j600_popblob( tmp, 4 );
+
+ if( POP != MyMAC[0] ||
+ POP != MyMAC[1] ||
+ POP != MyMAC[2] ||
+ POP != MyMAC[3] + 0 ) //current_dhcp_mode
+ {
+ return;
+ }
+/* if( strncmp( tmp, MyMAC, 4 ) != 0 )
+ {
+ //Not our request?
+ return;
+ }*/
+
+ enc424j600_dumpbytes( 8 ); //time elapsed + bootpflags + Client IP address
+
+ enc424j600_popblob( tmpip, 4 ); //MY IP ADDRESS!!!
+
+ enc424j600_dumpbytes( 0x18 + 0xc0 ); //Next IP + Relay IP + Mac + Padding + server name + boot name
+
+ first4 = POP16;
+ second4 = POP16;
+
+ if( first4 != 0x6382 || second4 != 0x5363 )
+ {
+ return;
+ }
+
+ //Ok, we know we have a valid DHCP packet.
+
+ //We dont want to get stuck, so we will eventually bail if we have an issue pasrsing.
+ while( optionsleft-- )
+ {
+ uint8_t option = POP;
+ uint8_t length = POP;
+
+ switch(option)
+ {
+ case 0x35: //DHCP Message Type
+ {
+ if( length < 1 ) return;
+ uint8_t rqt = POP;
+
+ if( rqt == 0x02 )
+ {
+ //OFFER!
+ current_dhcp_mode = 3;
+ memcpy( dhcp_server, ipsource, 4 );
+ memcpy( negotiating_ip, tmpip, 4 );
+ return;
+ }
+
+ if( rqt == 0x05 ) // Got a valid IP. (ACK)
+ {
+ //IP Is valid.
+ memcpy( MyIP, tmpip, 4 );
+ }
+
+/* if( POP != 0x05 ) //Is it /not/ a DHCP ACK?
+ {
+ return;
+ }
+*/
+ length--;
+ break;
+ }
+ case 0x3a: //Renewal time
+ {
+ if( length < 4 ) break;
+ first4 = POP16;
+ second4 = POP16;
+ if( first4 )
+ {
+ dhcp_seconds_remain = 0xffff;
+ }
+ else
+ {
+ dhcp_seconds_remain = second4;
+ }
+
+ length -= 4;
+ }
+ case 0x01: //Subnet mask
+ {
+ if( length < 4 ) break;
+ enc424j600_popblob( MyMask, 4 );
+ length -= 4;
+ }
+ case 0x03: //Router mask
+ {
+ if( length < 4 ) break;
+ enc424j600_popblob( MyGateway, 4 );
+ length -= 4;
+ }
+ case 0xff: //End of list.
+ return;
+ case 0x42: //Time server
+ case 0x06: //DNS server
+ default:
+ break;
+ }
+ enc424j600_dumpbytes( length );
+ }
+
+
+}
+
+void SetupDHCPName( const char * name )
+{
+ DHCPName = name;
+ memcpy( negotiating_ip, MyIP, 4 );
+ current_dhcp_mode = 1;
+}
+
+void TickDHCP()
+{
+ if( dhcp_ticks_in_sec++ < DHCP_TICKS_PER_SECOND )
+ {
+ return;
+ }
+
+ dhcp_ticks_in_sec = 0;
+
+
+ if( dhcp_seconds_remain == 0 )
+ {
+ //No DHCP received yet.
+ if( dhcp_clocking == 250 ) dhcp_clocking = 0;
+ dhcp_clocking++;
+ RequestNewIP( current_dhcp_mode );
+ }
+ else
+ {
+ dhcp_seconds_remain--;
+ }
+}
+
+//Mode = 1 for discover
+//Mode = 3 for request
+void RequestNewIP( uint8_t mode )
+{
+ uint8_t oldip[4];
+ SwitchToBroadcast();
+
+ enc424j600_stopop();
+ enc424j600_startsend( 0 );
+ send_etherlink_header( 0x0800 );
+
+ //Tricky - backup our IP - we want to spoof it to 0.0.0.0
+ memcpy( oldip, MyIP, 4 );
+ if( current_dhcp_mode == 3 )
+ {
+ //Try using our offered IP...
+ MyIP[0] = negotiating_ip[0]; MyIP[1] = negotiating_ip[1]; MyIP[2] = negotiating_ip[2]; MyIP[3] = negotiating_ip[3];
+ }
+ else
+ {
+ //Use 0.0.0.0
+ MyIP[0] = 0; MyIP[1] = 0; MyIP[2] = 0; MyIP[3] = 0;
+ }
+ send_ip_header( 0, "\xff\xff\xff\xff", 17 ); //UDP Packet to 255.255.255.255
+ memcpy( MyIP, oldip, 4 );
+
+ enc424j600_push16( 68 ); //From bootpc
+ enc424j600_push16( 67 ); //To bootps
+ enc424j600_push16( 0 ); //length for later
+ enc424j600_push16( 0 ); //csum for later
+
+ //Payload of BOOTP packet.
+ // 1, //Bootp request
+ // 1, //Ethernet
+ enc424j600_push16( 0x0101 );
+ // 6, //MAC Length
+ // 0, //Hops
+ enc424j600_push16( 0x0600 );
+
+ enc424j600_push8( MyMAC[0] ); //RequestID
+ enc424j600_push8( MyMAC[1] );
+ enc424j600_push8( MyMAC[2] );
+ enc424j600_push8( MyMAC[3] + 0 );
+
+ enc424j600_push16( dhcp_clocking ); //seconds
+ enc424j600_pushzeroes( 18 ); //unicast, and 4 zero IPs.
+ enc424j600_pushblob( MyMAC, 6 ); //client mac
+ enc424j600_pushzeroes( 10 + 0x40 + 0x80 ); //padding + Server Host Name
+ enc424j600_push16( 0x6382 ); //DHCP Magic Cookie
+ enc424j600_push16( 0x5363 );
+
+ //Now we are on our DHCP portion
+ enc424j600_push8( 0x35 ); //DHCP Message Type
+ enc424j600_push16( 0x0100 | mode );
+
+ {
+ enc424j600_push16( 0x3204 ); //Requested IP address. (4 length)
+ enc424j600_pushblob( negotiating_ip, 4 );
+ }
+
+ if( DHCPName )
+ {
+ uint8_t namelen = strlen( DHCPName );
+ enc424j600_push8( 0x0c ); //Name
+ enc424j600_push8( namelen );
+ enc424j600_pushblob( DHCPName, namelen );
+ }
+
+ enc424j600_push16( 0x3704 ); //Parameter request list
+ enc424j600_push16( 0x0103 ); //subnet mask, router
+ enc424j600_push16( 0x2a06 ); //NTP server, DNS server
+
+ enc424j600_push8( 0xff ); //End option
+
+ enc424j600_pushzeroes( 32 ); //Padding
+
+ util_finish_udp_packet();
+}
+
+#endif
+
+
void send_etherlink_header( unsigned short type )
{
PUSHB( macfrom, 6 );
@@ -231,6 +483,7 @@ static void HandleArp( )
void enc424j600_receivecallback( uint16_t packetlen )
{
+ uint8_t is_the_packet_for_me = 1;
unsigned char i;
unsigned char ipproto;
@@ -276,12 +529,13 @@ void enc424j600_receivecallback( uint16_t packetlen )
POPB( ipsource, 4 );
+
for( i = 0; i < 4; i++ )
{
unsigned char m = ~MyMask[i];
unsigned char ch = POP;
if( ch == MyIP[i] || (ch & m) == 0xff ) continue;
- return;
+ is_the_packet_for_me = 0;
}
//XXX TODO Handle IPL > 5 (IHL?)
@@ -289,6 +543,9 @@ void enc424j600_receivecallback( uint16_t packetlen )
switch( ipproto )
{
case 1: //ICMP
+ if( !is_the_packet_for_me )
+ break;
+
HandleICMP();
break;
#ifdef INCLUDE_UDP
@@ -296,6 +553,18 @@ void enc424j600_receivecallback( uint16_t packetlen )
{
remoteport = POP16;
localport = POP16;
+
+#ifdef ENABLE_DHCP_CLIENT
+ if( localport == 68 )
+ {
+ HandleDHCP( POP16 );
+ break;
+ }
+#endif
+
+ if( !is_the_packet_for_me )
+ break;
+
//err is this dangerous?
HandleUDP( POP16 );
break;
@@ -304,6 +573,9 @@ void enc424j600_receivecallback( uint16_t packetlen )
#ifdef INCLUDE_TCP
case 6: // TCP
{
+ if( !is_the_packet_for_me )
+ break;
+
remoteport = POP16;
localport = POP16;
iptotallen-=20;
@@ -312,8 +584,10 @@ void enc424j600_receivecallback( uint16_t packetlen )
}
#endif // HAVE_TCP_SUPPORT
default:
- enc424j600_finish_callback_now();
+ break;
}
+
+ enc424j600_finish_callback_now();
}
@@ -329,7 +603,7 @@ void util_finish_udp_packet( )// unsigned short length )
unsigned short length = enc424j600_get_write_length();
//Write length in packet
- enc424j600_alter_word( 10, length );
+ enc424j600_alter_word( 10, length-14 ); //Experimentally determined 14, 0 was used for a long time.
enc424j600_start_checksum( 8, 20 );
enc424j600_alter_word( 32, length-34 );
@@ -355,6 +629,14 @@ void util_finish_udp_packet( )// unsigned short length )
#endif
+
+void SwitchToBroadcast()
+{
+ //Set the address we want to send to (broadcast)
+ for( i = 0; i < 6; i++ )
+ macfrom[i] = 0xff;
+}
+
#ifdef ARP_CLIENT_SUPPORT
int8_t RequestARP( uint8_t * ip )
@@ -369,9 +651,7 @@ int8_t RequestARP( uint8_t * ip )
}
}
- //Set the address we want to send to (broadcast)
- for( i = 0; i < 6; i++ )
- macfrom[i] = 0xff;
+ SwitchToBroadcast();
//No MAC Found. Send an ARP request.
enc424j600_finish_callback_now();
View
17 ipcore/iparpetc.h
@@ -17,7 +17,7 @@ void enc28j60_receivecallback( uint16_t packetlen );
extern unsigned char MyIP[];
extern unsigned char MyMask[];
extern unsigned char MyMAC[];
-
+extern unsigned char MyGateway[];
extern unsigned char macfrom[6];
extern unsigned char ipsource[4];
@@ -25,9 +25,9 @@ extern unsigned short remoteport;
extern unsigned short localport;
//Utility out
+void SwitchToBroadcast();
void send_etherlink_header( unsigned short type );
void send_ip_header( unsigned short totallen, const unsigned char * to, unsigned char proto );
-
void util_finish_udp_packet();
#define ipsource_uint ((uint32_t*)&ipsource)
@@ -79,6 +79,19 @@ void DoPing( uint8_t pingslot );
#endif
+#ifdef ENABLE_DHCP_CLIENT
+
+//NOTE: This cannot exceed 255
+#ifndef DHCP_TICKS_PER_SECOND
+#define DHCP_TICKS_PER_SECOND 10
+#endif
+
+extern uint8_t did_get_dhcp;
+void SetupDHCPName( const char * name );
+void TickDHCP(); //Call this DHCP_TICKS_PER_SECOND times per second.
+
+#endif
+
#endif
View
1  libs/avr_print.c
@@ -6,6 +6,7 @@
#include <avr/sleep.h>
#include <util/delay.h>
#include <stdio.h>
+#include "avr_print.h"
#ifndef MUTE_PRINTF
View
19 libs/util10.c
@@ -57,3 +57,22 @@ void StrTack( char * str, uint16_t * optr, const char * strin )
*optr += sl;
}
+#ifdef __AVR__
+#include <avr/pgmspace.h>
+
+void PgmStrTack( char * str, uint16_t * optr, const char * strin )
+{
+ uint8_t r;
+ do
+ {
+ r = pgm_read_byte(strin++);
+ if( !r ) break;
+ str[((*optr)++)] = r;
+ } while( 1 );
+}
+#else
+void PgmStrTack( char * str, uint16_t * optr, const char * strin )
+{
+ StrTack( str, optr, strin );
+}
+#endif
View
9 libs/util10.h
@@ -9,7 +9,7 @@
//Warning: This currently uses a (uint32_t)/(uint8_t) operation!
void Uint32To10Str( char * sto, uint32_t indata );
-//Pass in a buffer of at least 4 bytes. number->string
+//Pass in a buffer of at least 4 bytes. number->string. The string will _always_ be three bytes long with a null.
void Uint8To10Str( char * str, uint8_t val );
//Convert an int to hex. Pass in 3-byte buffer. number->hexstring
@@ -19,4 +19,11 @@ void Uint8To16Str( char * str, uint8_t val );
//Tack two strings together.
void StrTack( char * str, uint16_t * optr, const char * strin );
+//Only strin is a pgmstr
+void PgmStrTack( char * str, uint16_t * optr, const char * strin );
+
+//Only strin is a pgmstr
+void PgmStrTack( char * str, uint16_t * optr, const char * strin );
+
+
#endif
View
2  microsd/basicfat.c
@@ -138,7 +138,7 @@ uint32_t FindClusterFileInDir( const char * fname, uint32_t cluster, int16_t fil
entry = 0;
if( fileid >= 0 )
- longfname = fname;
+ longfname = (char*)fname; //Don't worry, if this is the case, we won't be writing.
else
longfname = alloca( MAX_LONG_FILENAME );
Please sign in to comment.
Something went wrong with that request. Please try again.