Exemplo n.º 1
0
void TCPIP_ANNOUNCE_Send(void)
{
    UDP_SOCKET  announceSocket;
    uint16_t    dataLen;
    uint16_t    minimumDataLen;
    uint16_t    txLen;
    bool truncated;
    TCPIP_NET_IF *pNetIf;
    const char* interfaceName;
    ANNOUNCE_FIELD_PAYLOAD payloadType;
    int         netIx;
    uint16_t terminatorLen = strlen ((const char *)announceFieldTerminator);

#if defined (TCPIP_STACK_USE_IPV6)
    IPV6_INTERFACE_CONFIG*  pIpv6Config;
    IPV6_ADDR_STRUCT * addressPointer;
    IPV6_HEAP_NDP_DR_ENTRY *defaultRouter;
    IPV6_ADDR *pGatewayAddr;
#endif

    // create the socket
    announceSocket = TCPIP_UDP_ClientOpen(IP_ADDRESS_TYPE_IPV4, TCPIP_ANNOUNCE_PORT, 0);

    if (announceSocket == INVALID_UDP_SOCKET)
    {   // keep the request pending, we'll try next time
        return;
    }

    for(netIx = 0; netIx < announceIfs; netIx++)
    {
        // reply to the request on the interface it arrived on
        if((announceRequestMask & (1 << netIx)) != 0)
        {
            pNetIf = (TCPIP_NET_IF*)TCPIP_STACK_IndexToNet(netIx);

            if(TCPIP_STACK_NetworkIsLinked(pNetIf))
            {   // reply only if this interface is up and running

                TCPIP_UDP_SocketNetSet (announceSocket, pNetIf);
                TCPIP_UDP_BcastIPV4AddressSet(announceSocket, UDP_BCAST_NETWORK_DIRECTED, pNetIf);

#if defined (TCPIP_STACK_USE_IPV6)
                pIpv6Config = TCPIP_IPV6_InterfaceConfigGet(pNetIf);
#endif

                interfaceName = TCPIP_STACK_MACIdToString(pNetIf->macId);

                truncated = false;

                dataLen = ((terminatorLen + 1) * 4) + sizeof (IPV4_ADDR) + sizeof (TCPIP_MAC_ADDR);

                dataLen += strlen(interfaceName); 
                dataLen += strlen((char *)pNetIf->NetBIOSName);

                minimumDataLen = dataLen + 1 + terminatorLen;


#if defined (TCPIP_STACK_USE_IPV6)
                addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6UnicastAddresses.head;

                while(addressPointer != NULL)
                {
                    dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen;
                    addressPointer = addressPointer->next;
                }

                addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6MulticastAddresses.head;

                while(addressPointer != NULL)
                {
                    dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen;
                    addressPointer = addressPointer->next;
                }

                defaultRouter = pIpv6Config->currentDefaultRouter;
                while(defaultRouter != NULL)
                {
                    dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen;
                    defaultRouter = defaultRouter->next;
                }
                // For IPV6 gateway address
                dataLen += sizeof (IPV6_ADDR) + 1 + terminatorLen;
#endif

                if (dataLen > ANNOUNCE_MAX_PAYLOAD)
                {
                    dataLen = ANNOUNCE_MAX_PAYLOAD;
                }

                if ((txLen = TCPIP_UDP_TxPutIsReady(announceSocket, dataLen)) < dataLen)
                {
                    truncated = true;
                    if ((txLen = TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen)) < minimumDataLen)
                    {
                        TCPIP_UDP_Close (announceSocket);
                        return;
                    }
                }

                // Put Mac Address
                payloadType = ANNOUNCE_FIELD_MAC_ADDR;
                TCPIP_UDP_Put (announceSocket, payloadType);
                TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&pNetIf->netMACAddr, sizeof (TCPIP_MAC_ADDR));
                TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);

                if (truncated)
                {
                    payloadType = ANNOUNCE_FIELD_TRUNCATED;
                    TCPIP_UDP_Put (announceSocket, payloadType);
                    TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);
                }

                // Put Mac Type
                payloadType = ANNOUNCE_FIELD_MAC_TYPE;
                TCPIP_UDP_Put (announceSocket, payloadType);
                TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)interfaceName, strlen (interfaceName));
                TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);

                // Put Host Name
                payloadType = ANNOUNCE_FIELD_HOST_NAME;
                TCPIP_UDP_Put (announceSocket, payloadType);
                TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&pNetIf->NetBIOSName, strlen((char*)pNetIf->NetBIOSName));
                TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);

                // Put IPv4 Address
                payloadType = ANNOUNCE_FIELD_IPV4_ADDRESS;
                TCPIP_UDP_Put (announceSocket, payloadType);
                TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&pNetIf->netIPAddr, sizeof (IPV4_ADDR));
                TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);

