A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.

Dependents:   oldheating gps motorhome heating

tcp/tcb.cpp

Committer:
andrewboyson
Date:
2017-11-28
Revision:
57:e0fb648acf48
Parent:
52:fbc5a46b5e16

File content as of revision 57:e0fb648acf48:

#include  "mbed.h"
#include   "log.h"
#include   "tcp.h"
#include   "tcb.h"
#include "clock.h"

#define TCB_COUNT 10

#define TIMEOUT_SYN_RECEIVED 2
#define TIMEOUT_ESTABLISHED 20
#define TIMEOUT_CLOSING      2

struct tcb tcbs[TCB_COUNT];

uint32_t TcbGetIsn()
{
    static uint32_t isn = 0;
    isn += 100000; //Gives each tcb 100,000 packets and won't repeat before 42,940 tcbs.
    return isn;
}
struct tcb* TcbGetExisting(uint16_t port)
{
    for (int i = 0; i < TCB_COUNT; i++)
    {
        struct tcb* pTcb = tcbs + i;
        if (pTcb->state != TCB_EMPTY && pTcb->port == port) return pTcb;
    }
    return NULL;
}
struct tcb* TcbGetEmpty()
{
    for (int i = 0; i < TCB_COUNT; i++)
    {
        struct tcb* pTcb = tcbs + i;
        if (pTcb->state == TCB_EMPTY) return pTcb;
    }
    return NULL;
}

uint32_t TcbElapsed = 0;
static void reap()
{
    static struct tcb* pTcb = tcbs;
    
    if (pTcb->state == TCB_EMPTY) return;
    
    uint32_t limit;
    switch (pTcb->state)
    {
        case TCB_SYN_RECEIVED: limit = TIMEOUT_SYN_RECEIVED; break;
        case TCB_ESTABLISHED:  limit = TIMEOUT_ESTABLISHED;  break;
        case TCB_FIN_WAIT:     limit = TIMEOUT_CLOSING;      break;
        case TCB_ACK_WAIT:     limit = TIMEOUT_CLOSING;      break;
    }
    
    if (TcbElapsed - pTcb->elapsed > limit)
    {
        if (TcpTrace) LogTimeF("Reaping TCB %d port %d\r\n", pTcb - tcbs, pTcb->port);
        pTcb->state = TCB_EMPTY;
    }
    
    pTcb++;
    if (pTcb >= tcbs + TCB_COUNT) pTcb = tcbs;
}

void TcbMain()
{
    if (ClockTicked) TcbElapsed++;
    reap();
}
void TcbInit()
{
    for (int i = 0; i < TCB_COUNT; i++) tcbs[i].state = TCB_EMPTY;
}