Exemple #1
0
bool UdpServer::getAvailableClientsRemoteEndPoint(IPEndPoint *pRemoteEP, MAC * pRemoteMAC, int index)
{
    IPEndPoint remoteEP;
    unsigned short localPort;
    MAC macRemote;

    if(index >= _cPending)
    {
        return(false);
    } 

    // careful not to run PendingClients or IsListening so index order does not change
    GetUdpSocketEndPoints(_rghUDP[index], &remoteEP.ip, &macRemote, &remoteEP.port, &localPort);

    if(pRemoteEP != 0)
    {
        *pRemoteEP = remoteEP;
    }

    if(pRemoteMAC != 0)
    {
        *pRemoteMAC = macRemote;
    }
}
Exemple #2
0
bool UdpClient::isEndPointResolved(unsigned long msBlockMax, DNETcK::STATUS * pStatus)
{
    unsigned long tStart = 0;
    DNETcK::STATUS statusT = DNETcK::None;

    // we want this to be PeriodicTasks and not StackTask because we
    // want to run all of the applications when IsDNETcK::EndPointResolved is called
    // because this is a common call and we want to keep all things running
   EthernetPeriodicTasks();

    // nothing to do if we have already resolved it.
    if(_fEndPointsSetUp)
    {
        if(pStatus != NULL) *pStatus = DNETcK::EndPointResolved;
        return(true);
    }

    // make sure the network is initialized
    if(!DNETcK::isInitialzied(msBlockMax, pStatus))
    {
        return(false);
    }
    
    // make sure the UDP cache is big enough
    if(_cbCache < UdpClient::cbDatagramCacheMin)
    {
        if(pStatus != NULL) *pStatus = DNETcK::UDPCacheToSmall;
        return(false);
    }

    // initialize our status to our current state
    if(pStatus != NULL) *pStatus = _classState;

    // return our current state, except if we are in the process of resolving
    if(DNETcK::isStatusAnError(_classState))
    {
        return(false);
    }

    // continue with the resolve process
    tStart = millis();
    do
    {
        // run the stack
        EthernetPeriodicTasks();

        switch(_classState)
        {
            case DNETcK::DNSResolving:
                if(DNETcK::isDNSResolved(_szHostName, &_remoteEP.ip, DNETcK::msImmediate, &statusT))
                {
                    DNETcK::requestARPIpMacResolution(_remoteEP.ip);
                    _classState = DNETcK::ARPResolving;
                    _msARPtStart = millis();
                }

                // stay at the resolving state until an error occurs
                // if an error, then we fail.
                else if(DNETcK::isStatusAnError(statusT))
                {
                    _classState = DNETcK::DNSResolutionFailed;
                }
                break;

            case DNETcK::ARPResolving:

                // see if we resolved the MAC address
                if(DNETcK::isARPIpMacResolved(_remoteEP.ip, &_remoteMAC, DNETcK::msImmediate))
                {
                    _classState = DNETcK::AcquiringSocket;
                    _msARPtStart = 0;
                }

                // if the ARP timeout has occured; rmember, ARP really doesn't give us failues
                else if(hasTimeElapsed(_msARPtStart, _msARPWait, millis())) 
                {
                    // resend the ARP Request
                    if(_cARPRetries > 0)
                    {
                        DNETcK::requestARPIpMacResolution(_remoteEP.ip);
                        _msARPtStart = millis();
                        _cARPRetries--;
                    }
                    // otherwise we are done
                    else
                    {
                        _classState = DNETcK::ARPResolutionFailed;
                        _msARPtStart = 0;
                    }
                }
                break;

            case DNETcK::AcquiringSocket:

                // set up the socket
                _hUDP = UdpClientSetEndPoint(_remoteEP.ip.rgbIP, _remoteMAC.rgbMAC, _remoteEP.port, _localPort);

                if(_hUDP >= INVALID_UDP_SOCKET)
                {
                    _classState = DNETcK::SocketError;
                    if(pStatus != NULL) *pStatus = _classState;
                    break;
                }

                // fall right into finalize; we have finalize for the UdpServer to use

            case DNETcK::Finalizing:

                // assume the best that we will finish, unless something bad happens.
                _classState = DNETcK::EndPointResolved;

                // we just set up the socket, so all of the IP and port info should be correct
                // let's just update our code so we know we have what the MAL thinks.
                GetUdpSocketEndPoints(_hUDP, &_remoteEP.ip, &_remoteMAC, &_remoteEP.port, &_localPort);

                // see if a cache buffer came in.
                if(_rgbCache == NULL)
                {
                    close();
                    _classState = DNETcK::UDPCacheToSmall;
                }

                // add it to the underlying caching engine
                else
                {
                    ExchangeCacheBuffer(_hUDP, _rgbCache, _cbCache);
                }
                break;

            // if we got an error in the process, we are done. 
            // this is how we get out of the do-while on an error
            default:
                if(pStatus != NULL) *pStatus = _classState;
                return(false);
        }

    } while(_classState != DNETcK::EndPointResolved && !hasTimeElapsed(tStart, msBlockMax, millis()));

    // not sure how we got out of the loop
    // but assign our state and only return true if we succeeded.
    if(pStatus != NULL) *pStatus = _classState;
    if(_classState == DNETcK::EndPointResolved)
    {
        _fEndPointsSetUp = true;
        return(true);
    }

    return(false);
}