void SSMWaitForInternet_Tasks(void)
{
    switch(_state)
    {
        case STATE_WAIT_FOR_NETWORK:
            if(APP_ETH_Has_Link())
            {
                SYS_PRINT("INET: Gateway has Ethernet\r\n");
                _changeState(STATE_SETTLE);
            }
            else if(!appWifiData.valid)
            {
                SYS_PRINT("INET: No Ethernet and no WiFi config\r\n");
                _changeState(STATE_AP_ONLY);
            }
            if(APP_WIFI_Has_LinkINFRA())
            {
                SYS_PRINT("INET: Gateway has WiFi\r\n");
                _changeState(STATE_SETTLE);
            }
            break;

        case STATE_AP_ONLY:
            if(APP_ETH_Has_Link())
            {
                _changeState(STATE_WAIT_FOR_NETWORK);
            }
            else if(appWifiData.valid && ((SYS_TMR_TickCountGet() - wifiRetryStartTick) >=
                                          (SYS_TMR_TickCounterFrequencyGet() * WIFI_RETRY_TIMEOUT)))
            { // REVIEW: Use isElapsed kind of function
                if(APP_WIFI_Has_LinkAP())
                {
                    if(firstTimeAPReconnectTimeout)
                    {
                        SYS_PRINT("INET: Not trying to connect to WiFi router again because client is connected (after "
                                  "%d seconds)\r\n",
                                  (SYS_TMR_TickCountGet() - wifiRetryStartTick) / SYS_TMR_TickCounterFrequencyGet());
                        firstTimeAPReconnectTimeout = false;
                    }
                }
                else
                {
                    SYS_PRINT("INET: Trying to connect to WiFi router again (after %d seconds)\r\n",
                              (SYS_TMR_TickCountGet() - wifiRetryStartTick) / SYS_TMR_TickCounterFrequencyGet());
                    _changeState(STATE_WAIT_FOR_NETWORK);
                }
            }
            break;

        case STATE_SETTLE:
            if((SYS_TMR_TickCountGet() - settleStartTick) >= (SYS_TMR_TickCounterFrequencyGet() * 5))
            {
                _changeState(STATE_PING_PROBE);
            }
            break;

        case STATE_PING_PROBE:
            if(!ping_probe_sent)
            {
                IPV4_ADDR googledns = {0};
                googledns.v[0]      = 8;
                googledns.v[1]      = 8;
                googledns.v[2]      = 4;
                googledns.v[3]      = 4;

                ping_probe_reply_received = false;

                SYS_PRINT("INET: Ping probe\r\n");
                if(TCPIP_ICMP_EchoRequestSend(TCPIP_STACK_IndexToNet(WIFI_INTERFACE_NUM), &googledns, 0, 0x1234) !=
                   ICMP_ECHO_OK)
                {
                    SYS_PRINT("INET: Error sending probe on WiFi\r\n");
                }
                if(TCPIP_ICMP_EchoRequestSend(TCPIP_STACK_IndexToNet(ETH_INTERFACE_NUM), &googledns, 0, 0x1234) !=
                   ICMP_ECHO_OK)
                {
                    SYS_PRINT("INET: Error sending probe on Eth\r\n");
                }
                ping_probe_sent = true;
            }
            else if(ping_probe_reply_received)
            {
                SYS_PRINT("INET: Ping response from %s, set as default\r\n",
                          TCPIP_STACK_NetNameGet(TCPIP_STACK_NetDefaultGet()));
                if(ntpEverSynchronized)
                {
                    _changeState(STATE_DONE);
                }
                else
                {
                    _changeState(STATE_WAIT_FOR_NTP);
                }
                break;
            }
            else
            {
                if((SYS_TMR_TickCountGet() - pingStartTick) >=
                   (SYS_TMR_TickCounterFrequencyGet() * PING_TIMEOUT)) // REVIEW: Use isElapsed kind of function
                {
                    SYS_PRINT("INET: Ping Timeout of :%d seconds\r\n", PING_TIMEOUT);
                    pingStartTick             = SYS_TMR_TickCountGet();
                    ping_probe_sent           = false;
                    ping_probe_reply_received = false;
                    if(ping_retry >= PING_RETRIES)
                    {
                        // TODO: find a proper recovery -> _changeState(STATE_WAIT_FOR_NETWORK);
                        RebootWithMessage("Ping timeout %d retries, rebooting", PING_RETRIES);    
                        
                    }
                    ping_retry++;
                }
            }
            break;

        case STATE_WAIT_FOR_NTP:
        {
            uint32_t lastUpdate = 0;
            TCPIP_SNTP_TimeStampGet(NULL, &lastUpdate);
            if(lastUpdate != 0)
            { // If at least once NTP succeeded
                ntpEverSynchronized = true;
                _changeState(STATE_DONE);
            }
            else
            {
                if((SYS_TMR_TickCountGet() - ntpStartTick) >= (SYS_TMR_TickCounterFrequencyGet() * NTP_TIMEOUT))
                { // REVIEW: Use isElapsed kind of function
                    SYS_PRINT("INET: Not received any NTP response. Wait for network again (after %d seconds).\r\n",
                              (SYS_TMR_TickCountGet() - ntpStartTick) / SYS_TMR_TickCounterFrequencyGet());
                    _changeState(STATE_WAIT_FOR_NETWORK);
                }
                else if(TCPIP_SNTP_ConnectionInitiate() == SNTP_RES_OK)
                {
                    SYS_PRINT("INET: Initiated NTP request.\r\n");
                }
            }
            break;
        }

        case STATE_DONE:
            break;
    }
}
Exemplo n.º 2
0
void TCPIPCommandsTask(void)
{
    ICMP_ECHO_RESULT echoRes;
    DNS_RESULT  dnsRes;
    bool killIcmp = false;

    switch(icmpCmdStat)
    {
        case TCPIP_PING_CMD_DNS_GET:

            dnsRes = TCPIP_DNS_UsageBegin(0);
            if(dnsRes == DNS_RES_OK)
            {
                TCPIP_DNS_Resolve(icmpTargetHost, DNS_TYPE_A);
                icmpCmdStat = TCPIP_PING_CMD_DNS_WAIT;
            }
            else if(dnsRes != DNS_RES_BUSY)
            {   // some other error
                (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: DNS failure for %s\r\n", icmpTargetHost);
                killIcmp = true;
            }
            // else wait some more
            break;

        case TCPIP_PING_CMD_DNS_WAIT:
            dnsRes = TCPIP_DNS_IsResolved(icmpTargetHost, &icmpTargetAddr);
            if(dnsRes == DNS_RES_OK || dnsRes < 0)
            {
                TCPIP_DNS_UsageEnd(0);

                if(dnsRes == DNS_RES_OK)
                {

                    TCPIP_Helper_IPAddressToString(&icmpTargetAddr, icmpTargetAddrStr, sizeof(icmpTargetAddrStr));
                    icmpCmdStat = TCPIP_PING_CMD_DO_PING;
                }
                else
                {
                    (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: DNS failure for %s\r\n", icmpTargetHost);
                    killIcmp = true;
                }
            }
            // else (dnsRes > 0 ); wait some more
            break;


        case TCPIP_PING_CMD_DO_PING:
            if(icmpReqCount != 0 && icmpAckRecv == 0)
            {   // no reply received; 
                if(SYS_TICK_Get() - icmpStartTick > (SYS_TICK_ResolutionGet() * TCPIP_STACK_COMMANDS_ICMP_ECHO_TIMEOUT) / 1000)
                {   // timeout
                    (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: request timeout.\r\n");
                    killIcmp = true;
                    break;
                }
                // else wait some more
            }

            if(icmpReqCount == icmpReqNo)
            {   // no more requests to send
                killIcmp = true;
                break;
            }

            // send another request
            echoRes = TCPIP_ICMP_EchoRequestSend (&icmpTargetAddr, ++icmpSequenceNo, icmpIdentifier);

            if(echoRes >= 0 )
            {
                icmpStartTick = SYS_TICK_Get();
                if(icmpReqCount++ == 0)
                {
                    (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: request sent to: %s [%s]\r\n", icmpTargetHost, icmpTargetAddrStr);
                }
            }
            else
            {
                (*pIcmpCmd->pCmdApi->print)(icmpCmdIoParam, "Ping: failed to send request to: %s\r\n", icmpTargetAddrStr);
                killIcmp = true;
            }

            break;

        default:
            killIcmp = true;
            break;

    }

    if(killIcmp)
    {
        _PingStop(pIcmpCmd, icmpCmdIoParam);
    }

}