Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

ip6/icmp/ndp/rs.cpp

Committer:
andrewboyson
Date:
2017-10-24
Revision:
46:40d33e9037e4
Child:
47:73af5c0b0dc2

File content as of revision 46:40d33e9037e4:

#include "mbed.h"
#include "log.h"
#include "net.h"
#include "ndp.h"
#include "ip6.h"
#include "slaac.h"
#include "clock.h"
#include "action.h"
#include "mac.h"

bool RsTrace = false;

bool go = false;

#define REPEAT_DELAY_TIME 60
static uint32_t delayTime = 10000000; //Reset whenever a message is sent and blocks another send until count exceeds REPEAT_DELAY_TIME

int RsGetWaitingSolicitation(void* pPacket, int* pSize, uint8_t* pType, uint8_t* pCode)
{
    if (!go) return DO_NOTHING;
    go = false;
    
    __packed struct header
    {
        uint32_t  reserved;
    };
    struct header* pHeader = (header*)pPacket;
    pHeader->reserved = 0;
    *pSize = sizeof(struct header);
    *pType = 133; //Router solicitation
    *pCode = 0;

    char* pData = (char*)pHeader + sizeof(struct header);
    char* p = pData;
    
    p += NdpAddOptionSourceMac(p, MacLocal);
    
    *pSize = sizeof(struct header) + p - pData;
    
    if (RsTrace)
    {
        if (NetTraceNewLine) Log("\r\n");
        LogTime("NDP send router solicit\r\n");
        if (NetTraceVerbose)
        {
            Log("RS header\r\n");
            NdpLogOptions(pData, *pSize);
        }
        else
        {
            Log("RS    header\r\n");
        }
    }
    
    return ActionMakeFromDestAndTrace(MULTICAST_ROUTER, RsTrace && NetTraceStack);
    
}

static void checkIfGo()
{
    if (delayTime < REPEAT_DELAY_TIME) return; //Don't retry within the delay time
    
    if (NdpLifetime && NdpElapsedTime < (NdpLifetime >> 1)) return; //Do nothing if within half the life
    
    if (!NdpLifetime || NdpElapsedTime >= NdpLifetime)
    {
        if (RsTrace)
        {
            if (NetTraceNewLine) Log("\r\n");
            LogTime("NDP lifetime has expired: clear global prefix\r\n");
        }
        NdpLifetime = 0;
        Ip6Clear(NdpPrefix);
        SlaacMakeGlobal(NdpPrefix);
        Ip6Clear(NdpDnsServer);
    }
    
    delayTime = 0;
    go = true;
}

void RsMain()
{
    if (ClockTicked)
    {
        NdpElapsedTime++;
        delayTime++;
    }
    checkIfGo();
}