#if defined (TCPIP_STACK_USE_IPV6)

                // Put IPv6 unicast addresses
                minimumDataLen = sizeof (IPV6_ADDR) + 1 + terminatorLen;

                addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6UnicastAddresses.head;

                payloadType = ANNOUNCE_FIELD_IPV6_UNICAST;

                while(addressPointer != NULL && (TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen) >= minimumDataLen))
                {
                    TCPIP_UDP_Put (announceSocket, payloadType);
                    TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&addressPointer->address, sizeof (IPV6_ADDR));
                    TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);
                    addressPointer = addressPointer->next;
                }

                // Put IPv6 multicast listeners    
                addressPointer = (IPV6_ADDR_STRUCT *)pIpv6Config->listIpv6MulticastAddresses.head;

                payloadType = ANNOUNCE_FIELD_IPV6_MULTICAST;

                while(addressPointer != NULL && (TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen) >= minimumDataLen))
                {
                    TCPIP_UDP_Put (announceSocket, payloadType);
                    TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&addressPointer->address, sizeof (IPV6_ADDR));
                    TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);
                    addressPointer = addressPointer->next;
                }
                
                defaultRouter = pIpv6Config->currentDefaultRouter;
                payloadType = ANNOUNCE_FIELD_IPV6_DEFAULT_ROUTER;
                while(defaultRouter != NULL && (TCPIP_UDP_TxPutIsReady(announceSocket, minimumDataLen) >= minimumDataLen))
                {
                    TCPIP_UDP_Put (announceSocket, payloadType);
                    TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)&defaultRouter->neighborInfo->remoteIPAddress, sizeof (IPV6_ADDR));
                    TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);
                    defaultRouter = defaultRouter->next;
                }

                pGatewayAddr = (IPV6_ADDR*)TCPIP_STACK_NetDefaultIPv6GatewayGet(pNetIf);
                if(pGatewayAddr)
                {
                    payloadType = ANNOUNCE_FIELD_IPV6_DEFAULT_GATEWAY;
                    TCPIP_UDP_Put (announceSocket, payloadType);
                    TCPIP_UDP_ArrayPut(announceSocket, (const uint8_t *)pGatewayAddr, sizeof (IPV6_ADDR));
                    TCPIP_UDP_ArrayPut (announceSocket, announceFieldTerminator, terminatorLen);
                }

