/*=========================================================================*\
  Copyright (c) 2000-2001 Computer & Communications Research Laboratories,
                          Industrial Technology Research Institute
  
  RTP helper 
  
  Author: Jiun-Yao Huang <jyhuang@wizs.org>
  Revision: $Id: rtp_helper.c,v 1.11 2001/06/15 10:40:48 jyhuang Exp $
  Description:
\*=========================================================================*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "config.h"
#include "rtp_helper.h"
#ifdef	__UNIX     /* [ for UNIX ] */
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#else              /* [ for Windows ] */
#include <windows.h>
#endif             /* [ #ifdef __UNIX ] */


#ifdef	NDEBUG
#ifndef	__GNUC__
void rtptrace(char *fmt, ...) {}
#endif
#else	/* !NDEBUG */
void rtptrace(char *fmt, ...)
{
	va_list args;
	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
}
#endif /* NDEBUG */

#define	__INIT_SOURCE(s, ssrc) {	\
		memset(s, 0, sizeof(rtp_source_t)); \
		s->ssrc = ssrc; \
		s->probation = RTP_MIN_SEQUENTIAL - 1; \
	}

void __srclist_init(rtp_source_list_t *srcs)
{
	assert(srcs);

	srcs->psrc = (rtp_source_t *) malloc(sizeof(rtp_source_t));
	srcs->capacity = 1;
	srcs->size = 0;
}

rtp_source_t *__srclist_lookup(rtp_source_list_t *srcs, u_int32 ssrc)
{
	size_t	i;
	
	assert(srcs);
	
	for (i = 0; i < srcs->size; ++i)
		if (srcs->psrc[i].ssrc == ssrc)
			return &srcs->psrc[i];
	
	return NULL;
}

rtp_source_t *__srclist_add(rtp_source_list_t *srcs, u_int32 ssrc)
{
	assert(srcs);
	
	if (srcs->size < srcs->capacity) {	/* fine */
		__INIT_SOURCE((&srcs->psrc[srcs->size]), ssrc)
		srcs->size++;
		return(&srcs->psrc[srcs->size-1]);
	} else {
		rtp_source_t	*psrc;
		srcs->capacity *= 2;
		psrc = (rtp_source_t *) 
		       malloc(sizeof(rtp_source_t) * srcs->capacity);
		memcpy(psrc, srcs->psrc, sizeof(rtp_source_t) * srcs->size);
		free(srcs->psrc);
		srcs->psrc = psrc;
		return __srclist_add(srcs, ssrc);
	}
}

void __srclist_free(rtp_source_list_t *srcs)
{
	assert(srcs);
	free(srcs->psrc);
}

u_int32 __gen_ssrc(void)
{
	u_int32	ans = 0;
#ifdef	__UNIX     /* [ for UNIX ] */

	ans |= (getpid() & 0xffff0000);
	ans |= (__rtp_random() & 0xffff);
#else              /* [ for Windows ] */
	ans |= (GetCurrentThreadId() & 0xffff0000);
	ans |= (__rtp_random() & 0xffff);
#endif             /* [ #ifdef __UNIX ] */
	return ans;
}


int __getipaddr(const char *addrstr, struct in_addr *addr)
{
	if (addr == NULL)
		return -1;
	
	if ((addr->s_addr = inet_addr(addrstr)) == -1) {	/* failed */
		struct hostent	*hp;
		if ((hp = gethostbyname(addrstr)) != NULL) {
			int	i;
			for (i = 0; i < hp->h_length; ++i)
				((char *)addr)[i] = hp->h_addr[i];
		} else
			return -1;
	}

	return 0;
}

u_int16 __rtp_random(void)
{
	return (rand() & 0xFFFF);
}
