#include <rtp.h>

__BEGIN_SYS


RTP::RTP(UDP::Address remote) {
    UDP::Address rtp_local = UDP::Address( remote.port() );
    UDP::Address rtcp_local = UDP::Address( remote.port()+1 );
    UDP::Address rtcp_remote = UDP::Address( remote.address(), remote.port()+1 );
    _rtcp_remote = rtcp_remote;
    _rtp_remote = remote;
    _ssrc_id = RTP::get_ssrc_id();

    // Abrir as portas TCP do RTP e RTCP (listen)
    Thread *listener = new Thread(&RTP::listen, this, rtp_local, rtcp_local);
}


char *RTP::receive() {
    int r,s,buf_size;
    buf_size = 512;
    char buf[buf_size];

    if(_local_rtp->read(buf,buf_size) == 512) {
        db<RTP>(TRC) << "Received RTP Package.";
        PDU *pdu = reinterpret_cast<PDU*>(buf);

        return (char*)(pdu->data());
    }
    return 0;
}


int RTP::send(u32 timestamp, PType payload_type, u8 marker, char *payload,int payload_len) {
    if(!_remote_rtp){
        _remote_rtp = TCP::connect(_rtp_remote);
        _remote_rtcp = TCP::connect(_rtcp_remote);
    }

    Header h (marker, payload_type, timestamp, _ssrc_id);

    char* end_of_payload = payload + payload_len;
    for(; payload < end_of_payload; payload += PDU::PDU_DATA_SIZE ) {
        h.set_sequence_number(++_sequence_number);

        PDU pdu (h, payload);

        char * pduchar = reinterpret_cast<char*>(&pdu);
        _remote_rtp->send(pduchar, sizeof(pdu));
    }

    return 0;
}


int RTP::listen(RTP * self, UDP::Address rtp_local, UDP::Address rtcp_local) {
    self->_local_rtp = TCP::listen(rtp_local);
    self->_local_rtcp = TCP::listen(rtcp_local);
    return 0;
}


int RTP::get_ssrc_id() {
    return Pseudo_Random::random(42);
}


Debug& operator<< (Debug &db, const RTP::Header &h) {
    db << "{ver=" << h.version_number()
    << ",ext=" << h.extensions()
    << ",cc=" << h.contrib_sources_count()
    << ",ptype=" << h.payload_type()
    << ",marker="  << h.marker()
    << ",ssrc_id=" << h.ssrc_id()
    << ",timestamp=" << h.timestamp()
    << ",seq=" << h.sequence_number()
    << "}";
		
    return db;
}


__END_SYS