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

net.cpp

Committer:
andrewboyson
Date:
2017-03-12
Revision:
7:b794780e33b4
Parent:
5:5fc4ca9fbf17
Child:
9:91dae5300a4d

File content as of revision 7:b794780e33b4:

#include  "mbed.h"
#include   "phy.h"
#include   "net.h"
#include   "tcp.h"
#include  "dhcp.h"
#include   "arp.h"
#include   "dns.h"
#include "slaac.h"

static void addHexNibble(bool* pAdded, int number, int index, char** pp)
{
    int nibble = number;
    if (index) nibble >>= 4;
    nibble &= 0xF;
    
    if (nibble || *pAdded)
    {
        **pp = nibble < 10 ? nibble + '0' : nibble - 10 + 'a';
        *pp += 1;
        *pAdded = true;
    }
}
int NetIp6AddressToString(char* pIp, int size, char* pText)
{
    char* pIpE = pIp + 16;
    char* p = pText;
    while (true)
    {
        bool added = false;
        if (*pIp || *(pIp + 1))
        {
            if (p > pText + size - 2) break;  addHexNibble(&added, *(pIp + 0), 1, &p);
            if (p > pText + size - 2) break;  addHexNibble(&added, *(pIp + 0), 0, &p);
            if (p > pText + size - 2) break;  addHexNibble(&added, *(pIp + 1), 1, &p);
            if (p > pText + size - 2) break;  addHexNibble(&added, *(pIp + 1), 0, &p);
        }
        
        pIp += 2;
        if (pIp >= pIpE) break;
        
        if (p > pText + size - 2) break; *p++ = ':';
    }
    *p = 0;
    return p - pText;
}
int NetIp4AddressToString(uint32_t ip, int size, char* text)
{
    int a0 = (ip & 0xFF000000) >> 24;
    int a1 = (ip & 0x00FF0000) >> 16;
    int a2 = (ip & 0x0000FF00) >>  8;
    int a3 = (ip & 0x000000FF);
    return snprintf(text, size, "%d.%d.%d.%d", a3, a2, a1, a0); 
}
int NetMacToString(char* mac, int size, char* text)
{
    return snprintf(text, size, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
void NetProtocolToString(uint16_t protocol, int size, char* text)
{
    switch (protocol)
    {
        case ICMP6_PROTOCOL: strncpy (text, "ICMP6", size);        break;
        case   TCP_PROTOCOL: strncpy (text, "TCP"  , size);        break;
        case   UDP_PROTOCOL: strncpy (text, "UDP"  , size);        break;
        default:             snprintf(text, size, "%d", protocol); break;
    }
}

int16_t NetToHost16(int16_t n)
{
    int16_t h;
    
    char* pn = (char*)&n;
    char* ph = (char*)&h + 1;
    
    *ph = *pn; ph--; pn++; // 1<-0
    *ph = *pn;             // 0<-1

    return h;
}

int32_t NetToHost32(int32_t n)
{
    int32_t h;
    
    char* pn = (char*)&n;
    char* ph = (char*)&h + 3;
    
    *ph = *pn; ph--; pn++; // 3<-0
    *ph = *pn; ph--; pn++; // 2<-1
    *ph = *pn; ph--; pn++; // 1<-2
    *ph = *pn;             // 0<-3

    return h;
}
int64_t NetToHost64(int64_t n)
{
    int64_t h;
    
    char* pn = (char*)&n;
    char* ph = (char*)&h + 7;
    
    *ph = *pn; ph--; pn++; // 7<-0
    *ph = *pn; ph--; pn++; // 6<-1
    *ph = *pn; ph--; pn++; // 5<-2
    *ph = *pn; ph--; pn++; // 4<-3
    *ph = *pn; ph--; pn++; // 3<-4
    *ph = *pn; ph--; pn++; // 2<-5
    *ph = *pn; ph--; pn++; // 1<-6
    *ph = *pn;             // 0<-7

    return h;
}
uint16_t onesComplement(uint16_t start, int count, void* pData)
{    
    uint32_t sum = start;                               //Initialise the 32 bit accumulator with the last sum
    uint16_t* p = (uint16_t*)pData;                     //Set up a 16 bit pointer for the data
    
    while(count > 1)
    {
        sum += *p++;                                    // Add each pair of bytes into 32 bit accumulator
        count -= 2;
    }
    if(count) sum += * (uint8_t*) p;                    // Add left-over byte, if any
    while (sum>>16) sum = (sum & 0xffff) + (sum >> 16); // Add any carries from the sum back into the sum to make it ones complement
    return sum;
}
uint16_t NetCheckSumTwo(int count1, void* pData1, int count2, void* pData2)
{
    uint16_t sum = onesComplement(0, count1, pData1);
    return ~onesComplement(sum, count2, pData2);
}
uint16_t NetCheckSum(int count, void* pData)
{
    return ~onesComplement(0, count, pData);
}

static bool ticked()
{
    static time_t lastT = 0;
    time_t thisT = time(NULL);
    bool oneshot = lastT != thisT;
    lastT = thisT;
    return oneshot;
}

int NetInit()
{
    PhyInit();
    TcpInit();
    ArpInit();
    SlaacInit();
    return 0;
}
int NetMain()
{
    PhyMain();
    ArpMain();
    if (ticked())
    {
        DhcpTick();
        ArpTick();
        DnsTick();
    }
    return 0;
}