コード例 #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();
}
コード例 #2
0
void CDplusProtocol::HandleQueue(void)
{
    m_Queue.Lock();
    while ( !m_Queue.empty() )
    {
        // get the packet
        CPacket *packet = m_Queue.front();
        m_Queue.pop();
        
        // get our sender's id
        int iModId = g_Reflector.GetModuleIndex(packet->GetModuleId());
        
        // check if it's header and update cache
        if ( packet->IsDvHeader() )
        {
            // this relies on queue feeder setting valid module id
            m_DvHeadersCache[iModId] = CDvHeaderPacket((const CDvHeaderPacket &)*packet);
            m_iSeqCounters[iModId] = 0;
        }

        // encode it
        CBuffer buffer;
        if ( EncodeDvPacket(*packet, &buffer) )
        {
            // and push it to all our clients who are not streaming in
            // note that for dplus protocol, all stream of all modules are push to all clients
            // it's client who decide which stream he's interrrested in
            CClients *clients = g_Reflector.GetClients();
            int index = -1;
            CClient *client = NULL;
            while ( (client = clients->FindNextClient(PROTOCOL_DPLUS, &index)) != NULL )
            {
                // is this client busy ?
                if ( !client->IsAMaster() )
                {
                    // check if client is a dextra dongle
                    // then replace RPT2 with XRF instead of REF
                    // if the client type is not yet known, send bothheaders
                    if ( packet->IsDvHeader() )
                    {
                        // sending header in Dplus is client specific
                        SendDvHeader((CDvHeaderPacket *)packet, (CDplusClient *)client);
                    }
                    else if ( packet->IsDvFrame() )
                    {
                        // and send the DV frame
                         m_Socket.Send(buffer, client->GetIp());

                        // is it time to insert a DVheader copy ?
                        if ( (m_iSeqCounters[iModId]++ % 21) == 20 )
                        {
                            // yes, clone it
                            CDvHeaderPacket packet2(m_DvHeadersCache[iModId]);
                            // and send it 
                            SendDvHeader(&packet2, (CDplusClient *)client);
                        }
                    }
                    else
                    {
                        // otherwise, send the original packet
                        m_Socket.Send(buffer, client->GetIp());
                    }
                }
            }
            g_Reflector.ReleaseClients();
        }
        
        
        // done
        delete packet;
    }
    m_Queue.Unlock();
}