Ejemplo n.º 1
0
/*******************************************************************************
  Function:
    void DRV_WIFI_MacStatsGet(DRV_WIFI_MAC_STATS *p_macStats)

  Summary:
    Gets MAC statistics.

  Description:
    This function gets the various MAC layer stats as maintained by the MRF24WG.

  Parameters:
    p_macStats - Pointer to where MAC statistics are written.  See DRV_WIFI_MAC_STATS
                 structure.

  Returns:
    None.
  *****************************************************************************/
void DRV_WIFI_MacStatsGet(DRV_WIFI_MAC_STATS *p_macStats)
{
    uint32_t *p_value;
    uint8_t  numElements;
    uint8_t  i;
    
    SendGetParamMsg(PARAM_STAT_COUNTERS, (uint8_t *)p_macStats, sizeof(DRV_WIFI_MAC_STATS));
    
    /* calculate number of 32-bit counters in the stats structure and point to first element */
    numElements = sizeof(DRV_WIFI_MAC_STATS) / sizeof(uint32_t);
    p_value = (uint32_t *)p_macStats;
    
    /* correct endianness on all counters in structure */    
    for (i = 0; i < numElements; ++i)
    {
        *p_value = TCPIP_Helper_ntohl(*p_value);
        ++p_value;        
    }    
}
Ejemplo n.º 2
0
// sntp_manager.h
bool TCPIP_SNTP_Client(TCPIP_NET_IF* pNetIf)
{
    NTP_PACKET          pkt;
    uint16_t            w;
    DNS_RESULT          dnsRes;
    static SYS_TICK     SNTPTimer;

    if(pSntpIf != 0 && pNetIf != pSntpIf)
    {   // not our job
        return false;
    }

    switch(sntpState)
    {
        case SM_HOME:
            sntpSocket = INVALID_UDP_SOCKET;
            pSntpIf = pSntpDefIf;
            if(!TCPIP_STACK_NetworkIsLinked(pSntpIf))
            {
                pSntpIf = _TCPIPStackAnyNetLinked(true);
            }

            if(TCPIP_DNS_UsageBegin(pSntpIf) != DNS_RES_OK)
            {
                ntpLastError = SNTP_RES_NTP_DNS_ERR; 
                break;
            }
            TCPIP_DNS_Resolve(NTP_SERVER, ntpConnection ==IP_ADDRESS_TYPE_IPV6 ? DNS_TYPE_AAAA : DNS_TYPE_A);
            sntpState++;
            break;

        case SM_WAIT_DNS:

            dnsRes = TCPIP_DNS_IsResolved(NTP_SERVER, &serverIP);
            if(dnsRes == DNS_RES_PENDING)
            {   // ongoing operation;
                break;
            }
            else if(dnsRes < 0)
            {   // some DNS error occurred; retry after waiting a while
                SNTPTimer = SYS_TICK_Get();
                sntpState = SM_SHORT_WAIT;
                ntpLastError = SNTP_RES_NTP_DNS_ERR; 
            }
            else
            {
                sntpState++;
            }
            TCPIP_DNS_UsageEnd(pSntpIf);
            break;

        case SM_DNS_RESOLVED:

            sntpSocket = TCPIP_UDP_ClientOpen(ntpConnection, NTP_SERVER_PORT, &serverIP);
            if(sntpSocket != INVALID_UDP_SOCKET)
            {
                TCPIP_UDP_SocketNetSet(sntpSocket, pSntpIf);
                sntpState++;
                SNTPTimer = SYS_TICK_Get();
            }
            else
            {
                ntpLastError = SNTP_RES_SKT_ERR; 
            }
            break;

        case SM_UDP_IS_OPENED:
            if(TCPIP_UDP_IsOpened(sntpSocket) == true)
            {
                SNTPTimer = SYS_TICK_Get();
                sntpState = SM_UDP_SEND;
            }
            else if((SYS_TICK_Get() - SNTPTimer > 1*SYS_TICK_TicksPerSecondGet()))
            {   // failed to open
                TCPIP_UDP_Close(sntpSocket);
                sntpState = SM_DNS_RESOLVED;
                sntpSocket = INVALID_UDP_SOCKET;
                ntpLastError = SNTP_RES_SKT_ERR; 
            }
            break;

        case SM_UDP_SEND:
            // Open up the sending UDP socket
            // Make certain the socket can be written to
            if(!TCPIP_UDP_TxPutIsReady(sntpSocket, sizeof(pkt)))
            {   // Wait no more than 1 sec
                if((SYS_TICK_Get() - SNTPTimer > 1*SYS_TICK_TicksPerSecondGet()))
                {
                    TCPIP_UDP_Close(sntpSocket);
                    sntpState = SM_DNS_RESOLVED;
                    sntpSocket = INVALID_UDP_SOCKET;
                    ntpLastError = SNTP_RES_SKT_ERR; 
                    break;
                }
            }

            // Success
            // Transmit a time request packet
            memset(&pkt, 0, sizeof(pkt));
            pkt.flags.versionNumber = NTP_VERSION;
            pkt.flags.mode = 3;             // NTP Client
            pkt.orig_ts_secs = TCPIP_Helper_htonl(NTP_EPOCH);
            TCPIP_UDP_ArrayPut(sntpSocket, (uint8_t*) &pkt, sizeof(pkt));
            TCPIP_UDP_Flush(sntpSocket);

            SNTPTimer = SYS_TICK_Get();
            sntpState = SM_UDP_RECV;
            break;

        case SM_UDP_RECV:
            // Look for a response time packet
            if(!TCPIP_UDP_GetIsReady(sntpSocket))
            {
                if((SYS_TICK_Get()) - SNTPTimer > NTP_REPLY_TIMEOUT * SYS_TICK_TicksPerSecondGet())
                {
                    // Abort the request and resume
                    TCPIP_UDP_Close(sntpSocket);
                    //SNTPTimer = SYS_TICK_Get();
                    //sntpState = SM_SHORT_WAIT;
                    sntpState = SM_HOME;
                    sntpSocket = INVALID_UDP_SOCKET;
                    ntpLastError = SNTP_RES_NTP_SERVER_TMO; 
                }
                break;
            }

            // Get the response time packet
            w = TCPIP_UDP_ArrayGet(sntpSocket, (uint8_t*) &pkt, sizeof(pkt));
            TCPIP_UDP_Close(sntpSocket);
            SNTPTimer = SYS_TICK_Get();
            sntpState = SM_WAIT;
            sntpSocket = INVALID_UDP_SOCKET;

            // sanity packet check
            if(w != sizeof(pkt) || pkt.flags.versionNumber != NTP_VERSION )
            {
                ntpLastError = SNTP_RES_NTP_VERSION_ERR; 
                break;
            }
            if((pkt.tx_ts_secs == 0 && pkt.tx_ts_fraq == 0))
            {
                ntpLastError = SNTP_RES_NTP_TSTAMP_ERR; 
                break;
            }
            if(pkt.stratum == 0 )
            {
                ntpLastError = SNTP_RES_NTP_KOD_ERR; 
                break;
            }
            if(pkt.stratum >= NTP_MAX_STRATUM || pkt.flags.leapIndicator == 3 )
            {
                ntpLastError = SNTP_RES_NTP_SYNC_ERR; 
                break;
            }

            // get the last timestamp
            ntpTimeStamp.tStampSeconds = pkt.tx_ts_secs;
            ntpTimeStamp.tStampFraction = pkt.tx_ts_fraq;
            ntpLastStampTick = SYS_TICK_Get();
            
            // Set out local time to match the returned time
            dwLastUpdateTick = ntpLastStampTick;
            dwSNTPSeconds = TCPIP_Helper_ntohl(pkt.tx_ts_secs) - NTP_EPOCH;
            // Do rounding.  If the partial seconds is > 0.5 then add 1 to the seconds count.
            if(((uint8_t*)&pkt.tx_ts_fraq)[0] & 0x80)
                dwSNTPSeconds++;

            break;

        case SM_SHORT_WAIT:
            // Attempt to requery the NTP server after a specified NTP_FAST_QUERY_INTERVAL time (ex: 8 seconds) has elapsed.
            if(SYS_TICK_Get() - SNTPTimer > (NTP_FAST_QUERY_INTERVAL * SYS_TICK_TicksPerSecondGet()))
            {
                sntpState = SM_HOME;
                sntpSocket = INVALID_UDP_SOCKET;
            }
            break;

        case SM_WAIT:
            // Requery the NTP server after a specified NTP_QUERY_INTERVAL time (ex: 10 minutes) has elapsed.
            if(SYS_TICK_Get() - SNTPTimer > (NTP_QUERY_INTERVAL * SYS_TICK_TicksPerSecondGet()))
            {
                sntpState = SM_HOME;
                sntpSocket = INVALID_UDP_SOCKET;
            }

            break;
    }

    return true;

}//TCPIP_SNTP_Client
Ejemplo n.º 3
0
static void TCPIP_ZCLL_Process(void)
{
    int netIx;
    ZCLL_NET_HANDLE *hZcll;
    TCPIP_NET_IF*   pNetIf;
    int     zgzc_action;
    IPV4_ADDR zeroAdd = {0};
#if defined(TCPIP_ZC_INFO_ZCLL) || defined(TCPIP_ZC_DEBUG_ZCLL)
    char zeroconf_dbg_msg[256];
#endif

    for(netIx = 0; netIx < TCPIP_STACK_NumberOfNetworksGet(); netIx++)
    {

        hZcll = phZCLL + netIx;
        pNetIf = (TCPIP_NET_IF*)TCPIP_STACK_IndexToNet(netIx);


        if(hZcll->zcll_state == SM_INIT)
        {   // nothing to do in this state
            continue;
        }

        if(!TCPIP_STACK_NetworkIsLinked(pNetIf))
        {   // lost connection; re-start
            hZcll->zcll_state = SM_ADDR_INIT;
            TCPIP_STACK_AddressServiceEvent(pNetIf, TCPIP_STACK_ADDRESS_SERVICE_ZCLL, TCPIP_STACK_ADDRESS_SERVICE_EVENT_CONN_LOST);
        }

        switch(hZcll->zcll_state)
        {
            case SM_ADDR_INIT:
                /* Not yet seeded in init routine */
                /* setup random number generator
                 * we key this off the MAC-48 HW identifier
                 * the first 3 octets are the manufacturer
                 * the next 3 the serial number
                 * we'll use the last four for the largest variety
                 */

                hZcll->conflict_count = 0;
                _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true);
                hZcll->probe_count = 0;

                hZcll->zcll_state = SM_ADDR_PROBE;
                INFO_ZCLL_PRINT("ADDR_INIT --> ADDR_PROBE \r\n");

                // No break. Fall through

            case SM_ADDR_PROBE:

                zgzc_action = zgzc_wait_for(&hZcll->random_delay, &hZcll->event_time, &hZcll->time_recorded);

                if(zgzc_action == ZGZC_STARTED_WAITING)
                {

                    if (hZcll->probe_count == 0)
                    {
                        // First probe. Wait for [0 ~ PROBE_WAIT] seconds before sending the probe.

                        hZcll->random_delay = (_zcll_rand() % (PROBE_WAIT * SYS_TMR_TickCounterFrequencyGet()));
                        DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"PROBE_WAIT Random Delay [%d]: %ld secs \r\n",
                                hZcll->probe_count,
                                hZcll->random_delay);
                    }
                    else if (hZcll->probe_count < PROBE_NUM)
                    {
                        // Subsequent probes. Wait for [PROBE_MIN ~ PROBE_MAX] seconds before sending the probe.

                        hZcll->random_delay = ( (_zcll_rand() % ((PROBE_MAX-PROBE_MIN) * SYS_TMR_TickCounterFrequencyGet()) ) +
                                (PROBE_MIN * SYS_TMR_TickCounterFrequencyGet()) );

                        DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"PROBE Random Delay [%d]: %ld ticks \r\n",
                                hZcll->probe_count,
                                hZcll->random_delay);
                    }
                    else
                    {
                        // Completed PROBE_NUM of probes. Now wait for ANNOUNCE_WAIT seconds to determine if
                        // we can claim it.

                        hZcll->random_delay = (ANNOUNCE_WAIT * SYS_TMR_TickCounterFrequencyGet());
                        DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE_WAIT delay [%d]: %ld ticks\r\n",
                                hZcll->probe_count,
                                hZcll->random_delay /*SYS_TMR_TickCounterFrequencyGet() */);
                    }

                    DEBUG0_ZCLL_PRINT((char*)zeroconf_dbg_msg);
                    break;
                }
                else if(zgzc_action == ZGZC_STARTED_WAITING)
                {   // Not Completed the delay proposed
                    break;
                }

                // Completed the delay required

                DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"   delay: %ld ticks " \
                        "completed \r\n", hZcll->random_delay);
                DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg);

                if(hZcll->zcll_flags.probe_conflict)
                {
                    /* Conflict with selected address */
                    INFO_ZCLL_PRINT("Probe Conflict-1 Detected. Need to select diff addr \r\n");
                    hZcll->temp_IP_addr.Val = 0x0;

                    hZcll->conflict_count++;
                    _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true);
                }
                else if((hZcll->conflict_count == 0) &&
                        hZcll->temp_IP_addr.Val      &&
                        pNetIf->netIPAddr.Val != 0x0 &&
                        (TCPIP_ARP_IsResolved(pNetIf,&hZcll->temp_IP_addr, &hZcll->temp_MAC_addr)) )
                {
                    if(!memcmp (&hZcll->temp_MAC_addr, &pNetIf->netMACAddr, 6) )
                    {
                        DEBUG0_ZCLL_PRINT("SM_ADDR_PROBE: Resolved with our address only. " \
                                "Rare Case !!!! \r\n");
                    }
                    else
                    {
                        /* Conflict with selected address */
                        INFO_ZCLL_PRINT("Probe Conflict-2 Detected. Need to select diff addr \r\n");
                        hZcll->temp_IP_addr.Val = 0x0;

                        hZcll->conflict_count++;
                        _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true);
                    }
                }

                if ((hZcll->zcll_flags.probe_conflict == 1) ||
                        (!hZcll->bDefaultIPTried))
                {
                    /*
                     * Pick random IP address in IPv4 link-local range
                     * 169.254.1.0/16 is the allowed address range however
                     * 169.254.0.0/24 and 169.254.255.0/24 must be excluded,
                     * which removes 512 address from our 65535 candidates.
                     * That leaves us with 65023 (0xfdff).
                     * The link-local address must start with 169.254.#.#
                     * If it does not then assign it the default value of
                     169.254.1.2 and send out probe.
                     */
                    hZcll->probe_count = 0;

                    if(!hZcll->bDefaultIPTried)
                    {
                        // First probe, and the default IP is a valid IPV4_SOFTAP_LLBASE address.
                        if (((!hZcll->bDefaultIPTried)          &&
                                    (pNetIf->DefaultIPAddr.v[0] != 169)) ||
                                ((pNetIf->DefaultIPAddr.v[1] != 254) &&
                                 (pNetIf->DefaultIPAddr.v[2] != 0)   &&
                                 (pNetIf->DefaultIPAddr.v[3] != 255)))
                        {

                            WARN_ZCLL_MESG(zeroconf_dbg_msg,"\r\n%d.%d.%d.%d not a valid link local addess. "
                                    "Autogenerating address.\r\n"
                                    ,pNetIf->DefaultIPAddr.v[0],pNetIf->DefaultIPAddr.v[1]
                                    ,pNetIf->DefaultIPAddr.v[2],pNetIf->DefaultIPAddr.v[3]);
                            WARN_ZCLL_PRINT((char *)zeroconf_dbg_msg);
                            // First probe, if the default IP is a valid IPv4 LL then use it.
                            hZcll->temp_IP_addr.Val = (IPV4_LLBASE | ((abs(_zcll_rand()) % 0xfdff) ));
                            hZcll->bDefaultIPTried = 1;
                        }
                        else
                        {
                            hZcll->temp_IP_addr.Val = TCPIP_Helper_ntohl(pNetIf->DefaultIPAddr.Val);
                        }

                        hZcll->bDefaultIPTried = 1;
                    }
                    else
                    {
                        hZcll->temp_IP_addr.Val = (IPV4_LLBASE | ((abs(_zcll_rand()) % 0xfdff) ));
                    }

                    INFO_ZCLL_MESG(zeroconf_dbg_msg,"Picked IP-Addr [%d]: %d.%d.%d.%d \r\n",
                            hZcll->probe_count,
                            hZcll->temp_IP_addr.v[3],hZcll->temp_IP_addr.v[2],
                            hZcll->temp_IP_addr.v[1],hZcll->temp_IP_addr.v[0]);
                    INFO_ZCLL_PRINT((char *)zeroconf_dbg_msg);

                    hZcll->temp_IP_addr.Val = TCPIP_Helper_ntohl((uint32_t) hZcll->temp_IP_addr.Val);
                }

                if((hZcll->zcll_flags.probe_conflict == 1) || (hZcll->probe_count < PROBE_NUM))
                {

                    hZcll->zcll_flags.probe_conflict = 0;

                    TCPIP_ZCLL_ARPAction( pNetIf
                            , &pNetIf->netIPAddr
                            , &hZcll->temp_IP_addr
                            , ARP_OPERATION_REQ | ARP_OPERATION_CONFIGURE
                            , ZCLL_ARP_PROBE);
                    hZcll->probe_count++;

                    DEBUG0_ZCLL_MESG(zeroconf_dbg_msg, "Sending ARP [%d]\r\n", hZcll->probe_count);
                    DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg);

                    break;
                }

                // No conflict detected ...

                if(hZcll->probe_count >= PROBE_NUM)
                {
                    hZcll->zcll_state = SM_ADDR_CLAIM;
                    hZcll->bDefaultIPTried = 0;

                    INFO_ZCLL_PRINT("ADDR_PROBE --> ADDR_CLAIM \r\n");
                }

                break;

            case SM_ADDR_CLAIM:

                zgzc_action = zgzc_wait_for( &hZcll->random_delay, &hZcll->event_time, &hZcll->time_recorded);

                if(zgzc_action == ZGZC_STARTED_WAITING)
                {
                    if (hZcll->bDefaultIPTried == 0)
                    {
                        // First announcement is immediate. We have passed the ANNOUNCE_WAIT in
                        // PROBE state already.

                        hZcll->random_delay = 0;
                    }
                    else
                    {
                        // Subsequent announcements need to wait ANNOUNCE_INTERVAL seconds
                        // before sending the announcement.

                        hZcll->random_delay = (ANNOUNCE_INTERVAL * SYS_TMR_TickCounterFrequencyGet());
                    }
                    break;
                }
                else if(zgzc_action == ZGZC_KEEP_WAITING)
                {   // Not Completed the delay proposed
                    break;
                }

                // Completed the delay required

                DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE delay: %ld ticks completed \r\n", hZcll->random_delay);
                DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg);

                if ( hZcll->bDefaultIPTried < ANNOUNCE_NUM )
                {
                    TCPIP_ZCLL_ARPAction(pNetIf,&hZcll->temp_IP_addr,&hZcll->temp_IP_addr, ARP_OPERATION_REQ | ARP_OPERATION_CONFIGURE, ZCLL_ARP_CLAIM);
                    (hZcll->bDefaultIPTried)++;

                    DEBUG0_ZCLL_MESG(zeroconf_dbg_msg, "Sending ANNOUNCEMENT [%d]\r\n", hZcll->bDefaultIPTried);
                    DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg);
                }
                else
                {
                    // Claim it. Goto DEFEND state
                    IPV4_ADDR   zcllMask;
                    zcllMask.Val = IPV4_LLBASE_MASK;
                    _TCPIPStackSetConfigAddress(pNetIf, &hZcll->temp_IP_addr, &zcllMask, false);
                    hZcll->zcll_state = SM_ADDR_DEFEND;
                    INFO_ZCLL_MESG(zeroconf_dbg_msg,"\r\n******** Taken IP-Addr: " \
                            "%d.%d.%d.%d ******** \r\n",
                            pNetIf->netIPAddr.v[0],pNetIf->netIPAddr.v[1],
                            pNetIf->netIPAddr.v[2],pNetIf->netIPAddr.v[3]);
                    INFO_ZCLL_PRINT((char *)zeroconf_dbg_msg);
                    INFO_ZCLL_PRINT("ADDR_CLAIM --> ADDR_DEFEND \r\n");
                }

                break;

            case SM_ADDR_DEFEND:

                if( hZcll->zcll_flags.late_conflict)
                {
                    if (!hZcll->zcll_flags.defended)
                    {
                        hZcll->zcll_flags.late_conflict = 0;
                        INFO_ZCLL_PRINT("CONFLICT DETECTED !!! \r\n");

                        INFO_ZCLL_PRINT("Defending the Self Address once \r\n");
                        TCPIP_ZCLL_ARPAction( pNetIf
                                ,&pNetIf->netIPAddr
                                ,&pNetIf->netIPAddr
                                ,ARP_OPERATION_RESP | ARP_OPERATION_CONFIGURE
                                ,ZCLL_ARP_DEFEND);

                        hZcll->zcll_flags.defended = true;
                    }
                    else
                    {
                        // We are not allowed to defend another conflict during an active defended period

                        INFO_ZCLL_PRINT("Releasing the IP-Address because of multiple Conflicts \r\n");

                        hZcll->zcll_state = SM_ADDR_RELEASE;

                        hZcll->zcll_flags.defended = false;
                        hZcll->event_time = false;
                        hZcll->random_delay = false;

                        INFO_ZCLL_PRINT("ADDR_DEFEND --> ADDR_RELEASE \r\n");
                        break;
                    }
                }

                if (hZcll->zcll_flags.defended)
                {
                    zgzc_action = zgzc_wait_for(&hZcll->random_delay, &hZcll->event_time, &hZcll->time_recorded);

                    if(zgzc_action == ZGZC_STARTED_WAITING)
                    {
                        hZcll->random_delay = (DEFEND_INTERVAL * SYS_TMR_TickCounterFrequencyGet());
                        DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"DEFEND_INTERVAL Delay : %ld ticks\r\n",
                                hZcll->random_delay/*SYS_TMR_TickCounterFrequencyGet() */);
                        DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg);

                        break; 
                    }
                    else if(zgzc_action == ZGZC_KEEP_WAITING)
                    {   // Not Completed the delay proposed
                        break;
                    }

                    // Completed the delay required

                    DEBUG0_ZCLL_MESG(zeroconf_dbg_msg,"ANNOUNCE delay: %ld ticks " \
                            "completed \r\n", hZcll->random_delay);
                    DEBUG0_ZCLL_PRINT((char *)zeroconf_dbg_msg);

                    hZcll->zcll_flags.defended = false;
                }

                break;

            case SM_ADDR_RELEASE:

                INFO_ZCLL_PRINT("ADDR_RELEASE --> ADDR_INIT\r\n");

                _TCPIPStackSetConfigAddress(pNetIf, &zeroAdd, &zeroAdd, true);

                // Need New Addr
                hZcll->temp_IP_addr.Val = (IPV4_LLBASE | ((abs(_zcll_rand()) % 0xfdff) ));
                hZcll->temp_IP_addr.Val = TCPIP_Helper_ntohl((uint32_t) hZcll->temp_IP_addr.Val);

                hZcll->zcll_state = SM_ADDR_INIT;
                hZcll->time_recorded = false;
                hZcll->zcll_flags.defended      = false;
                hZcll->event_time    = false;
                break;

            default:
                break;
        }

    }

}