Beispiel #1
0
bool CDplusProtocol::EncodeDvHeaderPacket(const CDvHeaderPacket &Packet, CBuffer *Buffer) const
{
    uint8 tag[]	= { 0x3A,0x80,0x44,0x53,0x56,0x54,0x10,0x00,0x00,0x00,0x20,0x00,0x01,0x02 };
    struct dstar_header DstarHeader;
    
    Packet.ConvertToDstarStruct(&DstarHeader);
   
    Buffer->Set(tag, sizeof(tag));
    Buffer->Append(Packet.GetStreamId());
    Buffer->Append((uint8)0x80);
    Buffer->Append((uint8 *)&DstarHeader, sizeof(struct dstar_header));

    return true;
}
Beispiel #2
0
CDvHeaderPacket *CDplusProtocol::IsValidDvHeaderPacket(const CBuffer &Buffer)
{
    CDvHeaderPacket *header = NULL;
    
    if ( (Buffer.size() == 58) &&
         (Buffer.data()[0] == 0x3A) && (Buffer.data()[1] == 0x80) &&
         (Buffer.Compare((uint8 *)"DSVT", 2, 4) == 0) &&
         (Buffer.data()[6] == 0x10) && (Buffer.data()[10] == 0x20) )
    {
        // create packet
        header = new CDvHeaderPacket((struct dstar_header *)&(Buffer.data()[17]),
                                     *((uint16 *)&(Buffer.data()[14])), 0x80);
        // check validity of packet
        if ( !header->IsValid() )
        {
            delete header;
            header = NULL;
        }
    }
    return header;
}
Beispiel #3
0
bool CPacketStream::Open(const CDvHeaderPacket &DvHeader, CClient *client)
{
    bool ok = false;
    
    // not already open?
    if ( !m_bOpen )
    {
        // update status
        m_bOpen = true;
        m_uiStreamId = DvHeader.GetStreamId();
        m_DvHeader = DvHeader;
        m_OwnerClient = client;
        m_LastPacketTime.Now();
        ok = true;
    }
    return ok;
}
Beispiel #4
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();
    }
 }