#endif

                TCPIP_UDP_Flush (announceSocket);
            }

            announceRequestMask &= ~(1 << netIx);   // clear requests on this interface
        }
    }


    TCPIP_UDP_Close (announceSocket);
}
Exemplo 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
Exemplo n.º 3
0
Arquivo: app.c Projeto: ctapang/v0_70b
void APP_Tasks( void )
{
    static IPV4_ADDR dwLastIP[2] = { {-1}, {-1} };
    IPV4_ADDR           ipAddr;
    int i;

    switch(appData.state)
    {

        case APP_TCPIP_WAIT_FOR_IP:

            // if the IP address of an interface has changed
            // display the new value on the system console
            nNets = TCPIP_STACK_NumberOfNetworksGet();

            for (i = 0; i < nNets; i++)
            {
                netH = TCPIP_STACK_IndexToNet(i);
                ipAddr.Val = TCPIP_STACK_NetAddress(netH);
                if(dwLastIP[i].Val != ipAddr.Val)
                {
                    dwLastIP[i].Val = ipAddr.Val;

                    SYS_CONSOLE_MESSAGE(TCPIP_STACK_NetNameGet(netH));
                    SYS_CONSOLE_MESSAGE(" IP Address: ");
                    SYS_CONSOLE_PRINT("%d.%d.%d.%d \r\n", ipAddr.v[0], ipAddr.v[1], ipAddr.v[2], ipAddr.v[3]);
                    if (ipAddr.v[0] != 0 && ipAddr.v[0] != 169) // Wait for a Valid IP
                    {
                        appData.state = APP_TCPIP_WAITING_FOR_COMMAND;
                        SYS_CONSOLE_MESSAGE("Waiting for command type: sendudppacket\r\n");
                    }
                }
            }
            break;
        case APP_TCPIP_WAITING_FOR_COMMAND:
        {
            if (APP_Send_Packet)
            {
                APP_Send_Packet = false;
                DNS_RESULT result = TCPIP_DNS_UsageBegin(0);
                if (result != DNS_RES_OK)
                {
                    SYS_CONSOLE_MESSAGE("Error in DNS aborting 1\r\n");
                    break;
                }
                result = TCPIP_DNS_Resolve(APP_Hostname_Buffer, DNS_TYPE_A);
                if (result != DNS_RES_OK)
                {
                    SYS_CONSOLE_MESSAGE("Error in DNS aborting 2\r\n");
                    TCPIP_DNS_UsageEnd(0);
                    break;
                }
                appData.state = APP_TCPIP_WAIT_ON_DNS;
            }
        }
        break;

        case APP_TCPIP_WAIT_ON_DNS:
        {
            IPV4_ADDR addr;
            switch (_APP_PumpDNS(APP_Hostname_Buffer, &addr))
            {
                case -1:
                {
                    // Some sort of error, already reported
                    appData.state = APP_TCPIP_WAITING_FOR_COMMAND;
                }
                break;
                case 0:
                {
                    // Still waiting
                }
                break;
                case 1:
                {
                    uint16_t port = atoi(APP_Port_Buffer);
                    appData.socket = TCPIP_UDP_ClientOpen(IP_ADDRESS_TYPE_IPV4,
                                                          port,
                                                          (IP_MULTI_ADDRESS*) &addr);
                    if (appData.socket == INVALID_SOCKET)
                    {
                        SYS_CONSOLE_MESSAGE("Could not start connection\r\n");
                        appData.state = APP_TCPIP_WAITING_FOR_COMMAND;
                    }
                    SYS_CONSOLE_MESSAGE("Starting connection\r\n");
                    appData.state = APP_TCPIP_WAIT_FOR_CONNECTION;
                }
                break;
            }
        }
        break;

        case APP_TCPIP_WAIT_FOR_CONNECTION:
        {
            if (!TCPIP_UDP_IsConnected(appData.socket))
            {
                break;
            }
            if(UDPIsPutReady(appData.socket) == 0)
            {
                break;
            }
            TCPIP_UDP_ArrayPut(appData.socket, (uint8_t*)APP_Message_Buffer, strlen(APP_Message_Buffer));
            TCPIP_UDP_Flush(appData.socket);
            appData.state = APP_TCPIP_WAIT_FOR_RESPONSE;
        }
        break;

        case APP_TCPIP_WAIT_FOR_RESPONSE:
        {
            char buffer[180];
            memset(buffer, 0, sizeof(buffer));
            if (!TCPIP_UDP_IsConnected(appData.socket))
            {
                SYS_CONSOLE_MESSAGE("\r\nConnection Closed\r\n");
                appData.state = APP_TCPIP_WAITING_FOR_COMMAND;
                break;
            }
            if (TCPIP_UDP_GetIsReady(appData.socket))
            {
                TCPIP_UDP_ArrayGet(appData.socket, (uint8_t*)buffer, sizeof(buffer) - 1);
                SYS_CONSOLE_MESSAGE(buffer);
                appData.state = APP_TCPIP_WAITING_FOR_COMMAND;

            }
        }
        break;
        default:
            break;
    }
}