Beispiel #1
0
void CDplusProtocol::HandleKeepalives(void)
{
    // send keepalives
    CBuffer keepalive;
    EncodeKeepAlivePacket(&keepalive);
    
    // iterate on clients
    CClients *clients = g_Reflector.GetClients();
    int index = -1;
    CClient *client = NULL;
    while ( (client = clients->FindNextClient(PROTOCOL_DPLUS, &index)) != NULL )
    {
        // send keepalive
        //std::cout << "Sending DPlus packet @ " << client->GetIp() << std::endl;
        m_Socket.Send(keepalive, client->GetIp());
        
        // is this client busy ?
        if ( client->IsAMaster() )
        {
            // yes, just tickle it
            client->Alive();
        }
        // check it's still with us
        else if ( !client->IsAlive() )
        {
            // no, disconnect
            CBuffer disconnect;
            EncodeDisconnectPacket(&disconnect);
            m_Socket.Send(disconnect, client->GetIp());
            
            // and remove it
            std::cout << "DPlus client " << client->GetCallsign() << " keepalive timeout" << std::endl;
            clients->RemoveClient(client);
        }
    }
    g_Reflector.ReleaseClients();
}
Beispiel #2
0
void CDplusProtocol::Task(void)
{
    CBuffer             Buffer;
    CIp                 Ip;
    CCallsign           Callsign;
    CDvHeaderPacket     *Header;
    CDvFramePacket      *Frame;
    CDvLastFramePacket  *LastFrame;
    
    // handle incoming packets
    if ( m_Socket.Receive(&Buffer, &Ip, 20) != -1 )
    {
        // crack the packet
        if ( (Frame = IsValidDvFramePacket(Buffer)) != NULL )
        {
            //std::cout << "DPlus DV frame" << std::endl;
            
            // handle it
            OnDvFramePacketIn(Frame);
        }
        else if ( (Header = IsValidDvHeaderPacket(Buffer)) != NULL )
        {
            //std::cout << "DPlus DV header:" << std::endl << *Header << std::endl;
            
            // callsign muted?
            if ( g_GateKeeper.MayTransmit(Header->GetMyCallsign(), Ip, PROTOCOL_DPLUS, Header->GetRpt2Module()) )
            {
                // handle it
                OnDvHeaderPacketIn(Header, Ip);
            }
            else
            {
                delete Header;
            }
        }
        else if ( (LastFrame = IsValidDvLastFramePacket(Buffer)) != NULL )
        {
            //std::cout << "DPlus DV last frame" << std::endl;
            
            // handle it
            OnDvLastFramePacketIn(LastFrame);
       }
        else if ( IsValidConnectPacket(Buffer) )
        {
            std::cout << "DPlus connect request packet from " << Ip << std::endl;

            // acknowledge the request
            m_Socket.Send(Buffer, Ip);
        }
        else if ( IsValidLoginPacket(Buffer, &Callsign) )
        {
            std::cout << "DPlus login packet from " << Callsign << " at " << Ip << std::endl;
            
            // callsign authorized?
            if ( g_GateKeeper.MayLink(Callsign, Ip, PROTOCOL_DPLUS) )
            {
                // acknowledge the request
                EncodeLoginAckPacket(&Buffer);
                m_Socket.Send(Buffer, Ip);
                
               // create the client
                CDplusClient *client = new CDplusClient(Callsign, Ip);
                
                // and append
                g_Reflector.GetClients()->AddClient(client);
                g_Reflector.ReleaseClients();
            }
            else
            {
                // deny the request
                EncodeLoginNackPacket(&Buffer);
                m_Socket.Send(Buffer, Ip);
            }
            
        }
        else if ( IsValidDisconnectPacket(Buffer) )
        {
            std::cout << "DPlus disconnect packet from " << Ip << std::endl;
            
            // find client
            CClients *clients = g_Reflector.GetClients();
            CClient *client = clients->FindClient(Ip, PROTOCOL_DPLUS);
            if ( client != NULL )
            {
                // remove it
                clients->RemoveClient(client);
                // and acknowledge the disconnect
                EncodeDisconnectPacket(&Buffer);
                m_Socket.Send(Buffer, Ip);
            }
            g_Reflector.ReleaseClients();
        }
        else if ( IsValidKeepAlivePacket(Buffer) )
        {
            //std::cout << "DPlus keepalive packet from " << Ip << std::endl;
            
            // find all clients with that callsign & ip and keep them alive
            CClients *clients = g_Reflector.GetClients();
            int index = -1;
            CClient *client = NULL;
            while ( (client = clients->FindNextClient(Ip, PROTOCOL_DPLUS, &index)) != NULL )
            {
                client->Alive();
            }
            g_Reflector.ReleaseClients();
        }
        else
        {
            std::cout << "DPlus packet (" << Buffer.size() << ")" << std::endl;
        }
    }
    
    // handle end of streaming timeout
    CheckStreamsTimeout();
    
    // handle queue from reflector
    HandleQueue();
    
    // keep client alive
    if ( m_LastKeepaliveTime.DurationSinceNow() > DPLUS_KEEPALIVE_PERIOD )
    {
        //
        HandleKeepalives();
        
        // update time
        m_LastKeepaliveTime.Now();
    }
 }