Skip to content

Commit

Permalink
Merge pull request #14 from ntruchsess/dev
Browse files Browse the repository at this point in the history
Fix an overflow and add blocking write (configurable)
  • Loading branch information
ntruchsess committed Nov 16, 2013
2 parents 0c83d7c + 39023b4 commit 42e788b
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 41 deletions.
40 changes: 30 additions & 10 deletions UIPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,30 @@ size_t
UIPClient::_write(struct uip_conn* conn, const uint8_t *buf, size_t size)
{
uip_userdata_t *u;
int remain = size;
uint16_t written;
#if UIP_ATTEMPTS_ON_WRITE > 0
uint16_t attempts = UIP_ATTEMPTS_ON_WRITE;
#endif
repeat:
UIPEthernet.tick();
if (conn && (u = (uip_userdata_t *)conn->appstate.user) && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED)))
{
int remain = size;
uint16_t written;
memhandle* p = _currentBlock(&u->packets_out[0]);
if (*p == NOBLOCK)
{
newpacket:
*p = UIPEthernet.network.allocBlock(UIP_SOCKET_DATALEN);
if (*p == NOBLOCK)
goto ready;
{
#if UIP_ATTEMPTS_ON_WRITE > 0
if ((--attempts)>0)
#endif
#if UIP_ATTEMPTS_ON_WRITE != 0
goto repeat;
#endif
goto ready;
}
u->out_pos = 0;
}
#ifdef UIPETHERNET_DEBUG_CLIENT
Expand All @@ -191,7 +203,15 @@ UIPClient::_write(struct uip_conn* conn, const uint8_t *buf, size_t size)
if (remain > 0)
{
if (p==&u->packets_out[UIP_SOCKET_NUMPACKETS-1])
goto ready;
{
#if UIP_ATTEMPTS_ON_WRITE > 0
if ((--attempts)>0)
#endif
#if UIP_ATTEMPTS_ON_WRITE != 0
goto repeat;
#endif
goto ready;
}
p++;
goto newpacket;
}
Expand Down Expand Up @@ -316,11 +336,6 @@ UIPClient::uip_callback(uip_tcp_appstate_t *s)
}
if (u)
{
if (u->state & UIP_CLIENT_RESTART)
{
u->state &= ~UIP_CLIENT_RESTART;
uip_restart();
}
if (uip_newdata())
{
#ifdef UIPETHERNET_DEBUG_CLIENT
Expand Down Expand Up @@ -358,6 +373,11 @@ UIPClient::uip_callback(uip_tcp_appstate_t *s)
}
}
finish_newdata:
if (u->state & UIP_CLIENT_RESTART)
{
u->state &= ~UIP_CLIENT_RESTART;
uip_restart();
}
// If the connection has been closed, save received but unread data.
if (uip_closed() || uip_timedout())
{
Expand Down Expand Up @@ -451,7 +471,7 @@ UIPClient::uip_callback(uip_tcp_appstate_t *s)
memhandle*
UIPClient::_currentBlock(memhandle* block)
{
for(memhandle* end = block+UIP_SOCKET_NUMPACKETS; block < end; block++)
for(memhandle* end = block+UIP_SOCKET_NUMPACKETS-1; block < end; block++)
if(*(block+1) == NOBLOCK)
break;
return block;
Expand Down
31 changes: 3 additions & 28 deletions utility/Enc28J60Network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ extern "C" {

Enc28J60Network::Enc28J60Network() :
MemoryPool(TXSTART_INIT+1, TXSTOP_INIT-TXSTART_INIT), // 1 byte in between RX_STOP_INIT and pool to allow prepending of controlbyte
status(0),
bank(0xff)
{
}
Expand Down Expand Up @@ -268,7 +267,6 @@ uint16_t
Enc28J60Network::readPacket(memhandle handle, memaddress position, uint8_t* buffer, uint16_t len)
{
len = setReadPtr(handle, position, len);
checkDMA();
readBuffer(len, buffer);
return len;
}
Expand Down Expand Up @@ -322,15 +320,14 @@ Enc28J60Network::copyPacket(memhandle dest_pkt, memaddress dest_pos, memhandle s
memblock *dest = &blocks[dest_pkt];
memblock *src = src_pkt == UIP_RECEIVEBUFFERHANDLE ? &receivePkt : &blocks[src_pkt];
memblock_mv_cb(dest->begin+dest_pos,src->begin+src_pos,len);
if (src_pkt == UIP_RECEIVEBUFFERHANDLE)
status |= DMANEWPACKET;
// Move the RX read pointer to the start of the next received packet
// This frees the memory we just read out
setERXRDPT();
}

void
Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len)
{
checkDMA();

//as ENC28J60 DMA is unable to copy single bytes:
if (len == 1)
{
Expand Down Expand Up @@ -372,35 +369,14 @@ Enc28J60Network::memblock_mv_cb(uint16_t dest, uint16_t src, uint16_t len)
/* 4. Start the DMA copy by setting ECON1.DMAST. */
writeOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_DMAST);

status |= DMARUNNING;
}
}

void
Enc28J60Network::checkDMA()
{
if (status & DMARUNNING)
{
// wait until runnig DMA is completed
while (readOp(ENC28J60_READ_CTRL_REG, ECON1) & ECON1_DMAST);

if (status & DMANEWPACKET)
{
// Move the RX read pointer to the start of the next received packet
// This frees the memory we just read out
setERXRDPT();
}
status = 0;
}
}

void
Enc28J60Network::freePacket()
{
// wait until runnig new-packet DMA is completed. This implicitly frees the packet.
if (status & DMANEWPACKET)
checkDMA();
else
setERXRDPT();
}

Expand Down Expand Up @@ -548,7 +524,6 @@ uint16_t
Enc28J60Network::chksum(uint16_t sum, memhandle handle, memaddress pos, uint16_t len)
{
uint16_t t;
checkDMA();
len = setReadPtr(handle, pos, len)-1;
CSACTIVE;
// issue read command
Expand Down
3 changes: 0 additions & 3 deletions utility/Enc28J60Network.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,11 @@ class Enc28J60Network : public MemoryPool
{

private:
uint8_t status;
uint16_t nextPacketPtr;
uint8_t bank;

struct memblock receivePkt;

void checkDMA();

uint8_t readOp(uint8_t op, uint8_t address);
void writeOp(uint8_t op, uint8_t address, uint8_t data);
uint16_t setReadPtr(memhandle handle, memaddress position, uint16_t len);
Expand Down
4 changes: 4 additions & 0 deletions utility/uipethernet-conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@
#define UIP_CONF_UDP_CONNS 4
#define UIP_UDP_NUMPACKETS 5

/* number of attempts on write before returning number of bytes sent so far
* set to -1 to block until connection is closed by timeout */
#define UIP_ATTEMPTS_ON_WRITE -1

#endif

0 comments on commit 42e788b

Please sign in to comment.