#include "beacon.h"
#include "memory.h"

#define SECS_BETWEEN_1900_1970 2208988800u

static beacon_event *first, *last;  

rtp_t beacon_init(const char *addr, uint16_t rx_port, uint16_t tx_port,
                  int ttl, double rtcp_bw, uint8_t *userdata) 
{
    rtp_t session;

    session = rtp_init(addr,rx_port,tx_port,ttl,rtcp_bw,
	               beacon_callback,userdata);

    return(session);
}

rtp_t beacon_init_if(const char *addr, char *iface, uint16_t rx_port,
                     uint16_t tx_port, int ttl, double rtcp_bw,
		     uint8_t *userdata)
{

    rtp_t session;

    session = rtp_init_if(addr,iface,rx_port,tx_port,ttl,rtcp_bw,
	                  beacon_callback,userdata);

    return(session);
}

int beacon_queue_len(void)
{
    beacon_event *be;
    int i = 0;

    be = first;

    while(be) {
	i++;
	if(be->next) {
	    be = be->next;
	} else {
	    be = NULL;
	}
    }

    return(i);
}

void beacon_callback( struct rtp *session, rtp_event *event )
{
    beacon_event *be;
#ifdef DEBUG
    int i;
#endif /* DEBUG */

    be = process_event(event);

    if (be) {
	if (last) {
	    last->next = be;
	    last = be;
	} else {
	    last = be;
	    first = be;
	}
    }

#ifdef DEBUG
    if(be && be->type == RX_RR) {
	i = beacon_queue_len();

	if(i > 0 ) {
    	    fprintf(stderr,"%d events in the queue\n",i);
       	}
    }
#endif /* DEBUG */
}

beacon_event *beacon_get_next_event(void)
{
    beacon_event *rv;

    if (first) {
	rv = first;
	if (first->next) {
	    first = first->next;
	} else {
	    first = NULL;
	    last = NULL;
	}
    } else {
	rv = NULL;
    }

    return(rv);
}

void beacon_free_event(beacon_event *event)
{
    if(event->type == RX_RR) {
	xfree(event->rr);
    }

    xfree(event);
}

beacon_event *process_event( rtp_event *event )
{
    beacon_event *temp_event = NULL;
    uint32_t ntp_sec, ntp_frac;

    switch ( event->type ) {
        case RX_RTP:
	    xfree(event->data);
            break;
    
        case RX_SR:
        case RX_RTCP_FINISH:
        case RR_TIMEOUT:
        case RX_BYE:
        case RX_RR_EMPTY:
        case RX_RTCP_START:
        case RX_APP:
            break;
    
        case RX_RR:
        case RX_SDES:
        case SOURCE_CREATED:
        case SOURCE_DELETED:

	    temp_event = (beacon_event *) xmalloc( sizeof(beacon_event) );
	    temp_event->next = NULL;

	    temp_event->type = event->type;
            temp_event->ssrc = event->ssrc;

	    /* timeval adjusted to ntp32 time; see UCL RTP lib */
	    ntp_sec  = event->ts->tv_sec + SECS_BETWEEN_1900_1970;
	    ntp_frac = (event->ts->tv_usec << 12) + (event->ts->tv_usec << 8) - ((event->ts->tv_usec * 3650) >> 6);
	    temp_event->time = ((((ntp_sec)  & 0x0000ffff) << 16) | (((ntp_frac) & 0xffff0000) >> 16));

            if( event->type == RX_RR ) {
                rtcp_rr *temp_rr;
                temp_rr = (rtcp_rr *) event->data;

		temp_event->rr = (rtcp_rr *) xmalloc( sizeof(rtcp_rr) );
		memcpy(temp_event->rr, temp_rr, sizeof(rtcp_rr));

		temp_event->rr->fract_lost =
		    (int)(temp_rr->fract_lost/2.56);
            }

            break;
    }


    return temp_event;
}



syntax highlighted by Code2HTML, v. 0.9.1