ameba micropython sdk first commit

This commit is contained in:
xidameng 2020-07-31 22:16:12 +08:00
commit 8508ee6139
5619 changed files with 1874619 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,90 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "re.h"
#include "baresip.h"
#include "lwip/sockets.h"
#include "osdep_service.h"
#include "FreeRTOS.h"
#include "task.h"
#include "platform/platform_stdlib.h"
#include "avcodec_sip.h"
#if 1
/** Call constants */
enum {
PTIME = 20, /**< Packet time for audio */
};
/** Call States */
enum state {
STATE_IDLE = 0,
STATE_INCOMING,
STATE_OUTGOING,
STATE_RINGING,
STATE_EARLY,
STATE_ESTABLISHED,
STATE_TERMINATED
};
/** SIP Call Control object */
struct call {
MAGIC_DECL /**< Magic number for debugging */
struct le le; /**< Linked list element */
struct ua *ua; /**< SIP User-agent */
struct account *acc; /**< Account (ref.) */
struct sipsess *sess; /**< SIP Session */
struct sdp_session *sdp; /**< SDP Session */
struct sipsub *sub; /**< Call transfer REFER subscription */
struct sipnot *not; /**< REFER/NOTIFY client */
struct list streaml; /**< List of mediastreams (struct stream) */
#ifdef ENABLE_SIP_MMFV2
struct stream *strm; /**< Generic media stream */
u8 allow_stream; /*mmfv2 flag to indicate start or stop streaming*/
#else
struct audio *audio; /**< Audio stream */
#endif
#ifdef USE_VIDEO
struct video *video; /**< Video stream */
struct bfcp *bfcp; /**< BFCP Client */
#endif
enum state state; /**< Call state */
char *local_uri; /**< Local SIP uri */
char *local_name; /**< Local display name */
char *peer_uri; /**< Peer SIP Address */
char *peer_name; /**< Peer display name */
char *id; /**< Cached session call-id */
struct tmr tmr_inv; /**< Timer for incoming calls */
struct tmr tmr_dtmf; /**< Timer for incoming DTMF events */
time_t time_start; /**< Time when call started */
time_t time_conn; /**< Time when call initiated */
time_t time_stop; /**< Time when call stopped */
bool outgoing; /**< True if outgoing, false if incoming */
bool got_offer; /**< Got SDP Offer from Peer */
bool on_hold; /**< True if call is on hold */
struct mnat_sess *mnats; /**< Media NAT session */
bool mnat_wait; /**< Waiting for MNAT to establish */
struct menc_sess *mencs; /**< Media encryption session state */
int af; /**< Preferred Address Family */
uint16_t scode; /**< Termination status code */
call_event_h *eh; /**< Event handler */
#ifdef ENANBLE_DTMF_8195A
call_dtmf_h *dtmfh; /**< DTMF handler */
#endif
void *arg; /**< Handler argument */
struct config_avt config_avt; /**< AVT config */
struct config_call config_call; /**< Call config */
uint32_t rtp_timeout_ms; /**< RTP Timeout in [ms] */
uint32_t linenum; /**< Line number from 1 to N */
};
#endif

View file

@ -0,0 +1,565 @@
/**
* @file core.h Internal API
*
* Copyright (C) 2010 Creytiv.com
*/
#include "baresip.h"
#include <limits.h>
#include "sip/ua_api.h"
/* max bytes in pathname */
#if defined (PATH_MAX)
#define FS_PATH_MAX PATH_MAX
#elif defined (_POSIX_PATH_MAX)
#define FS_PATH_MAX _POSIX_PATH_MAX
#else
#define FS_PATH_MAX 512
#endif
/**
* RFC 3551:
*
* 0 - 95 Static payload types
* 96 - 127 Dynamic payload types
*/
enum {
PT_CN = 13,
PT_STAT_MIN = 0,
PT_STAT_MAX = 95,
PT_DYN_MIN = 96,
PT_DYN_MAX = 127
};
/** Media constants */
enum {
AUDIO_BANDWIDTH = 128000, /**< Bandwidth for audio in bits/s */
VIDEO_SRATE = 90000, /**< Sampling rate for video */
};
/* forward declarations */
struct stream_param;
/*
* Account
*/
struct account {
char *buf; /**< Buffer for the SIP address */
struct sip_addr laddr; /**< Decoded SIP address */
struct uri luri; /**< Decoded AOR uri */
char *dispname; /**< Display name */
char *aor; /**< Local SIP uri */
/* parameters: */
enum answermode answermode; /**< Answermode for incoming calls */
struct le acv[8]; /**< List elements for aucodecl */
struct list aucodecl; /**< List of preferred audio-codecs */
char *auth_user; /**< Authentication username */
char *auth_pass; /**< Authentication password */
char *mnatid; /**< Media NAT handling */
char *mencid; /**< Media encryption type */
const struct mnat *mnat; /**< MNAT module */
const struct menc *menc; /**< MENC module */
char *outboundv[2]; /**< Optional SIP outbound proxies */
uint32_t ptime; /**< Configured packet time in [ms] */
uint32_t regint; /**< Registration interval in [seconds] */
uint32_t pubint; /**< Publication interval in [seconds] */
char *regq; /**< Registration Q-value */
char *rtpkeep; /**< RTP Keepalive mechanism */
char *sipnat; /**< SIP Nat mechanism */
char *stun_user; /**< STUN Username */
char *stun_pass; /**< STUN Password */
char *stun_host; /**< STUN Hostname */
uint16_t stun_port; /**< STUN Port number */
struct le vcv[4]; /**< List elements for vidcodecl */
struct list vidcodecl; /**< List of preferred video-codecs */
};
/*
* Audio Player
*/
struct auplay_st {
struct auplay *ap;
};
struct auplay {
struct le le;
const char *name;
auplay_alloc_h *alloch;
};
/*
* Audio Source
*/
struct ausrc_st {
const struct ausrc *as;
};
struct ausrc {
struct le le;
const char *name;
ausrc_alloc_h *alloch;
};
/*
* Audio Stream
*/
struct audio;
typedef void (audio_event_h)(int key, bool end, void *arg);
typedef void (audio_err_h)(int err, const char *str, void *arg);
int audio_alloc(struct audio **ap, const struct stream_param *stream_prm,
const struct config *cfg,
struct call *call, struct sdp_session *sdp_sess, int label,
const struct mnat *mnat, struct mnat_sess *mnat_sess,
const struct menc *menc, struct menc_sess *menc_sess,
uint32_t ptime, const struct list *aucodecl, bool offerer,
audio_event_h *eventh, audio_err_h *errh, void *arg);
#ifndef ENABLE_SIP_VIDEO
int audio_start_sip(struct audio *a);
void audio_stop(struct audio *a);
int audio_encoder_set(struct audio *a, const struct aucodec *ac,
int pt_tx, const char *params);
int audio_decoder_set(struct audio *a, const struct aucodec *ac,
int pt_rx, const char *params);
int audio_send_digit(struct audio *a, char key);
void audio_sdp_attr_decode(struct audio *a);
int audio_print_rtpstat(struct re_printf *pf, const struct audio *au);
#endif
/*
* BFCP
*/
struct bfcp;
int bfcp_alloc(struct bfcp **bfcpp, struct sdp_session *sdp_sess,
const char *proto, bool offerer,
const struct mnat *mnat, struct mnat_sess *mnat_sess);
int bfcp_start(struct bfcp *bfcp);
/*
* Call Control
*/
enum {
CALL_LINENUM_MIN = 1,
CALL_LINENUM_MAX = 256
};
struct call;
/** Call parameters */
struct call_prm {
struct sa laddr;
enum vidmode vidmode;
int af;
bool use_rtp;
};
int call_alloc(struct call **callp, const struct config *cfg,
struct list *lst,
const char *local_name, const char *local_uri,
struct account *acc, struct ua *ua, const struct call_prm *prm,
const struct sip_msg *msg, struct call *xcall,
struct dnsc *dnsc,
call_event_h *eh, void *arg);
int call_connect(struct ua_context *ua_ctx,struct call *call, const struct pl *paddr);
int call_accept(struct call *call, struct sipsess_sock *sess_sock,
const struct sip_msg *msg);
int call_hangup(struct call *call, uint16_t scode, const char *reason);
int call_progress(struct ua_context *ua_ctx,struct call *call);
int call_answer(struct call *call, uint16_t scode);
int call_sdp_get(const struct call *call, struct mbuf **descp, bool offer);
int call_jbuf_stat(struct re_printf *pf, const struct call *call);
int call_info(struct re_printf *pf, const struct call *call);
int call_reset_transp(struct call *call, const struct sa *laddr);
int call_notify_sipfrag(struct call *call, uint16_t scode,
const char *reason, ...);
int call_af(const struct call *call);
void call_set_xrtpstat(struct call *call);
struct account *call_account(const struct call *call);
/*
* Conf
*/
int conf_get_range(const struct conf *conf, const char *name,
struct range *rng);
int conf_get_csv(const struct conf *conf, const char *name,
char *str1, size_t sz1, char *str2, size_t sz2);
/*
* Media control
*/
int mctrl_handle_media_control(struct pl *body, bool *pfu);
/*
* Media NAT traversal
*/
struct mnat {
struct le le;
const char *id;
const char *ftag;
mnat_sess_h *sessh;
mnat_media_h *mediah;
mnat_update_h *updateh;
};
const struct mnat *mnat_find(const struct list *mnatl, const char *id);
/*
* Metric
*/
struct metric {
/* internal stuff: */
struct tmr tmr;
uint64_t ts_start;
bool started;
/* counters: */
uint32_t n_packets;
uint32_t n_bytes;
uint32_t n_err;
/* bitrate calculation */
uint32_t cur_bitrate;
uint64_t ts_last;
uint32_t n_bytes_last;
};
void metric_init(struct metric *metric);
void metric_reset(struct metric *metric);
void metric_add_packet(struct metric *metric, size_t packetsize);
double metric_avg_bitrate(const struct metric *metric);
/*
* Module
*/
int module_init(const struct conf *conf);
void module_app_unload(void);
/*
* Register client
*/
struct reg;
int reg_add(struct list *lst, struct ua *ua, int regid);
int reg_register(struct reg *reg, const char *reg_uri,
const char *params, uint32_t regint, const char *outbound);
void reg_unregister(struct reg *reg);
bool reg_isok(const struct reg *reg);
int reg_debug(struct re_printf *pf, const struct reg *reg);
int reg_status(struct re_printf *pf, const struct reg *reg);
/*
* RTP Header Extensions
*/
#define RTPEXT_HDR_SIZE 4
#define RTPEXT_TYPE_MAGIC 0xbede
enum {
RTPEXT_ID_MIN = 1,
RTPEXT_ID_MAX = 14,
};
enum {
RTPEXT_LEN_MIN = 1,
RTPEXT_LEN_MAX = 16,
};
struct rtpext {
unsigned id:4;
unsigned len:4;
uint8_t data[RTPEXT_LEN_MAX];
};
int rtpext_hdr_encode(struct mbuf *mb, size_t num_bytes);
int rtpext_encode(struct mbuf *mb, unsigned id, unsigned len,
const uint8_t *data);
int rtpext_decode(struct rtpext *ext, struct mbuf *mb);
/*
* RTP keepalive
*/
struct rtpkeep;
int rtpkeep_alloc(struct rtpkeep **rkp, const char *method, int proto,
struct rtp_sock *rtp, struct sdp_media *sdp);
void rtpkeep_refresh(struct rtpkeep *rk, uint32_t ts);
/*
* SDP
*/
int sdp_decode_multipart(const struct pl *ctype_prm, struct mbuf *mb);
const struct sdp_format *sdp_media_format_cycle(struct sdp_media *m);
/*
* Stream
*/
struct rtp_header;
enum {STREAM_PRESZ = 4+12}; /* same as RTP_HEADER_SIZE */
typedef void (stream_rtp_h)(const struct rtp_header *hdr,
struct rtpext *extv, size_t extc,
struct mbuf *mb, void *arg);
typedef void (stream_rtcp_h)(struct rtcp_msg *msg, void *arg);
typedef void (stream_error_h)(struct stream *strm, int err, void *arg);
/** Common parameters for media stream */
struct stream_param {
bool use_rtp;
};
/** Defines a generic media stream */
struct stream {
struct le le; /**< Linked list element */
struct config_avt cfg; /**< Stream configuration */
struct call *call; /**< Ref. to call object */
struct sdp_media *sdp; /**< SDP Media line */
struct rtp_sock *rtp; /**< RTP Socket */
struct rtpkeep *rtpkeep; /**< RTP Keepalive */
struct rtcp_stats rtcp_stats;/**< RTCP statistics */
struct jbuf *jbuf; /**< Jitter Buffer for incoming RTP */
struct mnat_media *mns; /**< Media NAT traversal state */
const struct menc *menc; /**< Media encryption module */
struct menc_sess *mencs; /**< Media encryption session state */
struct menc_media *mes; /**< Media Encryption media state */
struct metric metric_tx; /**< Metrics for transmit */
struct metric metric_rx; /**< Metrics for receiving */
char *cname; /**< RTCP Canonical end-point identifier */
uint32_t ssrc_rx; /**< Incoming syncronizing source */
uint32_t pseq; /**< Sequence number for incoming RTP */
int pt_enc; /**< Payload type for encoding */
bool rtcp; /**< Enable RTCP */
bool rtcp_mux; /**< RTP/RTCP multiplex supported by peer */
bool jbuf_started; /**< True if jitter-buffer was started */
stream_rtp_h *rtph; /**< Stream RTP handler */
stream_rtcp_h *rtcph; /**< Stream RTCP handler */
void *arg; /**< Handler argument */
stream_error_h *errorh; /**< Stream error handler */
void *errorh_arg; /**< Error handler argument */
struct tmr tmr_rtp; /**< Timer for detecting RTP timeout */
uint64_t ts_last; /**< Timestamp of last received RTP pkt */
bool terminated; /**< Stream is terminated flag */
uint32_t rtp_timeout_ms; /**< RTP Timeout value in [ms] */
bool rtp_estab; /**< True if RTP stream is established */
};
int stream_alloc(struct stream **sp, const struct stream_param *prm,
const struct config_avt *cfg,
struct call *call, struct sdp_session *sdp_sess,
const char *name, int label,
const struct mnat *mnat, struct mnat_sess *mnat_sess,
const struct menc *menc, struct menc_sess *menc_sess,
const char *cname,
stream_rtp_h *rtph, stream_rtcp_h *rtcph, uint16_t media_port,void *arg);
struct sdp_media *stream_sdpmedia(const struct stream *s);
struct rtp_sock *stream_rtp(const struct stream *s);
int stream_send(struct stream *s, bool ext, bool marker, int pt, uint32_t ts,
struct mbuf *mb);
void stream_update(struct stream *s);
void stream_update_encoder(struct stream *s, int pt_enc);
int stream_jbuf_stat(struct re_printf *pf, const struct stream *s);
void stream_hold(struct stream *s, bool hold);
void stream_set_srate(struct stream *s, uint32_t srate_tx, uint32_t srate_rx);
void stream_send_fir(struct stream *s, bool pli);
void stream_reset(struct stream *s);
void stream_set_bw(struct stream *s, uint32_t bps);
void stream_set_error_handler(struct stream *strm,
stream_error_h *errorh, void *arg);
int stream_debug(struct re_printf *pf, const struct stream *s);
int stream_print(struct re_printf *pf, const struct stream *s);
void stream_enable_rtp_timeout(struct stream *strm, uint32_t timeout_ms);
/*
* User-Agent
*/
struct ua;
void ua_event(struct ua *ua, enum ua_event ev, struct call *call,
const char *fmt, ...);
void ua_printf(const struct ua *ua, const char *fmt, ...);
struct tls *uag_tls(void);
const char *uag_allowed_methods(void);
/*
* Video Display
*/
struct vidisp {
struct le le;
const char *name;
vidisp_alloc_h *alloch;
vidisp_update_h *updateh;
vidisp_disp_h *disph;
vidisp_hide_h *hideh;
};
/*
* Video Source
*/
struct vidsrc {
struct le le;
const char *name;
vidsrc_alloc_h *alloch;
vidsrc_update_h *updateh;
};
struct vidsrc *vidsrc_get(struct vidsrc_st *st);
struct vidisp *vidisp_get(struct vidisp_st *st);
/*
* Video Stream
*/
struct video;
typedef void (video_err_h)(int err, const char *str, void *arg);
#if 1
int video_alloc(struct video **vp, const struct stream_param *stream_prm,
const struct config *cfg,
struct call *call, struct sdp_session *sdp_sess, int label,
const struct mnat *mnat, struct mnat_sess *mnat_sess,
const struct menc *menc, struct menc_sess *menc_sess,
const char *content, const struct list *vidcodecl,
video_err_h *errh, void *arg);
#endif
#ifndef CONFIG_PLATFORM_8195BHP
int video_start(struct video *v, const char *peer);
void video_stop(struct video *v);
bool video_is_started(const struct video *v);
int video_encoder_set(struct video *v, struct vidcodec *vc,
int pt_tx, const char *params);
int video_decoder_set(struct video *v, struct vidcodec *vc, int pt_rx,
const char *fmtp);
void video_update_picture(struct video *v);
void video_sdp_attr_decode(struct video *v);
int video_print(struct re_printf *pf, const struct video *v);
#endif
/*
* Timestamp helpers
*/
/**
* This struct is used to keep track of timestamps for
* incoming RTP packets.
*/
struct timestamp_recv {
uint32_t first;
uint32_t last;
bool is_set;
unsigned num_wraps;
};
static inline uint64_t calc_extended_timestamp(uint32_t num_wraps, uint32_t ts)
{
uint64_t ext_ts;
ext_ts = (uint64_t)num_wraps * 0x100000000ULL;
ext_ts += (uint64_t)ts;
return ext_ts;
}
static inline uint64_t timestamp_duration(const struct timestamp_recv *ts)
{
uint64_t last_ext;
if (!ts || !ts->is_set)
return 0;
last_ext = calc_extended_timestamp(ts->num_wraps, ts->last);
return last_ext - ts->first;
}
/*
* -1 backwards wrap-around
* 0 no wrap-around
* 1 forward wrap-around
*/
static inline int timestamp_wrap(uint32_t ts_new, uint32_t ts_old)
{
int32_t delta;
if (ts_new < ts_old) {
delta = (int32_t)ts_new - (int32_t)ts_old;
if (delta > 0)
return 1;
}
else if ((int32_t)(ts_old - ts_new) > 0) {
return -1;
}
return 0;
}
/*
* Timer
*/
uint64_t tmr_jiffies_usec(void);

View file

@ -0,0 +1,38 @@
/**
* @file magic.h Interface to magic macros
*
* Copyright (C) 2010 Creytiv.com
*/
#ifndef RELEASE
#ifndef MAGIC
#error "macro MAGIC must be defined"
#endif
/*
* Any C compiler conforming to C99 or later MUST support __func__
*/
#if __STDC_VERSION__ >= 199901L
#define __MAGIC_FUNC__ (const char *)__func__
#else
#define __MAGIC_FUNC__ __FUNCTION__
#endif
/** Check magic number */
#define MAGIC_DECL uint32_t magic;
#define MAGIC_INIT(s) (s)->magic = MAGIC
#define MAGIC_CHECK(s) \
if (MAGIC != s->magic) { \
warning("%s: wrong magic struct=%p (magic=0x%08x)\n", \
__MAGIC_FUNC__, s, s->magic); \
BREAKPOINT; \
}
#else
#define MAGIC_DECL
#define MAGIC_INIT(s)
#define MAGIC_CHECK(s) do {(void)(s);} while (0);
#endif

View file

@ -0,0 +1,163 @@
//
// qedit.h - cutted version of qedit.h from DirectX SDK
//
// Copyright (c) Shareaza Development Team, 2010.
// This file is part of SHAREAZA (shareaza.sourceforge.net)
//
// Shareaza is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Shareaza is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
#pragma once
#ifndef __ISampleGrabberCB_INTERFACE_DEFINED__
#define __ISampleGrabberCB_INTERFACE_DEFINED__
#include <DShow.h>
/* interface ISampleGrabberCB */
/* [unique][helpstring][local][uuid][object] */
EXTERN_C const IID IID_ISampleGrabberCB;
MIDL_INTERFACE("0579154A-2B53-4994-B0D0-E773148EFF85")
ISampleGrabberCB : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE SampleCB(
double SampleTime,
IMediaSample *pSample) = 0;
virtual HRESULT STDMETHODCALLTYPE BufferCB(
double SampleTime,
BYTE *pBuffer,
long BufferLen) = 0;
};
#endif /* __ISampleGrabberCB_INTERFACE_DEFINED__ */
#ifndef __ISampleGrabber_INTERFACE_DEFINED__
#define __ISampleGrabber_INTERFACE_DEFINED__
/* interface ISampleGrabber */
/* [unique][helpstring][local][uuid][object] */
EXTERN_C const IID IID_ISampleGrabber;
MIDL_INTERFACE("6B652FFF-11FE-4fce-92AD-0266B5D7C78F")
ISampleGrabber : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE SetOneShot(
BOOL OneShot) = 0;
virtual HRESULT STDMETHODCALLTYPE SetMediaType(
const AM_MEDIA_TYPE *pType) = 0;
virtual HRESULT STDMETHODCALLTYPE GetConnectedMediaType(
AM_MEDIA_TYPE *pType) = 0;
virtual HRESULT STDMETHODCALLTYPE SetBufferSamples(
BOOL BufferThem) = 0;
virtual HRESULT STDMETHODCALLTYPE GetCurrentBuffer(
/* [out][in] */ long *pBufferSize,
/* [out] */ long *pBuffer) = 0;
virtual HRESULT STDMETHODCALLTYPE GetCurrentSample(
/* [retval][out] */ IMediaSample **ppSample) = 0;
virtual HRESULT STDMETHODCALLTYPE SetCallback(
ISampleGrabberCB *pCallback,
long WhichMethodToCallback) = 0;
};
DEFINE_GUID(CLSID_SampleGrabber,0xc1f400a0,0x3f08,0x11d3,0x9f,0x0b,0x00,0x60,0x08,0x03,0x9e,0x37);
#endif /* __ISampleGrabber_INTERFACE_DEFINED__ */
#ifndef __IMediaDet_INTERFACE_DEFINED__
#define __IMediaDet_INTERFACE_DEFINED__
/* interface IMediaDet */
/* [unique][helpstring][uuid][object] */
EXTERN_C const IID IID_IMediaDet;
MIDL_INTERFACE("65BD0710-24D2-4ff7-9324-ED2E5D3ABAFA")
IMediaDet : public IUnknown
{
public:
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Filter(
/* [retval][out] */ __RPC__deref_out_opt IUnknown **pVal) = 0;
virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Filter(
/* [in] */ __RPC__in_opt IUnknown *newVal) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_OutputStreams(
/* [retval][out] */ __RPC__out long *pVal) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_CurrentStream(
/* [retval][out] */ __RPC__out long *pVal) = 0;
virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_CurrentStream(
/* [in] */ long newVal) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamType(
/* [retval][out] */ __RPC__out GUID *pVal) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamTypeB(
/* [retval][out] */ __RPC__deref_out_opt BSTR *pVal) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamLength(
/* [retval][out] */ __RPC__out double *pVal) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_Filename(
/* [retval][out] */ __RPC__deref_out_opt BSTR *pVal) = 0;
virtual /* [helpstring][id][propput] */ HRESULT STDMETHODCALLTYPE put_Filename(
/* [in] */ __RPC__in BSTR newVal) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetBitmapBits(
double StreamTime,
__RPC__in long *pBufferSize,
__RPC__in char *pBuffer,
long Width,
long Height) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE WriteBitmapBits(
double StreamTime,
long Width,
long Height,
__RPC__in BSTR Filename) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_StreamMediaType(
/* [retval][out] */ __RPC__out AM_MEDIA_TYPE *pVal) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE GetSampleGrabber(
/* [out] */ __RPC__deref_out_opt ISampleGrabber **ppVal) = 0;
virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_FrameRate(
/* [retval][out] */ __RPC__out double *pVal) = 0;
virtual /* [helpstring][id] */ HRESULT STDMETHODCALLTYPE EnterBitmapGrabMode(
double SeekTime) = 0;
};
#endif /* __IMediaDet_INTERFACE_DEFINED__ */
EXTERN_C const CLSID CLSID_MediaDet;
class DECLSPEC_UUID("65BD0711-24D2-4ff7-9324-ED2E5D3ABAFA")
MediaDet;

View file

@ -0,0 +1,68 @@
/**
* @file re.h Wrapper for all header files
*
* Copyright (C) 2010 Creytiv.com
*/
#ifndef RE_H__
#define RE_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Basic types */
#include "re_types.h"
#include "re_fmt.h"
#include "re_mbuf.h"
#include "re_msg.h"
#include "re_list.h"
#include "re_sa.h"
/* Library modules */
#include "re_aes.h"
#include "re_base64.h"
#include "re_bfcp.h"
#include "re_conf.h"
#include "re_crc32.h"
#include "re_dns.h"
#include "re_hash.h"
#include "re_hmac.h"
#include "re_http.h"
#include "re_httpauth.h"
#include "re_ice.h"
#include "re_jbuf.h"
#include "re_lock.h"
#include "re_main.h"
#include "re_md5.h"
#include "re_mem.h"
#include "re_mod.h"
#include "re_mqueue.h"
#include "re_net.h"
#include "re_odict.h"
#include "re_json.h"
#include "re_rtp.h"
#include "re_sdp.h"
#include "re_uri.h"
#include "re_sip.h"
#include "re_sipevent.h"
#include "re_sipreg.h"
#include "re_sipsess.h"
#include "re_stun.h"
#include "re_natbd.h"
#include "re_srtp.h"
#include "re_sys.h"
#include "re_tcp.h"
#include "re_telev.h"
#include "re_tmr.h"
#include "re_tls.h"
#include "re_turn.h"
#include "re_udp.h"
#include "re_websock.h"
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,27 @@
/**
* @file re_aes.h Interface to AES (Advanced Encryption Standard)
*
* Copyright (C) 2010 Creytiv.com
*/
#ifndef AES_BLOCK_SIZE
#define AES_BLOCK_SIZE 16
#endif
/** AES mode */
enum aes_mode {
AES_MODE_CTR, /**< AES Counter mode (CTR) */
AES_MODE_GCM, /**< AES Galois Counter Mode (GCM) */
};
struct aes;
int aes_alloc(struct aes **stp, enum aes_mode mode,
const uint8_t *key, size_t key_bits,
const uint8_t *iv);
void aes_set_iv(struct aes *aes, const uint8_t *iv);
int aes_encr(struct aes *aes, uint8_t *out, const uint8_t *in, size_t len);
int aes_decr(struct aes *aes, uint8_t *out, const uint8_t *in, size_t len);
int aes_get_authtag(struct aes *aes, uint8_t *tag, size_t taglen);
int aes_authenticate(struct aes *aes, const uint8_t *tag, size_t taglen);

View file

@ -0,0 +1,10 @@
/**
* @file re_base64.h Interface to Base64 encoding/decoding functions
*
* Copyright (C) 2010 Creytiv.com
*/
int base64_encode(const uint8_t *in, size_t ilen, char *out, size_t *olen);
int base64_print(struct re_printf *pf, const uint8_t *ptr, size_t len);
int base64_decode(const char *in, size_t ilen, uint8_t *out, size_t *olen);

View file

@ -0,0 +1,286 @@
/**
* @file re_bfcp.h Interface to Binary Floor Control Protocol (BFCP)
*
* Copyright (C) 2010 Creytiv.com
*/
/** BFCP Versions */
enum {
BFCP_VER1 = 1,
BFCP_VER2 = 2,
};
/** BFCP Primitives */
enum bfcp_prim {
BFCP_FLOOR_REQUEST = 1,
BFCP_FLOOR_RELEASE = 2,
BFCP_FLOOR_REQUEST_QUERY = 3,
BFCP_FLOOR_REQUEST_STATUS = 4,
BFCP_USER_QUERY = 5,
BFCP_USER_STATUS = 6,
BFCP_FLOOR_QUERY = 7,
BFCP_FLOOR_STATUS = 8,
BFCP_CHAIR_ACTION = 9,
BFCP_CHAIR_ACTION_ACK = 10,
BFCP_HELLO = 11,
BFCP_HELLO_ACK = 12,
BFCP_ERROR = 13,
BFCP_FLOOR_REQ_STATUS_ACK = 14,
BFCP_FLOOR_STATUS_ACK = 15,
BFCP_GOODBYE = 16,
BFCP_GOODBYE_ACK = 17,
};
/** BFCP Attributes */
enum bfcp_attrib {
BFCP_BENEFICIARY_ID = 1,
BFCP_FLOOR_ID = 2,
BFCP_FLOOR_REQUEST_ID = 3,
BFCP_PRIORITY = 4,
BFCP_REQUEST_STATUS = 5,
BFCP_ERROR_CODE = 6,
BFCP_ERROR_INFO = 7,
BFCP_PART_PROV_INFO = 8,
BFCP_STATUS_INFO = 9,
BFCP_SUPPORTED_ATTRS = 10,
BFCP_SUPPORTED_PRIMS = 11,
BFCP_USER_DISP_NAME = 12,
BFCP_USER_URI = 13,
/* grouped: */
BFCP_BENEFICIARY_INFO = 14,
BFCP_FLOOR_REQ_INFO = 15,
BFCP_REQUESTED_BY_INFO = 16,
BFCP_FLOOR_REQ_STATUS = 17,
BFCP_OVERALL_REQ_STATUS = 18,
/** Mandatory Attribute */
BFCP_MANDATORY = 1<<7,
/** Encode Handler */
BFCP_ENCODE_HANDLER = 1<<8,
};
/** BFCP Request Status */
enum bfcp_reqstat {
BFCP_PENDING = 1,
BFCP_ACCEPTED = 2,
BFCP_GRANTED = 3,
BFCP_DENIED = 4,
BFCP_CANCELLED = 5,
BFCP_RELEASED = 6,
BFCP_REVOKED = 7
};
/** BFCP Error Codes */
enum bfcp_err {
BFCP_CONF_NOT_EXIST = 1,
BFCP_USER_NOT_EXIST = 2,
BFCP_UNKNOWN_PRIM = 3,
BFCP_UNKNOWN_MAND_ATTR = 4,
BFCP_UNAUTH_OPERATION = 5,
BFCP_INVALID_FLOOR_ID = 6,
BFCP_FLOOR_REQ_ID_NOT_EXIST = 7,
BFCP_MAX_FLOOR_REQ_REACHED = 8,
BFCP_USE_TLS = 9,
BFCP_PARSE_ERROR = 10,
BFCP_USE_DTLS = 11,
BFCP_UNSUPPORTED_VERSION = 12,
BFCP_BAD_LENGTH = 13,
BFCP_GENERIC_ERROR = 14,
};
/** BFCP Priority */
enum bfcp_priority {
BFCP_PRIO_LOWEST = 0,
BFCP_PRIO_LOW = 1,
BFCP_PRIO_NORMAL = 2,
BFCP_PRIO_HIGH = 3,
BFCP_PRIO_HIGHEST = 4
};
/** BFCP Transport */
enum bfcp_transp {
BFCP_UDP,
BFCP_DTLS,
};
/** BFCP Request Status */
struct bfcp_reqstatus {
enum bfcp_reqstat status;
uint8_t qpos;
};
/** BFCP Error Code */
struct bfcp_errcode {
enum bfcp_err code;
uint8_t *details; /* optional */
size_t len;
};
/** BFCP Supported Attributes */
struct bfcp_supattr {
enum bfcp_attrib *attrv;
size_t attrc;
};
/** BFCP Supported Primitives */
struct bfcp_supprim {
enum bfcp_prim *primv;
size_t primc;
};
/** BFCP Attribute */
struct bfcp_attr {
struct le le;
struct list attrl;
enum bfcp_attrib type;
bool mand;
union bfcp_union {
/* generic types */
char *str;
uint16_t u16;
/* actual attributes */
uint16_t beneficiaryid;
uint16_t floorid;
uint16_t floorreqid;
enum bfcp_priority priority;
struct bfcp_reqstatus reqstatus;
struct bfcp_errcode errcode;
char *errinfo;
char *partprovinfo;
char *statusinfo;
struct bfcp_supattr supattr;
struct bfcp_supprim supprim;
char *userdname;
char *useruri;
uint16_t reqbyid;
} v;
};
/** BFCP unknown attributes */
struct bfcp_unknown_attr {
uint8_t typev[16];
size_t typec;
};
/** BFCP Message */
struct bfcp_msg {
struct bfcp_unknown_attr uma;
struct sa src;
uint8_t ver;
unsigned r:1;
unsigned f:1;
enum bfcp_prim prim;
uint16_t len;
uint32_t confid;
uint16_t tid;
uint16_t userid;
struct list attrl;
};
struct tls;
struct bfcp_conn;
/**
* Defines the BFCP encode handler
*
* @param mb Mbuf to encode into
* @param arg Handler argument
*
* @return 0 if success, otherwise errorcode
*/
typedef int (bfcp_encode_h)(struct mbuf *mb, void *arg);
/** BFCP Encode */
struct bfcp_encode {
bfcp_encode_h *ench;
void *arg;
};
/**
* Defines the BFCP attribute handler
*
* @param attr BFCP attribute
* @param arg Handler argument
*
* @return True to stop processing, false to continue
*/
typedef bool (bfcp_attr_h)(const struct bfcp_attr *attr, void *arg);
/**
* Defines the BFCP receive handler
*
* @param msg BFCP message
* @param arg Handler argument
*/
typedef void (bfcp_recv_h)(const struct bfcp_msg *msg, void *arg);
/**
* Defines the BFCP response handler
*
* @param err Error code
* @param msg BFCP message
* @param arg Handler argument
*/
typedef void (bfcp_resp_h)(int err, const struct bfcp_msg *msg, void *arg);
/* attr */
int bfcp_attrs_vencode(struct mbuf *mb, unsigned attrc, va_list *ap);
int bfcp_attrs_encode(struct mbuf *mb, unsigned attrc, ...);
struct bfcp_attr *bfcp_attr_subattr(const struct bfcp_attr *attr,
enum bfcp_attrib type);
struct bfcp_attr *bfcp_attr_subattr_apply(const struct bfcp_attr *attr,
bfcp_attr_h *h, void *arg);
int bfcp_attr_print(struct re_printf *pf, const struct bfcp_attr *attr);
const char *bfcp_attr_name(enum bfcp_attrib type);
const char *bfcp_reqstatus_name(enum bfcp_reqstat status);
const char *bfcp_errcode_name(enum bfcp_err code);
/* msg */
int bfcp_msg_vencode(struct mbuf *mb, uint8_t ver, bool r, enum bfcp_prim prim,
uint32_t confid, uint16_t tid, uint16_t userid,
unsigned attrc, va_list *ap);
int bfcp_msg_encode(struct mbuf *mb, uint8_t ver, bool r, enum bfcp_prim prim,
uint32_t confid, uint16_t tid, uint16_t userid,
unsigned attrc, ...);
int bfcp_msg_decode(struct bfcp_msg **msgp, struct mbuf *mb);
struct bfcp_attr *bfcp_msg_attr(const struct bfcp_msg *msg,
enum bfcp_attrib type);
struct bfcp_attr *bfcp_msg_attr_apply(const struct bfcp_msg *msg,
bfcp_attr_h *h, void *arg);
int bfcp_msg_print(struct re_printf *pf, const struct bfcp_msg *msg);
const char *bfcp_prim_name(enum bfcp_prim prim);
/* conn */
int bfcp_listen(struct bfcp_conn **bcp, enum bfcp_transp tp, struct sa *laddr,
struct tls *tls, bfcp_recv_h *recvh, void *arg);
void *bfcp_sock(const struct bfcp_conn *bc);
/* request */
int bfcp_request(struct bfcp_conn *bc, const struct sa *dst, uint8_t ver,
enum bfcp_prim prim, uint32_t confid, uint16_t userid,
bfcp_resp_h *resph, void *arg, unsigned attrc, ...);
/* notify */
int bfcp_notify(struct bfcp_conn *bc, const struct sa *dst, uint8_t ver,
enum bfcp_prim prim, uint32_t confid, uint16_t userid,
unsigned attrc, ...);
/* reply */
int bfcp_reply(struct bfcp_conn *bc, const struct bfcp_msg *req,
enum bfcp_prim prim, unsigned attrc, ...);
int bfcp_edreply(struct bfcp_conn *bc, const struct bfcp_msg *req,
enum bfcp_err code, const uint8_t *details, size_t len);
int bfcp_ereply(struct bfcp_conn *bc, const struct bfcp_msg *req,
enum bfcp_err code);

View file

@ -0,0 +1,73 @@
/**
* @file re_bitv.h Interface to Bit Vector functions
*
* Copyright (C) 2010 Creytiv.com
*/
typedef unsigned long bitv_t;
enum {
BITS_SZ = (8*sizeof(bitv_t)),
BITS_MASK = (BITS_SZ-1)
};
#define BITV_NELEM(nbits) (((nbits) + (BITS_SZ) - 1) / (BITS_SZ))
#define BITV_DECL(name, nbits) bitv_t (name)[BITV_NELEM(nbits)]
static inline uint32_t index2offset(uint32_t i)
{
return i/BITS_SZ;
}
static inline bitv_t index2bit(uint32_t i)
{
return (bitv_t)1<<(i & BITS_MASK);
}
/*
* Public API
*/
static inline void bitv_init(bitv_t *bv, uint32_t nbits, bool val)
{
memset(bv, val?0xff:0x00, BITV_NELEM(nbits)*sizeof(bitv_t));
}
static inline void bitv_set(bitv_t *bv, uint32_t i)
{
bv[index2offset(i)] |= index2bit(i);
}
static inline void bitv_clr(bitv_t *bv, uint32_t i)
{
bv[index2offset(i)] &= ~index2bit(i);
}
static inline void bitv_assign(bitv_t *bv, uint32_t i, bool val)
{
if (val)
bitv_set(bv, i);
else
bitv_clr(bv, i);
}
static inline bool bitv_val(const bitv_t *bv, uint32_t i)
{
return 0 != (bv[index2offset(i)] & index2bit(i));
}
static inline void bitv_toggle(bitv_t *bv, uint32_t i)
{
bv[index2offset(i)] ^= index2bit(i);
}
static inline void bitv_assign_range(bitv_t *bv, uint32_t i, uint32_t n,
bool val)
{
while (n--)
bitv_assign(bv, i+n, val);
}

View file

@ -0,0 +1,20 @@
/**
* @file re_conf.h Interface to configuration
*
* Copyright (C) 2010 Creytiv.com
*/
struct conf;
typedef int (conf_h)(const struct pl *val, void *arg);
int conf_alloc(struct conf **confp, const char *filename);
int conf_alloc_buf(struct conf **confp, const uint8_t *buf, size_t sz);
int conf_get(const struct conf *conf, const char *name, struct pl *pl);
int conf_get_str(const struct conf *conf, const char *name, char *str,
size_t size);
int conf_get_u32(const struct conf *conf, const char *name, uint32_t *num);
int conf_get_bool(const struct conf *conf, const char *name, bool *val);
int conf_apply(const struct conf *conf, const char *name,
conf_h *ch, void *arg);

View file

@ -0,0 +1,12 @@
/**
* @file re_crc32.h Interface to CRC-32 functions
*
* Copyright (C) 2010 Creytiv.com
*/
#ifdef USE_ZLIB
#include <zlib.h>
#else
uint32_t crc32(uint32_t crc, const void *buf, uint32_t size);
#endif

View file

@ -0,0 +1,194 @@
/**
* @file re_dbg.h Interface to debugging module
*
* Copyright (C) 2010 Creytiv.com
*/
#ifdef __cplusplus
extern "C" {
#endif
/** Debug levels */
enum {
DBG_EMERG = 0, /**< System is unusable */
DBG_ALERT = 1, /**< Action must be taken immediately */
DBG_CRIT = 2, /**< Critical conditions */
DBG_ERR = 3, /**< Error conditions */
DBG_WARNING = 4, /**< Warning conditions */
DBG_NOTICE = 5, /**< Normal but significant condition */
DBG_INFO = 6, /**< Informational */
DBG_DEBUG = 7 /**< Debug-level messages */
};
/**
* @def DEBUG_MODULE
*
* Module name defined by application
*/
/**
* @def DEBUG_LEVEL
*
* Debug level defined by application
*/
#ifndef DEBUG_MODULE
# warning "DEBUG_MODULE is not defined"
#define DEBUG_MODULE "?"
#endif
#ifndef DEBUG_LEVEL
# warning "DEBUG_LEVEL is not defined"
#define DEBUG_LEVEL 7
#endif
/**
* @def DEBUG_WARNING(...)
*
* Print warning message
*/
/**
* @def DEBUG_NOTICE(...)
*
* Print notice message
*/
/**
* @def DEBUG_INFO(...)
*
* Print info message
*/
/**
* @def DEBUG_PRINTF(...)
*
* Print debug message
*/
/* Check for ISO C99 variable argument macros */
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
|| (__GNUC__ >= 3)
#if (DEBUG_LEVEL >= 4)
#define DEBUG_WARNING(...) \
dbg_printf(DBG_WARNING, DEBUG_MODULE ": " __VA_ARGS__)
#else
#define DEBUG_WARNING(...)
#endif
#if (DEBUG_LEVEL >= 5)
#define DEBUG_NOTICE(...) \
dbg_printf(DBG_NOTICE, DEBUG_MODULE ": " __VA_ARGS__)
#else
#define DEBUG_NOTICE(...)
#endif
#if (DEBUG_LEVEL >= 6)
#define DEBUG_INFO(...) \
dbg_printf(DBG_INFO, DEBUG_MODULE ": " __VA_ARGS__)
#else
#define DEBUG_INFO(...)
#endif
#if (DEBUG_LEVEL >= 7)
#define DEBUG_PRINTF(...) \
dbg_printf(DBG_DEBUG, DEBUG_MODULE ": " __VA_ARGS__)
#else
#define DEBUG_PRINTF(...)
#endif
/* GNU extensions for variable argument macros */
#elif defined(__GNUC__)
#if (DEBUG_LEVEL >= 4)
#define DEBUG_WARNING(a...) dbg_printf(DBG_WARNING, DEBUG_MODULE ": " a)
#else
#define DEBUG_WARNING(a...)
#endif
#if (DEBUG_LEVEL >= 5)
#define DEBUG_NOTICE(a...) dbg_printf(DBG_NOTICE, DEBUG_MODULE ": " a)
#else
#define DEBUG_NOTICE(a...)
#endif
#if (DEBUG_LEVEL >= 6)
#define DEBUG_INFO(a...) dbg_printf(DBG_INFO, DEBUG_MODULE ": " a)
#else
#define DEBUG_INFO(a...)
#endif
#if (DEBUG_LEVEL >= 7)
#define DEBUG_PRINTF(a...) dbg_printf(DBG_DEBUG, DEBUG_MODULE ": " a)
#else
#define DEBUG_PRINTF(a...)
#endif
/* No variable argument macros */
#else
#if (DEBUG_LEVEL >= 4)
#define DEBUG_WARNING dbg_warning
#else
#define DEBUG_WARNING dbg_noprintf
#endif
#if (DEBUG_LEVEL >= 5)
#define DEBUG_NOTICE dbg_notice
#else
#define DEBUG_NOTICE dbg_noprintf
#endif
#if (DEBUG_LEVEL >= 6)
#define DEBUG_INFO dbg_info
#else
#define DEBUG_INFO dbg_noprintf
#endif
#if (DEBUG_LEVEL >= 7)
#define DEBUG_PRINTF dbg_noprintf
#else
#define DEBUG_PRINTF dbg_noprintf
#endif
#endif
/** Debug flags */
enum dbg_flags {
DBG_NONE = 0, /**< No debug flags */
DBG_TIME = 1<<0, /**< Print timestamp flag */
DBG_ANSI = 1<<1, /**< Print ANSI color codes */
DBG_ALL = DBG_TIME|DBG_ANSI /**< All flags enabled */
};
/**
* Defines the debug print handler
*
* @param level Debug level
* @param p Debug string
* @param len String length
* @param arg Handler argument
*/
typedef void (dbg_print_h)(int level, const char *p, size_t len, void *arg);
void dbg_init(int level, enum dbg_flags flags);
void dbg_close(void);
int dbg_logfile_set(const char *name);
void dbg_handler_set(dbg_print_h *ph, void *arg);
#undef dbg_printf
void dbg_printf(int level, const char *fmt, ...);
void dbg_noprintf(const char *fmt, ...);
void dbg_warning(const char *fmt, ...);
void dbg_notice(const char *fmt, ...);
void dbg_info(const char *fmt, ...);
const char *dbg_level_str(int level);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,218 @@
/**
* @file re_dns.h Interface to DNS module
*
* Copyright (C) 2010 Creytiv.com
*/
enum {
DNS_PORT = 53,
DNS_HEADER_SIZE = 12
};
/** DNS Opcodes */
enum {
DNS_OPCODE_QUERY = 0,
DNS_OPCODE_IQUERY = 1,
DNS_OPCODE_STATUS = 2,
DNS_OPCODE_NOTIFY = 4
};
/** DNS Response codes */
enum {
DNS_RCODE_OK = 0,
DNS_RCODE_FMT_ERR = 1,
DNS_RCODE_SRV_FAIL = 2,
DNS_RCODE_NAME_ERR = 3,
DNS_RCODE_NOT_IMPL = 4,
DNS_RCODE_REFUSED = 5,
DNS_RCODE_NOT_AUTH = 9
};
/** DNS Resource Record types */
enum {
DNS_TYPE_A = 0x0001,
DNS_TYPE_NS = 0x0002,
DNS_TYPE_CNAME = 0x0005,
DNS_TYPE_SOA = 0x0006,
DNS_TYPE_PTR = 0x000c,
DNS_TYPE_MX = 0x000f,
DNS_TYPE_AAAA = 0x001c,
DNS_TYPE_SRV = 0x0021,
DNS_TYPE_NAPTR = 0x0023,
DNS_QTYPE_IXFR = 0x00fb,
DNS_QTYPE_AXFR = 0x00fc,
DNS_QTYPE_ANY = 0x00ff
};
/** DNS Classes */
enum {
DNS_CLASS_IN = 0x0001,
DNS_QCLASS_ANY = 0x00ff
};
/** Defines a DNS Header */
struct dnshdr {
uint16_t id;
bool qr;
uint8_t opcode;
bool aa;
bool tc;
bool rd;
bool ra;
uint8_t z;
uint8_t rcode;
uint16_t nq;
uint16_t nans;
uint16_t nauth;
uint16_t nadd;
};
/** Defines a DNS Resource Record (RR) */
struct dnsrr {
struct le le;
struct le le_priv;
char *name;
uint16_t type;
uint16_t dnsclass;
int64_t ttl;
uint16_t rdlen;
union {
struct {
uint32_t addr;
} a;
struct {
char *nsdname;
} ns;
struct {
char *cname;
} cname;
struct {
char *mname;
char *rname;
uint32_t serial;
uint32_t refresh;
uint32_t retry;
uint32_t expire;
uint32_t ttlmin;
} soa;
struct {
char *ptrdname;
} ptr;
struct {
uint16_t pref;
char *exchange;
} mx;
struct {
uint8_t addr[16];
} aaaa;
struct {
uint16_t pri;
uint16_t weight;
uint16_t port;
char *target;
} srv;
struct {
uint16_t order;
uint16_t pref;
char *flags;
char *services;
char *regexp;
char *replace;
} naptr;
} rdata;
};
struct hash;
/**
* Defines the DNS Query handler
*
* @param err 0 if success, otherwise errorcode
* @param hdr DNS Header
* @param ansl List of Answer records
* @param authl List of Authoritive records
* @param addl List of Additional records
* @param arg Handler argument
*/
typedef void(dns_query_h)(int err, const struct dnshdr *hdr,
struct list *ansl, struct list *authl,
struct list *addl, void *arg);
/**
* Defines the DNS Resource Record list handler
*
* @param rr DNS Resource Record
* @param arg Handler argument
*
* @return True to stop traversing, False to continue
*/
typedef bool(dns_rrlist_h)(struct dnsrr *rr, void *arg);
int dns_hdr_encode(struct mbuf *mb, const struct dnshdr *hdr);
int dns_hdr_decode(struct mbuf *mb, struct dnshdr *hdr);
const char *dns_hdr_opcodename(uint8_t opcode);
const char *dns_hdr_rcodename(uint8_t rcode);
struct dnsrr *dns_rr_alloc(void);
int dns_rr_encode(struct mbuf *mb, const struct dnsrr *rr, int64_t ttl_offs,
struct hash *ht_dname, size_t start);
int dns_rr_decode(struct mbuf *mb, struct dnsrr **rr, size_t start);
bool dns_rr_cmp(const struct dnsrr *rr1, const struct dnsrr *rr2, bool rdata);
const char *dns_rr_typename(uint16_t type);
const char *dns_rr_classname(uint16_t dnsclass);
int dns_rr_print(struct re_printf *pf, const struct dnsrr *rr);
int dns_dname_encode(struct mbuf *mb, const char *name,
struct hash *ht_dname, size_t start, bool comp);
int dns_dname_decode(struct mbuf *mb, char **name, size_t start);
int dns_cstr_encode(struct mbuf *mb, const char *str);
int dns_cstr_decode(struct mbuf *mb, char **str);
void dns_rrlist_sort(struct list *rrl, uint16_t type, size_t key);
void dns_rrlist_sort_addr(struct list *rrl, size_t key);
struct dnsrr *dns_rrlist_apply(struct list *rrl, const char *name,
uint16_t type, uint16_t dnsclass,
bool recurse, dns_rrlist_h *rrlh, void *arg);
struct dnsrr *dns_rrlist_apply2(struct list *rrl, const char *name,
uint16_t type1, uint16_t type2,
uint16_t dnsclass, bool recurse,
dns_rrlist_h *rrlh, void *arg);
struct dnsrr *dns_rrlist_find(struct list *rrl, const char *name,
uint16_t type, uint16_t dnsclass, bool recurse);
/* DNS Client */
struct sa;
struct dnsc;
struct dns_query;
/** DNS Client configuration */
struct dnsc_conf {
uint32_t query_hash_size;
uint32_t tcp_hash_size;
uint32_t conn_timeout; /* in [ms] */
uint32_t idle_timeout; /* in [ms] */
};
int dnsc_alloc(struct dnsc **dcpp, const struct dnsc_conf *conf,
const struct sa *srvv, uint32_t srvc);
int dnsc_srv_set(struct dnsc *dnsc, const struct sa *srvv, uint32_t srvc);
int dnsc_query(struct dns_query **qp, struct dnsc *dnsc, const char *name,
uint16_t type, uint16_t dnsclass,
bool rd, dns_query_h *qh, void *arg);
int dnsc_query_srv(struct dns_query **qp, struct dnsc *dnsc, const char *name,
uint16_t type, uint16_t dnsclass, int proto,
const struct sa *srvv, const uint32_t *srvc,
bool rd, dns_query_h *qh, void *arg);
int dnsc_notify(struct dns_query **qp, struct dnsc *dnsc, const char *name,
uint16_t type, uint16_t dnsclass, const struct dnsrr *ans_rr,
int proto, const struct sa *srvv, const uint32_t *srvc,
dns_query_h *qh, void *arg);
/* DNS System functions */
int dns_srv_get(char *domain, size_t dsize, struct sa *srvv, uint32_t *n);

View file

@ -0,0 +1,147 @@
/**
* @file re_fmt.h Interface to formatted text functions
*
* Copyright (C) 2010 Creytiv.com
*/
#include <stdarg.h>
#include <stdio.h>
struct mbuf;
/** Defines a pointer-length string type */
struct pl {
const char *p; /**< Pointer to string */
size_t l; /**< Length of string */
};
/** Initialise a pointer-length object from a constant string */
#define PL(s) {(s), sizeof((s))-1}
/** Pointer-length Initializer */
#define PL_INIT {NULL, 0}
extern const struct pl pl_null;
void pl_set_str(struct pl *pl, const char *str);
void pl_set_mbuf(struct pl *pl, const struct mbuf *mb);
uint32_t pl_u32(const struct pl *pl);
uint32_t pl_x32(const struct pl *pl);
uint64_t pl_u64(const struct pl *pl);
uint64_t pl_x64(const struct pl *pl);
double pl_float(const struct pl *pl);
bool pl_isset(const struct pl *pl);
int pl_strcpy(const struct pl *pl, char *str, size_t size);
int pl_strdup(char **dst, const struct pl *src);
int pl_dup(struct pl *dst, const struct pl *src);
int pl_strcmp(const struct pl *pl, const char *str);
int pl_strcasecmp(const struct pl *pl, const char *str);
int pl_cmp(const struct pl *pl1, const struct pl *pl2);
int pl_casecmp(const struct pl *pl1, const struct pl *pl2);
const char *pl_strchr(const struct pl *pl, char c);
/** Advance pl position/length by +/- N bytes */
static inline void pl_advance(struct pl *pl, ssize_t n)
{
pl->p += n;
pl->l -= n;
}
/* Formatted printing */
/**
* Defines the re_vhprintf() print handler
*
* @param p String to print
* @param size Size of string to print
* @param arg Handler argument
*
* @return 0 for success, otherwise errorcode
*/
typedef int(re_vprintf_h)(const char *p, size_t size, void *arg);
/** Defines a print backend */
struct re_printf {
re_vprintf_h *vph; /**< Print handler */
void *arg; /**< Handler agument */
};
/**
* Defines the %H print handler
*
* @param pf Print backend
* @param arg Handler argument
*
* @return 0 for success, otherwise errorcode
*/
typedef int(re_printf_h)(struct re_printf *pf, void *arg);
int re_vhprintf(const char *fmt, va_list ap, re_vprintf_h *vph, void *arg);
int re_vfprintf(FILE *stream, const char *fmt, va_list ap);
int re_vprintf(const char *fmt, va_list ap);
int re_vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
int re_vsdprintf(char **strp, const char *fmt, va_list ap);
int re_hprintf(struct re_printf *pf, const char *fmt, ...);
int re_fprintf(FILE *stream, const char *fmt, ...);
int re_printf(const char *fmt, ...);
int re_snprintf(char *str, size_t size, const char *fmt, ...);
int re_sdprintf(char **strp, const char *fmt, ...);
/* Regular expressions */
int re_regex(const char *ptr, size_t len, const char *expr, ...);
/* Character functions */
uint8_t ch_hex(char ch);
/* String functions */
int str_hex(uint8_t *hex, size_t len, const char *str);
void str_ncpy(char *dst, const char *src, size_t n);
int str_dup(char **dst, const char *src);
int str_cmp(const char *s1, const char *s2);
int str_casecmp(const char *s1, const char *s2);
size_t str_len(const char *s);
const char *str_error(int errnum, char *buf, size_t sz);
/**
* Check if string is set
*
* @param s Zero-terminated string
*
* @return true if set, false if not set
*/
static inline bool str_isset(const char *s)
{
return s && s[0] != '\0';
}
/* time */
int fmt_gmtime(struct re_printf *pf, void *ts);
int fmt_human_time(struct re_printf *pf, const uint32_t *seconds);
void hexdump(FILE *f, const void *p, size_t len);
/* param */
typedef void (fmt_param_h)(const struct pl *name, const struct pl *val,
void *arg);
bool fmt_param_exists(const struct pl *pl, const char *pname);
bool fmt_param_get(const struct pl *pl, const char *pname, struct pl *val);
void fmt_param_apply(const struct pl *pl, fmt_param_h *ph, void *arg);
/* unicode */
int utf8_encode(struct re_printf *pf, const char *str);
int utf8_decode(struct re_printf *pf, const struct pl *pl);
size_t utf8_byteseq(char u[4], unsigned cp);

View file

@ -0,0 +1,33 @@
/**
* @file re_hash.h Interface to hashmap table
*
* Copyright (C) 2010 Creytiv.com
*/
struct hash;
struct pl;
int hash_alloc(struct hash **hp, uint32_t bsize);
void hash_append(struct hash *h, uint32_t key, struct le *le, void *data);
void hash_unlink(struct le *le);
struct le *hash_lookup(const struct hash *h, uint32_t key, list_apply_h *ah,
void *arg);
struct le *hash_apply(const struct hash *h, list_apply_h *ah, void *arg);
struct list *hash_list(const struct hash *h, uint32_t key);
uint32_t hash_bsize(const struct hash *h);
void hash_flush(struct hash *h);
void hash_clear(struct hash *h);
uint32_t hash_valid_size(uint32_t size);
/* Hash functions */
uint32_t hash_joaat(const uint8_t *key, size_t len);
uint32_t hash_joaat_ci(const char *str, size_t len);
uint32_t hash_joaat_str(const char *str);
uint32_t hash_joaat_str_ci(const char *str);
uint32_t hash_joaat_pl(const struct pl *pl);
uint32_t hash_joaat_pl_ci(const struct pl *pl);
uint32_t hash_fast(const char *k, size_t len);
uint32_t hash_fast_str(const char *str);

View file

@ -0,0 +1,26 @@
/**
* @file re_hmac.h Interface to HMAC functions
*
* Copyright (C) 2010 Creytiv.com
*/
void hmac_sha1(const uint8_t *k, /* secret key */
size_t lk, /* length of the key in bytes */
const uint8_t *d, /* data */
size_t ld, /* length of data in bytes */
uint8_t* out, /* output buffer, at least "t" bytes */
size_t t);
enum hmac_hash {
HMAC_HASH_SHA1,
HMAC_HASH_SHA256
};
struct hmac;
int hmac_create(struct hmac **hmacp, enum hmac_hash hash,
const uint8_t *key, size_t key_len);
int hmac_digest(struct hmac *hmac, uint8_t *md, size_t md_len,
const uint8_t *data, size_t data_len);

View file

@ -0,0 +1,171 @@
/**
* @file re_http.h Hypertext Transfer Protocol
*
* Copyright (C) 2010 Creytiv.com
*/
/** HTTP Header ID (perfect hash value) */
enum http_hdrid {
HTTP_HDR_ACCEPT = 3186,
HTTP_HDR_ACCEPT_CHARSET = 24,
HTTP_HDR_ACCEPT_ENCODING = 708,
HTTP_HDR_ACCEPT_LANGUAGE = 2867,
HTTP_HDR_ACCEPT_RANGES = 3027,
HTTP_HDR_AGE = 742,
HTTP_HDR_ALLOW = 2429,
HTTP_HDR_AUTHORIZATION = 2503,
HTTP_HDR_CACHE_CONTROL = 2530,
HTTP_HDR_CONNECTION = 865,
HTTP_HDR_CONTENT_ENCODING = 580,
HTTP_HDR_CONTENT_LANGUAGE = 3371,
HTTP_HDR_CONTENT_LENGTH = 3861,
HTTP_HDR_CONTENT_LOCATION = 3927,
HTTP_HDR_CONTENT_MD5 = 406,
HTTP_HDR_CONTENT_RANGE = 2846,
HTTP_HDR_CONTENT_TYPE = 809,
HTTP_HDR_DATE = 1027,
HTTP_HDR_ETAG = 2392,
HTTP_HDR_EXPECT = 1550,
HTTP_HDR_EXPIRES = 1983,
HTTP_HDR_FROM = 1963,
HTTP_HDR_HOST = 3191,
HTTP_HDR_IF_MATCH = 2684,
HTTP_HDR_IF_MODIFIED_SINCE = 2187,
HTTP_HDR_IF_NONE_MATCH = 4030,
HTTP_HDR_IF_RANGE = 2220,
HTTP_HDR_IF_UNMODIFIED_SINCE = 962,
HTTP_HDR_LAST_MODIFIED = 2946,
HTTP_HDR_LOCATION = 2514,
HTTP_HDR_MAX_FORWARDS = 3549,
HTTP_HDR_PRAGMA = 1673,
HTTP_HDR_PROXY_AUTHENTICATE = 116,
HTTP_HDR_PROXY_AUTHORIZATION = 2363,
HTTP_HDR_RANGE = 4004,
HTTP_HDR_REFERER = 2991,
HTTP_HDR_RETRY_AFTER = 409,
HTTP_HDR_SEC_WEBSOCKET_ACCEPT = 2959,
HTTP_HDR_SEC_WEBSOCKET_EXTENSIONS = 2937,
HTTP_HDR_SEC_WEBSOCKET_KEY = 746,
HTTP_HDR_SEC_WEBSOCKET_PROTOCOL = 2076,
HTTP_HDR_SEC_WEBSOCKET_VERSION = 3158,
HTTP_HDR_SERVER = 973,
HTTP_HDR_TE = 2035,
HTTP_HDR_TRAILER = 2577,
HTTP_HDR_TRANSFER_ENCODING = 2115,
HTTP_HDR_UPGRADE = 717,
HTTP_HDR_USER_AGENT = 4064,
HTTP_HDR_VARY = 3076,
HTTP_HDR_VIA = 3961,
HTTP_HDR_WARNING = 2108,
HTTP_HDR_WWW_AUTHENTICATE = 2763,
HTTP_HDR_NONE = -1
};
/** HTTP Header */
struct http_hdr {
struct le le; /**< Linked-list element */
struct pl name; /**< HTTP Header name */
struct pl val; /**< HTTP Header value */
enum http_hdrid id; /**< HTTP Header id (unique) */
};
/** HTTP Message */
struct http_msg {
struct pl ver; /**< HTTP Version number */
struct pl met; /**< Request Method */
struct pl path; /**< Request path/resource */
struct pl prm; /**< Request parameters */
uint16_t scode; /**< Response Status code */
struct pl reason; /**< Response Reason phrase */
struct list hdrl; /**< List of HTTP headers (struct http_hdr) */
struct msg_ctype ctyp; /**< Content-type */
struct mbuf *_mb; /**< Buffer containing the HTTP message */
struct mbuf *mb; /**< Buffer containing the HTTP body */
uint32_t clen; /**< Content length */
};
typedef bool(http_hdr_h)(const struct http_hdr *hdr, void *arg);
int http_msg_decode(struct http_msg **msgp, struct mbuf *mb, bool req);
const struct http_hdr *http_msg_hdr(const struct http_msg *msg,
enum http_hdrid id);
const struct http_hdr *http_msg_hdr_apply(const struct http_msg *msg,
bool fwd, enum http_hdrid id,
http_hdr_h *h, void *arg);
const struct http_hdr *http_msg_xhdr(const struct http_msg *msg,
const char *name);
const struct http_hdr *http_msg_xhdr_apply(const struct http_msg *msg,
bool fwd, const char *name,
http_hdr_h *h, void *arg);
uint32_t http_msg_hdr_count(const struct http_msg *msg, enum http_hdrid id);
uint32_t http_msg_xhdr_count(const struct http_msg *msg, const char *name);
bool http_msg_hdr_has_value(const struct http_msg *msg, enum http_hdrid id,
const char *value);
bool http_msg_xhdr_has_value(const struct http_msg *msg, const char *name,
const char *value);
int http_msg_print(struct re_printf *pf, const struct http_msg *msg);
/* Client */
struct http_cli;
struct http_req;
struct dnsc;
struct tcp_conn;
struct tls_conn;
typedef void (http_resp_h)(int err, const struct http_msg *msg, void *arg);
typedef int (http_data_h)(const uint8_t *buf, size_t size,
const struct http_msg *msg, void *arg);
typedef void (http_conn_h)(struct tcp_conn *tc, struct tls_conn *sc,
void *arg);
int http_client_alloc(struct http_cli **clip, struct dnsc *dnsc);
int http_request(struct http_req **reqp, struct http_cli *cli, const char *met,
const char *uri, http_resp_h *resph, http_data_h *datah,
void *arg, const char *fmt, ...);
void http_req_set_conn_handler(struct http_req *req, http_conn_h *connh);
/* Server */
struct http_sock;
struct http_conn;
typedef void (http_req_h)(struct http_conn *conn, const struct http_msg *msg,
void *arg);
int http_listen(struct http_sock **sockp, const struct sa *laddr,
http_req_h *reqh, void *arg);
int https_listen(struct http_sock **sockp, const struct sa *laddr,
const char *cert, http_req_h *reqh, void *arg);
struct tcp_sock *http_sock_tcp(struct http_sock *sock);
const struct sa *http_conn_peer(const struct http_conn *conn);
struct tcp_conn *http_conn_tcp(struct http_conn *conn);
struct tls_conn *http_conn_tls(struct http_conn *conn);
void http_conn_close(struct http_conn *conn);
int http_reply(struct http_conn *conn, uint16_t scode, const char *reason,
const char *fmt, ...);
int http_creply(struct http_conn *conn, uint16_t scode, const char *reason,
const char *ctype, const char *fmt, ...);
int http_ereply(struct http_conn *conn, uint16_t scode, const char *reason);
/* Authentication */
struct http_auth {
const char *realm;
bool stale;
};
typedef int (http_auth_h)(const struct pl *username, uint8_t *ha1, void *arg);
int http_auth_print_challenge(struct re_printf *pf,
const struct http_auth *auth);
bool http_auth_check(const struct pl *hval, const struct pl *method,
struct http_auth *auth, http_auth_h *authh, void *arg);
bool http_auth_check_request(const struct http_msg *msg,
struct http_auth *auth,
http_auth_h *authh, void *arg);

View file

@ -0,0 +1,40 @@
/**
* @file re_httpauth.h Interface to HTTP Authentication
*
* Copyright (C) 2010 Creytiv.com
*/
/** HTTP Digest Challenge */
struct httpauth_digest_chall {
struct pl realm;
struct pl nonce;
/* optional */
struct pl opaque;
struct pl stale;
struct pl algorithm;
struct pl qop;
};
/** HTTP Digest response */
struct httpauth_digest_resp {
struct pl realm;
struct pl nonce;
struct pl response;
struct pl username;
struct pl uri;
/* optional */
struct pl nc;
struct pl cnonce;
struct pl qop;
};
int httpauth_digest_challenge_decode(struct httpauth_digest_chall *chall,
const struct pl *hval);
int httpauth_digest_response_decode(struct httpauth_digest_resp *resp,
const struct pl *hval);
int httpauth_digest_response_auth(const struct httpauth_digest_resp *resp,
const struct pl *method, const uint8_t *ha1);

View file

@ -0,0 +1,161 @@
/**
* @file re_ice.h Interface to Interactive Connectivity Establishment (ICE)
*
* Copyright (C) 2010 Creytiv.com
*/
/** ICE mode */
enum ice_mode {
ICE_MODE_FULL,
ICE_MODE_LITE
};
/** ICE Role */
enum ice_role {
ICE_ROLE_UNKNOWN = 0,
ICE_ROLE_CONTROLLING,
ICE_ROLE_CONTROLLED
};
/** ICE Component ID */
enum ice_compid {
ICE_COMPID_RTP = 1,
ICE_COMPID_RTCP = 2
};
/** ICE Nomination */
enum ice_nomination {
ICE_NOMINATION_REGULAR = 0,
ICE_NOMINATION_AGGRESSIVE
};
/** ICE Candidate type */
enum ice_cand_type {
ICE_CAND_TYPE_HOST, /**< Host candidate */
ICE_CAND_TYPE_SRFLX, /**< Server Reflexive candidate */
ICE_CAND_TYPE_PRFLX, /**< Peer Reflexive candidate */
ICE_CAND_TYPE_RELAY /**< Relayed candidate */
};
/** ICE TCP protocol type */
enum ice_tcptype {
ICE_TCP_ACTIVE, /**< Active TCP client */
ICE_TCP_PASSIVE, /**< Passive TCP server */
ICE_TCP_SO /**< Simultaneous-open TCP client/server */
};
/** Candidate pair states */
enum ice_candpair_state {
ICE_CANDPAIR_FROZEN = 0, /**< Frozen state (default) */
ICE_CANDPAIR_WAITING, /**< Waiting to become highest on list */
ICE_CANDPAIR_INPROGRESS, /**< In-Progress state;transac. in progress */
ICE_CANDPAIR_SUCCEEDED, /**< Succeeded state; successful result */
ICE_CANDPAIR_FAILED /**< Failed state; check failed */
};
struct ice;
struct ice_cand;
struct icem;
struct turnc;
/** ICE Configuration */
struct ice_conf {
enum ice_nomination nom; /**< Nomination algorithm */
uint32_t rto; /**< STUN Retransmission TimeOut */
uint32_t rc; /**< STUN Retransmission Count */
bool debug; /**< Enable ICE debugging */
};
typedef void (ice_connchk_h)(int err, bool update, void *arg);
/* ICE Media */
int icem_alloc(struct icem **icemp, enum ice_mode mode,
enum ice_role role, int proto, int layer,
uint64_t tiebrk, const char *lufrag, const char *lpwd,
ice_connchk_h *chkh, void *arg);
struct ice_conf *icem_conf(struct icem *icem);
enum ice_role icem_local_role(const struct icem *icem);
void icem_set_conf(struct icem *icem, const struct ice_conf *conf);
void icem_set_role(struct icem *icem, enum ice_role role);
void icem_set_name(struct icem *icem, const char *name);
int icem_comp_add(struct icem *icem, unsigned compid, void *sock);
int icem_cand_add(struct icem *icem, unsigned compid, uint16_t lprio,
const char *ifname, const struct sa *addr);
int icem_lite_set_default_candidates(struct icem *icem);
bool icem_verify_support(struct icem *icem, unsigned compid,
const struct sa *raddr);
int icem_conncheck_start(struct icem *icem);
void icem_conncheck_stop(struct icem *icem, int err);
int icem_add_chan(struct icem *icem, unsigned compid, const struct sa *raddr);
bool icem_mismatch(const struct icem *icem);
void icem_update(struct icem *icem);
int ice_sdp_decode(struct icem *ice, const char *name, const char *value);
int icem_sdp_decode(struct icem *icem, const char *name, const char *value);
int icem_debug(struct re_printf *pf, const struct icem *icem);
struct list *icem_lcandl(const struct icem *icem);
struct list *icem_rcandl(const struct icem *icem);
struct list *icem_checkl(const struct icem *icem);
struct list *icem_validl(const struct icem *icem);
const struct sa *icem_cand_default(struct icem *icem, unsigned compid);
const struct sa *icem_selected_laddr(const struct icem *icem, unsigned compid);
const struct ice_cand *icem_selected_lcand(const struct icem *icem,
unsigned compid);
const struct ice_cand *icem_selected_rcand(const struct icem *icem,
unsigned compid);
void ice_candpair_set_states(struct icem *icem);
void icem_cand_redund_elim(struct icem *icem);
int icem_comps_set_default_cand(struct icem *icem);
struct stun *icem_stun(struct icem *icem);
int icem_set_turn_client(struct icem *icem, unsigned compid,
struct turnc *turnc);
bool ice_remotecands_avail(const struct icem *icem);
int ice_cand_encode(struct re_printf *pf, const struct ice_cand *cand);
int ice_remotecands_encode(struct re_printf *pf, const struct icem *icem);
struct ice_cand *icem_cand_find(const struct list *lst, unsigned compid,
const struct sa *addr);
int icem_lcand_add(struct icem *icem, struct ice_cand *base,
enum ice_cand_type type,
const struct sa *addr);
struct ice_cand *icem_lcand_base(struct ice_cand *lcand);
const struct sa *icem_lcand_addr(const struct ice_cand *cand);
enum ice_cand_type icem_cand_type(const struct ice_cand *cand);
extern const char ice_attr_cand[];
extern const char ice_attr_lite[];
extern const char ice_attr_mismatch[];
extern const char ice_attr_pwd[];
extern const char ice_attr_remote_cand[];
extern const char ice_attr_ufrag[];
const char *ice_cand_type2name(enum ice_cand_type type);
enum ice_cand_type ice_cand_name2type(const char *name);
const char *ice_role2name(enum ice_role role);
const char *ice_candpair_state2name(enum ice_candpair_state st);
uint32_t ice_cand_calc_prio(enum ice_cand_type type, uint16_t local,
unsigned compid);
/** Defines an SDP candidate attribute */
struct ice_cand_attr {
char foundation[32]; /**< Foundation string */
unsigned compid; /**< Component ID (1-256) */
int proto; /**< Transport protocol */
uint32_t prio; /**< Priority of this candidate */
struct sa addr; /**< Transport address */
enum ice_cand_type type; /**< Candidate type */
struct sa rel_addr; /**< Related transport address (optional) */
enum ice_tcptype tcptype; /**< TCP candidate type (TCP-only) */
};
int ice_cand_attr_encode(struct re_printf *pf,
const struct ice_cand_attr *cand);
int ice_cand_attr_decode(struct ice_cand_attr *cand, const char *val);

View file

@ -0,0 +1,28 @@
/**
* @file re_jbuf.h Interface to Jitter Buffer
*
* Copyright (C) 2010 Creytiv.com
*/
struct jbuf;
struct rtp_header;
/** Jitter buffer statistics */
struct jbuf_stat {
uint32_t n_put; /**< Number of frames put into jitter buffer */
uint32_t n_get; /**< Number of frames got from jitter buffer */
uint32_t n_oos; /**< Number of out-of-sequence frames */
uint32_t n_dups; /**< Number of duplicate frames detected */
uint32_t n_late; /**< Number of frames arriving too late */
uint32_t n_lost; /**< Number of lost frames */
uint32_t n_overflow; /**< Number of overflows */
uint32_t n_underflow; /**< Number of underflows */
uint32_t n_flush; /**< Number of times jitter buffer flushed */
};
int jbuf_alloc(struct jbuf **jbp, uint32_t min, uint32_t max);
int jbuf_put(struct jbuf *jb, const struct rtp_header *hdr, void *mem);
int jbuf_get(struct jbuf *jb, struct rtp_header *hdr, void **mem);
void jbuf_flush(struct jbuf *jb);
int jbuf_stats(const struct jbuf *jb, struct jbuf_stat *jstat);
int jbuf_debug(struct re_printf *pf, const struct jbuf *jb);

View file

@ -0,0 +1,50 @@
/**
* @file re_json.h Interface to JavaScript Object Notation (JSON) -- RFC 7159
*
* Copyright (C) 2010 - 2015 Creytiv.com
*/
enum json_typ {
JSON_STRING,
JSON_INT,
JSON_DOUBLE,
JSON_BOOL,
JSON_NULL,
};
struct json_value {
union {
char *str;
int64_t integer;
double dbl;
bool boolean;
} v;
enum json_typ type;
};
struct json_handlers;
typedef int (json_object_entry_h)(const char *name,
const struct json_value *value, void *arg);
typedef int (json_array_entry_h)(unsigned idx,
const struct json_value *value, void *arg);
typedef int (json_object_h)(const char *name, unsigned idx,
struct json_handlers *h);
typedef int (json_array_h)(const char *name, unsigned idx,
struct json_handlers *h);
struct json_handlers {
json_object_h *oh;
json_array_h *ah;
json_object_entry_h *oeh;
json_array_entry_h *aeh;
void *arg;
};
int json_decode(const char *str, size_t len, unsigned maxdepth,
json_object_h *oh, json_array_h *ah,
json_object_entry_h *oeh, json_array_entry_h *aeh, void *arg);
int json_decode_odict(struct odict **op, uint32_t hash_size, const char *str,
size_t len, unsigned maxdepth);
int json_encode_odict(struct re_printf *pf, const struct odict *o);

View file

@ -0,0 +1,96 @@
/**
* @file re_list.h Interface to Linked List
*
* Copyright (C) 2010 Creytiv.com
*/
/** Linked-list element */
struct le {
struct le *prev; /**< Previous element */
struct le *next; /**< Next element */
struct list *list; /**< Parent list (NULL if not linked-in) */
void *data; /**< User-data */
};
/** List Element Initializer */
#define LE_INIT {NULL, NULL, NULL, NULL}
/** Defines a linked list */
struct list {
struct le *head; /**< First list element */
struct le *tail; /**< Last list element */
};
/** Linked list Initializer */
#define LIST_INIT {NULL, NULL}
/**
* Defines the list apply handler
*
* @param le List element
* @param arg Handler argument
*
* @return true to stop traversing, false to continue
*/
typedef bool (list_apply_h)(struct le *le, void *arg);
/**
* Defines the list sort handler
*
* @param le1 Current list element
* @param le2 Next list element
* @param arg Handler argument
*
* @return true if sorted, otherwise false
*/
typedef bool (list_sort_h)(struct le *le1, struct le *le2, void *arg);
void list_init(struct list *list);
void list_flush(struct list *list);
void list_clear(struct list *list);
void list_append(struct list *list, struct le *le, void *data);
void list_prepend(struct list *list, struct le *le, void *data);
void list_insert_before(struct list *list, struct le *le, struct le *ile,
void *data);
void list_insert_after(struct list *list, struct le *le, struct le *ile,
void *data);
void list_unlink(struct le *le);
void list_sort(struct list *list, list_sort_h *sh, void *arg);
struct le *list_apply(const struct list *list, bool fwd, list_apply_h *ah,
void *arg);
struct le *list_head(const struct list *list);
struct le *list_tail(const struct list *list);
uint32_t list_count(const struct list *list);
/**
* Get the user-data from a list element
*
* @param le List element
*
* @return Pointer to user-data
*/
static inline void *list_ledata(const struct le *le)
{
return le ? le->data : NULL;
}
static inline bool list_contains(const struct list *list, const struct le *le)
{
return le ? le->list == list : false;
}
static inline bool list_isempty(const struct list *list)
{
return list ? list->head == NULL : true;
}
#define LIST_FOREACH(list, le) \
for ((le) = list_head((list)); (le); (le) = (le)->next)

View file

@ -0,0 +1,18 @@
/**
* @file re_lock.h Interface to locking functions
*
* Copyright (C) 2010 Creytiv.com
*/
struct lock;
int lock_alloc(struct lock **lp);
void lock_read_get(struct lock *l);
void lock_write_get(struct lock *l);
int lock_read_try(struct lock *l);
int lock_write_try(struct lock *l);
void lock_rel(struct lock *l);

View file

@ -0,0 +1,69 @@
/**
* @file re_main.h Interface to main polling routine
*
* Copyright (C) 2010 Creytiv.com
*/
enum {
#ifndef FD_READ
FD_READ = 1<<0,
#endif
#ifndef FD_WRITE
FD_WRITE = 1<<1,
#endif
FD_EXCEPT = 1<<2
};
/**
* File descriptor event handler
*
* @param flags Event flags
* @param arg Handler argument
*/
typedef void (fd_h)(int flags, void *arg);
/**
* Thread-safe signal handler
*
* @param sig Signal number
*/
typedef void (re_signal_h)(int sig);
int fd_listen(int fd, int flags, fd_h *fh, void *arg);
void fd_close(int fd);
int fd_setsize(int maxfds);
void fd_debug(void);
int libre_init(void);
void libre_close(void);
int re_main(re_signal_h *signalh);
void re_cancel(void);
int re_debug(struct re_printf *pf, void *unused);
int re_thread_init(void);
void re_thread_close(void);
void re_thread_enter(void);
void re_thread_leave(void);
void re_set_mutex(void *mutexp);
/** Polling methods */
enum poll_method {
METHOD_NULL = 0,
METHOD_POLL,
METHOD_SELECT,
METHOD_EPOLL,
METHOD_KQUEUE,
/* sep */
METHOD_MAX
};
int poll_method_set(enum poll_method method);
enum poll_method poll_method_best(void);
const char *poll_method_name(enum poll_method method);
int poll_method_type(enum poll_method *method, const struct pl *name);

View file

@ -0,0 +1,169 @@
/**
* @file re_mbuf.h Interface to memory buffers
*
* Copyright (C) 2010 Creytiv.com
*/
#include <stdarg.h>
#ifndef RELEASE
#define MBUF_DEBUG 1 /**< Mbuf debugging (0 or 1) */
#endif
#if MBUF_DEBUG
/** Check that mbuf position does not exceed end */
#define MBUF_CHECK_POS(mb) \
if ((mb) && (mb)->pos > (mb)->end) { \
BREAKPOINT; \
}
/** Check that mbuf end does not exceed size */
#define MBUF_CHECK_END(mb) \
if ((mb) && (mb)->end > (mb)->size) { \
BREAKPOINT; \
}
#else
#define MBUF_CHECK_POS(mb)
#define MBUF_CHECK_END(mb)
#endif
/** Defines a memory buffer */
struct mbuf {
uint8_t *buf; /**< Buffer memory */
size_t size; /**< Size of buffer */
size_t pos; /**< Position in buffer */
size_t end; /**< End of buffer */
};
struct pl;
struct re_printf;
struct mbuf *mbuf_alloc(size_t size);
struct mbuf *mbuf_alloc_ref(struct mbuf *mbr);
void mbuf_init(struct mbuf *mb);
void mbuf_reset(struct mbuf *mb);
int mbuf_resize(struct mbuf *mb, size_t size);
void mbuf_trim(struct mbuf *mb);
int mbuf_shift(struct mbuf *mb, ssize_t shift);
int mbuf_write_mem(struct mbuf *mb, const uint8_t *buf, size_t size);
int mbuf_write_u8(struct mbuf *mb, uint8_t v);
int mbuf_write_u16(struct mbuf *mb, uint16_t v);
int mbuf_write_u32(struct mbuf *mb, uint32_t v);
int mbuf_write_u64(struct mbuf *mb, uint64_t v);
int mbuf_write_str(struct mbuf *mb, const char *str);
int mbuf_write_pl(struct mbuf *mb, const struct pl *pl);
int mbuf_read_mem(struct mbuf *mb, uint8_t *buf, size_t size);
uint8_t mbuf_read_u8(struct mbuf *mb);
uint16_t mbuf_read_u16(struct mbuf *mb);
uint32_t mbuf_read_u32(struct mbuf *mb);
uint64_t mbuf_read_u64(struct mbuf *mb);
int mbuf_read_str(struct mbuf *mb, char *str, size_t size);
int mbuf_strdup(struct mbuf *mb, char **strp, size_t len);
int mbuf_vprintf(struct mbuf *mb, const char *fmt, va_list ap);
int mbuf_printf(struct mbuf *mb, const char *fmt, ...);
int mbuf_write_pl_skip(struct mbuf *mb, const struct pl *pl,
const struct pl *skip);
int mbuf_fill(struct mbuf *mb, uint8_t c, size_t n);
int mbuf_debug(struct re_printf *pf, const struct mbuf *mb);
/**
* Get the buffer from the current position
*
* @param mb Memory buffer
*
* @return Current buffer
*/
static inline uint8_t *mbuf_buf(const struct mbuf *mb)
{
return mb ? mb->buf + mb->pos : (uint8_t *)NULL;
}
/**
* Get number of bytes left in a memory buffer, from current position to end
*
* @param mb Memory buffer
*
* @return Number of bytes left
*/
static inline size_t mbuf_get_left(const struct mbuf *mb)
{
return (mb && (mb->end > mb->pos)) ? (mb->end - mb->pos) : 0;
}
/**
* Get available space in buffer (size - pos)
*
* @param mb Memory buffer
*
* @return Number of bytes available in buffer
*/
static inline size_t mbuf_get_space(const struct mbuf *mb)
{
return (mb && (mb->size > mb->pos)) ? (mb->size - mb->pos) : 0;
}
/**
* Set absolute position
*
* @param mb Memory buffer
* @param pos Position
*/
static inline void mbuf_set_pos(struct mbuf *mb, size_t pos)
{
mb->pos = pos;
MBUF_CHECK_POS(mb);
}
/**
* Set absolute end
*
* @param mb Memory buffer
* @param end End position
*/
static inline void mbuf_set_end(struct mbuf *mb, size_t end)
{
mb->end = end;
MBUF_CHECK_END(mb);
}
/**
* Advance position +/- N bytes
*
* @param mb Memory buffer
* @param n Number of bytes to advance
*/
static inline void mbuf_advance(struct mbuf *mb, ssize_t n)
{
mb->pos += n;
MBUF_CHECK_POS(mb);
}
/**
* Rewind position and end to the beginning of buffer
*
* @param mb Memory buffer
*/
static inline void mbuf_rewind(struct mbuf *mb)
{
mb->pos = mb->end = 0;
}
/**
* Set position to the end of the buffer
*
* @param mb Memory buffer
*/
static inline void mbuf_skip_to_end(struct mbuf *mb)
{
mb->pos = mb->end;
}

View file

@ -0,0 +1,15 @@
/**
* @file re_md5.h Interface to MD5 functions
*
* Copyright (C) 2010 Creytiv.com
*/
/** MD5 values */
enum {
MD5_SIZE = 16, /**< Number of bytes in MD5 hash */
MD5_STR_SIZE = 2*MD5_SIZE + 1 /**< Number of bytes in MD5 string */
};
//void md5(const uint8_t *d, size_t n, uint8_t *md);
int md5_printf(uint8_t *md, const char *fmt, ...);

View file

@ -0,0 +1,45 @@
/**
* @file re_mem.h Interface to Memory management with reference counting
*
* Copyright (C) 2010 Creytiv.com
*/
/**
* Defines the memory destructor handler, which is called when the reference
* of a memory object goes down to zero
*
* @param data Pointer to memory object
*/
typedef void (mem_destroy_h)(void *data);
/** Memory Statistics */
struct memstat {
size_t bytes_cur; /**< Current bytes allocated */
size_t bytes_peak; /**< Peak bytes allocated */
size_t blocks_cur; /**< Current blocks allocated */
size_t blocks_peak; /**< Peak blocks allocated */
size_t size_min; /**< Lowest block size allocated */
size_t size_max; /**< Largest block size allocated */
};
void *mem_alloc(size_t size, mem_destroy_h *dh);
void *mem_zalloc(size_t size, mem_destroy_h *dh);
void *mem_realloc(void *data, size_t size);
void *mem_reallocarray(void *ptr, size_t nmemb,
size_t membsize, mem_destroy_h *dh);
void *mem_ref(void *data);
void *mem_deref(void *data);
uint32_t mem_nrefs(const void *data);
void mem_debug(void);
void mem_threshold_set(ssize_t n);
struct re_printf;
int mem_status(struct re_printf *pf, void *unused);
int mem_get_stat(struct memstat *mstat);
/* Secure memory functions */
int mem_seccmp(const volatile uint8_t *volatile s1,
const volatile uint8_t *volatile s2,
size_t n);

View file

@ -0,0 +1,75 @@
/**
* @file re_mod.h Interface to loadable modules
*
* Copyright (C) 2010 Creytiv.com
*/
/**
* @def MOD_PRE
*
* Module Prefix
*
* @def MOD_EXT
*
* Module Extension
*/
#if defined (WIN32)
#define MOD_PRE ""
#define MOD_EXT ".dll"
#else
#define MOD_PRE ""
#define MOD_EXT ".so"
#endif
/** Symbol to enable exporting of functions from a module */
#ifdef WIN32
#define EXPORT_SYM __declspec(dllexport)
#else
#define EXPORT_SYM
#endif
/* ----- Module API ----- */
/**
* Defines the module initialisation handler
*
* @return 0 for success, otherwise errorcode
*/
typedef int (mod_init_h)(void);
/**
* Defines the module close handler
*
* @return 0 for success, otherwise errorcode
*/
typedef int (mod_close_h)(void);
struct mod;
struct re_printf;
/** Defines the module export */
struct mod_export {
const char *name; /**< Module name */
const char *type; /**< Module type */
mod_init_h *init; /**< Module init handler */
mod_close_h *close; /**< Module close handler */
};
/* ----- Application API ----- */
void mod_init(void);
void mod_close(void);
int mod_load(struct mod **mp, const char *name);
int mod_add(struct mod **mp, const struct mod_export *me);
struct mod *mod_find(const char *name);
const struct mod_export *mod_export(const struct mod *m);
struct list *mod_list(void);
int mod_debug(struct re_printf *pf, void *unused);

View file

@ -0,0 +1,12 @@
/**
* @file re_mqueue.h Thread Safe Message Queue
*
* Copyright (C) 2010 Creytiv.com
*/
struct mqueue;
typedef void (mqueue_h)(int id, void *data, void *arg);
int mqueue_alloc(struct mqueue **mqp, mqueue_h *h, void *arg);
int mqueue_push(struct mqueue *mq, int id, void *data);

View file

@ -0,0 +1,21 @@
/**
* @file re_msg.h Interface to generic message components
*
* Copyright (C) 2010 Creytiv.com
*/
/** Content-Type */
struct msg_ctype {
struct pl type;
struct pl subtype;
struct pl params;
};
int msg_ctype_decode(struct msg_ctype *ctype, const struct pl *pl);
bool msg_ctype_cmp(const struct msg_ctype *ctype,
const char *type, const char *subtype);
int msg_param_decode(const struct pl *pl, const char *name, struct pl *val);
int msg_param_exists(const struct pl *pl, const char *name, struct pl *end);

View file

@ -0,0 +1,128 @@
/**
* @file re_natbd.h NAT Behavior Discovery Using STUN (RFC 5780)
*
* Copyright (C) 2010 Creytiv.com
*/
/** NAT Mapping/Filtering types - See RFC 4787 for definitions */
enum nat_type {
NAT_TYPE_UNKNOWN = 0, /**< Unknown type */
NAT_TYPE_ENDP_INDEP = 1, /**< Endpoint-Independent */
NAT_TYPE_ADDR_DEP = 2, /**< Address-Dependent */
NAT_TYPE_ADDR_PORT_DEP = 3 /**< Address and Port-Dependent */
};
/* Strings */
const char *nat_type_str(enum nat_type type);
/*
* Diagnosing NAT Hairpinning
*/
struct nat_hairpinning;
/**
* Defines the NAT Hairpinning handler
*/
typedef void (nat_hairpinning_h)(int err, bool supported, void *arg);
int nat_hairpinning_alloc(struct nat_hairpinning **nhp,
const struct sa *srv, int proto,
const struct stun_conf *conf,
nat_hairpinning_h *hph, void *arg);
int nat_hairpinning_start(struct nat_hairpinning *nh);
/*
* Determining NAT Mapping Behavior
*/
struct nat_mapping;
/**
* Defines the NAT Mapping handler
*
* @param err Errorcode
* @param type NAT Mapping type
* @param arg Handler argument
*/
typedef void (nat_mapping_h)(int err, enum nat_type map, void *arg);
int nat_mapping_alloc(struct nat_mapping **nmp, const struct sa *laddr,
const struct sa *srv, int proto,
const struct stun_conf *conf,
nat_mapping_h *mh, void *arg);
int nat_mapping_start(struct nat_mapping *nm);
/*
* Determining NAT Filtering Behavior
*/
struct nat_filtering;
/**
* Defines the NAT Filtering handler
*
* @param err Errorcode
* @param type NAT Filtering type
* @param arg Handler argument
*/
typedef void (nat_filtering_h)(int err, enum nat_type filt, void *arg);
int nat_filtering_alloc(struct nat_filtering **nfp, const struct sa *srv,
const struct stun_conf *conf,
nat_filtering_h *fh, void *arg);
int nat_filtering_start(struct nat_filtering *nf);
/*
* Binding Lifetime Discovery
*/
struct nat_lifetime;
/** Defines the NAT lifetime interval */
struct nat_lifetime_interval {
uint32_t min; /**< Minimum lifetime interval in [seconds] */
uint32_t cur; /**< Current lifetime interval in [seconds] */
uint32_t max; /**< Maximum lifetime interval in [seconds] */
};
/**
* Defines the NAT Lifetime handler
*
* @param err Errorcode
* @param i NAT Lifetime intervals
* @param arg Handler argument
*/
typedef void (nat_lifetime_h)(int err, const struct nat_lifetime_interval *i,
void *arg);
int nat_lifetime_alloc(struct nat_lifetime **nlp, const struct sa *srv,
uint32_t interval, const struct stun_conf *conf,
nat_lifetime_h *lh, void *arg);
int nat_lifetime_start(struct nat_lifetime *nl);
/*
* Detecting Generic ALGs
*/
struct nat_genalg;
/**
* Defines the NAT Generic ALG handler
*
* @param err Errorcode
* @param errcode STUN Error code (if set)
* @param status Generic ALG status (-1=not detected, 1=detected)
* @param map Mapped network address
* @param arg Handler argument
*/
typedef void (nat_genalg_h)(int err, uint16_t scode, const char *reason,
int status, const struct sa *map, void *arg);
int nat_genalg_alloc(struct nat_genalg **ngp, const struct sa *srv, int proto,
const struct stun_conf *conf,
nat_genalg_h *gh, void *arg);
int nat_genalg_start(struct nat_genalg *ng);

View file

@ -0,0 +1,130 @@
/**
* @file re_net.h Interface to Networking module.
*
* Copyright (C) 2010 Creytiv.com
*/
#if defined(WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(CONFIG_PLATFORM_8195BHP)
/* input flags for struct addrinfo */
#define AI_PASSIVE 0x01
#define AI_CANONNAME 0x02
#define AI_NUMERICHOST 0x04
#define AI_NUMERICSERV 0x08
#define AI_V4MAPPED 0x10
#define AI_ALL 0x20
#define AI_ADDRCONFIG 0x40
#if LWIP_IPV6
#define AF_INET6 10
#else /* LWIP_IPV6 */
#define AF_INET6 AF_UNSPEC
#endif /* LWIP_IPV6 */
#define NI_MAXHOST 1025
#define NI_MAXSERV 32
#else
#include <sys/types.h>
#ifndef _BSD_SOCKLEN_T_
#define _BSD_SOCKLEN_T_ int /**< Defines the BSD socket length type */
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#ifndef HAVE_GAI_STRERROR
/** stub */
#ifndef gai_strerror
#define gai_strerror(err) "?"
#endif
#endif
/** Length of IPv4 address string */
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
/** Length of IPv6 address string */
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
/** Length of IPv4/v6 address string */
#ifdef HAVE_INET6
#define NET_ADDRSTRLEN INET6_ADDRSTRLEN
#else
#define NET_ADDRSTRLEN INET_ADDRSTRLEN
#endif
/* forward declarations */
struct sa;
/* Net generic */
int net_hostaddr(int af, struct sa *ip);
int net_default_source_addr_get(int af, struct sa *ip);
int net_default_gateway_get(int af, struct sa *gw);
/* Net sockets */
int net_sock_init(void);
void net_sock_close(void);
/* Net socket options */
int net_sockopt_blocking_set(int fd, bool blocking);
int net_sockopt_reuse_set(int fd, bool reuse);
/* Net interface (if.c) */
/**
* Defines the interface address handler - called once per interface
*
* @param ifname Name of the interface
* @param sa IP address of the interface
* @param arg Handler argument
*
* @return true to stop traversing, false to continue
*/
typedef bool (net_ifaddr_h)(const char *ifname, const struct sa *sa,
void *arg);
int net_if_getname(char *ifname, size_t sz, int af, const struct sa *ip);
int net_if_getaddr(const char *ifname, int af, struct sa *ip);
int net_if_getaddr4(const char *ifname, int af, struct sa *ip);
int net_if_list(net_ifaddr_h *ifh, void *arg);
int net_if_apply(net_ifaddr_h *ifh, void *arg);
int net_if_debug(struct re_printf *pf, void *unused);
int net_if_getlinklocal(const char *ifname, int af, struct sa *ip);
/* Net interface (ifaddrs.c) */
int net_getifaddrs(net_ifaddr_h *ifh, void *arg);
/* Net route */
/**
* Defines the routing table handler - called once per route entry
*
* @param ifname Interface name
* @param dst Destination IP address/network
* @param dstlen Prefix length of destination
* @param gw Gateway IP address
* @param arg Handler argument
*
* @return true to stop traversing, false to continue
*/
typedef bool (net_rt_h)(const char *ifname, const struct sa *dst,
int dstlen, const struct sa *gw, void *arg);
int net_rt_list(net_rt_h *rth, void *arg);
int net_rt_default_get(int af, char *ifname, size_t size);
int net_rt_debug(struct re_printf *pf, void *unused);
/* Net strings */
const char *net_proto2name(int proto);
const char *net_af2name(int af);

View file

@ -0,0 +1,47 @@
/**
* @file re_odict.h Interface to Ordered Dictionary
*
* Copyright (C) 2010 - 2015 Creytiv.com
*/
enum odict_type {
ODICT_OBJECT,
ODICT_ARRAY,
ODICT_STRING,
ODICT_INT,
ODICT_DOUBLE,
ODICT_BOOL,
ODICT_NULL,
};
struct odict {
struct list lst;
struct hash *ht;
};
struct odict_entry {
struct le le, he;
char *key;
union {
struct odict *odict; /* ODICT_OBJECT / ODICT_ARRAY */
char *str; /* ODICT_STRING */
int64_t integer; /* ODICT_INT */
double dbl; /* ODICT_DOUBLE */
bool boolean; /* ODICT_BOOL */
} u;
enum odict_type type;
};
int odict_alloc(struct odict **op, uint32_t hash_size);
const struct odict_entry *odict_lookup(const struct odict *o, const char *key);
size_t odict_count(const struct odict *o, bool nested);
int odict_debug(struct re_printf *pf, const struct odict *o);
int odict_entry_add(struct odict *o, const char *key,
int type, ...);
void odict_entry_del(struct odict *o, const char *key);
int odict_entry_debug(struct re_printf *pf, const struct odict_entry *e);
bool odict_type_iscontainer(enum odict_type type);
bool odict_type_isreal(enum odict_type type);
const char *odict_type_name(enum odict_type type);

View file

@ -0,0 +1,239 @@
/**
* @file re_rtp.h Interface to Real-time Transport Protocol and RTCP
*
* Copyright (C) 2010 Creytiv.com
*/
/** RTP protocol values */
enum {
RTP_VERSION = 2, /**< Defines the RTP version we support */
RTCP_VERSION = 2, /**< Supported RTCP Version */
RTP_HEADER_SIZE = 12 /**< Number of bytes in RTP Header */
};
/** Defines the RTP header */
struct rtp_header {
uint8_t ver; /**< RTP version number */
bool pad; /**< Padding bit */
bool ext; /**< Extension bit */
uint8_t cc; /**< CSRC count */
bool m; /**< Marker bit */
uint8_t pt; /**< Payload type */
uint16_t seq; /**< Sequence number */
uint32_t ts; /**< Timestamp */
uint32_t ssrc; /**< Synchronization source */
uint32_t csrc[16]; /**< Contributing sources */
struct {
uint16_t type; /**< Defined by profile */
uint16_t len; /**< Number of 32-bit words */
} x;
};
/** RTCP Packet Types */
enum rtcp_type {
RTCP_FIR = 192, /**< Full INTRA-frame Request (RFC 2032) */
RTCP_NACK = 193, /**< Negative Acknowledgement (RFC 2032) */
RTCP_SR = 200, /**< Sender Report */
RTCP_RR = 201, /**< Receiver Report */
RTCP_SDES = 202, /**< Source Description */
RTCP_BYE = 203, /**< Goodbye */
RTCP_APP = 204, /**< Application-defined */
RTCP_RTPFB = 205, /**< Transport layer FB message (RFC 4585) */
RTCP_PSFB = 206, /**< Payload-specific FB message (RFC 4585) */
RTCP_XR = 207, /**< Extended Report (RFC 3611) */
RTCP_AVB = 208, /**< AVB RTCP Packet (IEEE1733) */
};
/** SDES Types */
enum rtcp_sdes_type {
RTCP_SDES_END = 0, /**< End of SDES list */
RTCP_SDES_CNAME = 1, /**< Canonical name */
RTCP_SDES_NAME = 2, /**< User name */
RTCP_SDES_EMAIL = 3, /**< User's electronic mail address */
RTCP_SDES_PHONE = 4, /**< User's phone number */
RTCP_SDES_LOC = 5, /**< Geographic user location */
RTCP_SDES_TOOL = 6, /**< Name of application or tool */
RTCP_SDES_NOTE = 7, /**< Notice about the source */
RTCP_SDES_PRIV = 8 /**< Private extension */
};
/** Transport Layer Feedback Messages */
enum rtcp_rtpfb {
RTCP_RTPFB_GNACK = 1 /**< Generic NACK */
};
/** Payload-Specific Feedback Messages */
enum rtcp_psfb {
RTCP_PSFB_PLI = 1, /**< Picture Loss Indication (PLI) */
RTCP_PSFB_SLI = 2, /**< Slice Loss Indication (SLI) */
RTCP_PSFB_AFB = 15, /**< Application layer Feedback Messages */
};
/** Reception report block */
struct rtcp_rr {
uint32_t ssrc; /**< Data source being reported */
unsigned int fraction:8; /**< Fraction lost since last SR/RR */
int lost:24; /**< Cumul. no. pkts lost (signed!) */
uint32_t last_seq; /**< Extended last seq. no. received */
uint32_t jitter; /**< Interarrival jitter */
uint32_t lsr; /**< Last SR packet from this source */
uint32_t dlsr; /**< Delay since last SR packet */
};
/** SDES item */
struct rtcp_sdes_item {
enum rtcp_sdes_type type; /**< Type of item (enum rtcp_sdes_type) */
uint8_t length; /**< Length of item (in octets) */
char *data; /**< Text, not null-terminated */
};
/** One RTCP Message */
struct rtcp_msg {
/** RTCP Header */
struct rtcp_hdr {
unsigned int version:2; /**< Protocol version */
unsigned int p:1; /**< Padding flag */
unsigned int count:5; /**< Varies by packet type */
unsigned int pt:8; /**< RTCP packet type */
uint16_t length; /**< Packet length in words */
} hdr;
union {
/** Sender report (SR) */
struct {
uint32_t ssrc; /**< Sender generating report */
uint32_t ntp_sec; /**< NTP timestamp - seconds */
uint32_t ntp_frac; /**< NTP timestamp - fractions */
uint32_t rtp_ts; /**< RTP timestamp */
uint32_t psent; /**< RTP packets sent */
uint32_t osent; /**< RTP octets sent */
struct rtcp_rr *rrv; /**< Reception report blocks */
} sr;
/** Reception report (RR) */
struct {
uint32_t ssrc; /**< Receiver generating report*/
struct rtcp_rr *rrv; /**< Reception report blocks */
} rr;
/** Source Description (SDES) */
struct rtcp_sdes {
uint32_t src; /**< First SSRC/CSRC */
struct rtcp_sdes_item *itemv; /**< SDES items */
uint32_t n; /**< Number of SDES items */
} *sdesv;
/** BYE */
struct {
uint32_t *srcv; /**< List of sources */
char *reason; /**< Reason for leaving (opt.) */
} bye;
/** Application-defined (APP) */
struct {
uint32_t src; /**< SSRC/CSRC */
char name[4]; /**< Name (ASCII) */
uint8_t *data; /**< Application data (32 bits) */
size_t data_len; /**< Number of data bytes */
} app;
/** Full INTRA-frame Request (FIR) packet */
struct {
uint32_t ssrc; /**< SSRC for sender of this packet */
} fir_rtp;
/** Negative ACKnowledgements (NACK) packet */
struct {
uint32_t ssrc; /**< SSRC for sender of this packet */
uint16_t fsn; /**< First Sequence Number lost */
uint16_t blp; /**< Bitmask of lost packets */
} nack;
/** Feedback (RTPFB or PSFB) packet */
struct {
uint32_t ssrc_packet;
uint32_t ssrc_media;
uint32_t n;
/** Feedback Control Information (FCI) */
union {
struct gnack {
uint16_t pid;
uint16_t blp;
} *gnackv;
struct sli {
uint16_t first;
uint16_t number;
uint8_t picid;
} *sliv;
struct mbuf *afb;
void *p;
} fci;
} fb;
} r;
};
/** RTCP Statistics */
struct rtcp_stats {
struct {
uint32_t sent; /**< Tx RTP Packets */
int lost; /**< Tx RTP Packets Lost */
uint32_t jit; /**< Tx Inter-arrival Jitter in [us] */
} tx;
struct {
uint32_t sent; /**< Rx RTP Packets */
int lost; /**< Rx RTP Packets Lost */
uint32_t jit; /**< Rx Inter-Arrival Jitter in [us] */
} rx;
uint32_t rtt; /**< Current Round-Trip Time in [us] */
};
struct sa;
struct re_printf;
struct rtp_sock;
typedef void (rtp_recv_h)(const struct sa *src, const struct rtp_header *hdr,
struct mbuf *mb, void *arg);
typedef void (rtcp_recv_h)(const struct sa *src, struct rtcp_msg *msg,
void *arg);
/* RTP api */
int rtp_alloc(struct rtp_sock **rsp);
int rtp_listen(struct rtp_sock **rsp, int proto, const struct sa *ip,
uint16_t min_port, uint16_t max_port, bool enable_rtcp,
rtp_recv_h *recvh, rtcp_recv_h *rtcph, void *arg);
int rtp_hdr_encode(struct mbuf *mb, const struct rtp_header *hdr);
int rtp_hdr_decode(struct rtp_header *hdr, struct mbuf *mb);
int rtp_encode(struct rtp_sock *rs, bool ext, bool marker, uint8_t pt,
uint32_t ts, struct mbuf *mb);
int rtp_decode(struct rtp_sock *rs, struct mbuf *mb, struct rtp_header *hdr);
int rtp_send(struct rtp_sock *rs, const struct sa *dst, bool ext,
bool marker, uint8_t pt, uint32_t ts, struct mbuf *mb);
int rtp_debug(struct re_printf *pf, const struct rtp_sock *rs);
void *rtp_sock(const struct rtp_sock *rs);
uint32_t rtp_sess_ssrc(const struct rtp_sock *rs);
const struct sa *rtp_local(const struct rtp_sock *rs);
/* RTCP session api */
void rtcp_start(struct rtp_sock *rs, const char *cname,
const struct sa *peer);
void rtcp_enable_mux(struct rtp_sock *rs, bool enabled);
void rtcp_set_srate(struct rtp_sock *rs, uint32_t sr_tx, uint32_t sr_rx);
void rtcp_set_srate_tx(struct rtp_sock *rs, uint32_t srate_tx);
void rtcp_set_srate_rx(struct rtp_sock *rs, uint32_t srate_rx);
int rtcp_send_app(struct rtp_sock *rs, const char name[4],
const uint8_t *data, size_t len);
int rtcp_send_fir(struct rtp_sock *rs, uint32_t ssrc);
int rtcp_send_nack(struct rtp_sock *rs, uint16_t fsn, uint16_t blp);
int rtcp_send_pli(struct rtp_sock *rs, uint32_t fb_ssrc);
int rtcp_debug(struct re_printf *pf, const struct rtp_sock *rs);
void *rtcp_sock(const struct rtp_sock *rs);
int rtcp_stats(struct rtp_sock *rs, uint32_t ssrc, struct rtcp_stats *stats);
/* RTCP utils */
int rtcp_encode(struct mbuf *mb, enum rtcp_type type, uint32_t count, ...);
int rtcp_decode(struct rtcp_msg **msgp, struct mbuf *mb);
int rtcp_msg_print(struct re_printf *pf, const struct rtcp_msg *msg);
int rtcp_sdes_encode(struct mbuf *mb, uint32_t src, uint32_t itemc, ...);
const char *rtcp_type_name(enum rtcp_type type);
const char *rtcp_sdes_name(enum rtcp_sdes_type sdes);

View file

@ -0,0 +1,66 @@
/**
* @file re_sa.h Interface to Socket Address
*
* Copyright (C) 2010 Creytiv.com
*/
#if defined(WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(CONFIG_PLATFORM_8195BHP)
#include <lwip/sockets.h>
#define FILE void
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif
struct pl;
/** Socket Address flags */
enum sa_flag {
SA_ADDR = 1<<0,
SA_PORT = 1<<1,
SA_ALL = SA_ADDR | SA_PORT
};
/** Defines a Socket Address */
struct sa {
union {
struct sockaddr sa;
struct sockaddr_in in;
#ifdef HAVE_INET6
struct sockaddr_in6 in6;
#endif
uint8_t padding[28];
} u;
socklen_t len;
};
void sa_init(struct sa *sa, int af);
int sa_set(struct sa *sa, const struct pl *addr, uint16_t port);
int sa_set_str(struct sa *sa, const char *addr, uint16_t port);
void sa_set_in(struct sa *sa, uint32_t addr, uint16_t port);
void sa_set_in6(struct sa *sa, const uint8_t *addr, uint16_t port);
int sa_set_sa(struct sa *sa, const struct sockaddr *s);
void sa_set_port(struct sa *sa, uint16_t port);
int sa_decode(struct sa *sa, const char *str, size_t len);
int sa_af(const struct sa *sa);
uint32_t sa_in(const struct sa *sa);
void sa_in6(const struct sa *sa, uint8_t *addr);
int sa_ntop(const struct sa *sa, char *buf, int size);
uint16_t sa_port(const struct sa *sa);
bool sa_isset(const struct sa *sa, int flag);
uint32_t sa_hash(const struct sa *sa, int flag);
void sa_cpy(struct sa *dst, const struct sa *src);
bool sa_cmp(const struct sa *l, const struct sa *r, int flag);
bool sa_is_linklocal(const struct sa *sa);
bool sa_is_loopback(const struct sa *sa);
bool sa_is_any(const struct sa *sa);
struct re_printf;
int sa_print_addr(struct re_printf *pf, const struct sa *sa);

View file

@ -0,0 +1,185 @@
/**
* @file re_sdp.h Interface to Session Description Protocol (SDP)
*
* Copyright (C) 2010 Creytiv.com
*/
enum {
SDP_VERSION = 0
};
/** SDP Direction */
enum sdp_dir {
SDP_INACTIVE = 0,
SDP_RECVONLY = 1,
SDP_SENDONLY = 2,
SDP_SENDRECV = 3,
};
/** SDP Bandwidth type */
enum sdp_bandwidth {
SDP_BANDWIDTH_MIN = 0,
SDP_BANDWIDTH_CT = 0, /**< [kbit/s] Conference Total */
SDP_BANDWIDTH_AS, /**< [kbit/s] Application Specific */
SDP_BANDWIDTH_RS, /**< [bit/s] RTCP Senders (RFC 3556) */
SDP_BANDWIDTH_RR, /**< [bit/s] RTCP Receivers (RFC 3556) */
SDP_BANDWIDTH_TIAS, /**< [bit/s] Transport Independent Application
Specific Maximum (RFC 3890) */
SDP_BANDWIDTH_MAX,
};
struct sdp_format;
typedef int(sdp_media_enc_h)(struct mbuf *mb, bool offer, void *arg);
typedef int(sdp_fmtp_enc_h)(struct mbuf *mb, const struct sdp_format *fmt,
bool offer, void *data);
typedef bool(sdp_fmtp_cmp_h)(const char *params1, const char *params2,
void *data);
typedef bool(sdp_format_h)(struct sdp_format *fmt, void *arg);
typedef bool(sdp_attr_h)(const char *name, const char *value, void *arg);
/** SDP Format */
struct sdp_format {
struct le le;
char *id;
char *params;
char *rparams;
char *name;
sdp_fmtp_enc_h *ench;
sdp_fmtp_cmp_h *cmph;
void *data;
bool ref;
bool sup;
int pt;
uint32_t srate;
uint8_t ch;
};
/* session */
struct sdp_session;
int sdp_session_alloc(struct sdp_session **sessp, const struct sa *laddr);
void sdp_session_set_laddr(struct sdp_session *sess, const struct sa *laddr);
void sdp_session_set_lbandwidth(struct sdp_session *sess,
enum sdp_bandwidth type, int32_t bw);
int sdp_session_set_lattr(struct sdp_session *sess, bool replace,
const char *name, const char *value, ...);
void sdp_session_del_lattr(struct sdp_session *sess, const char *name);
int32_t sdp_session_lbandwidth(const struct sdp_session *sess,
enum sdp_bandwidth type);
int32_t sdp_session_rbandwidth(const struct sdp_session *sess,
enum sdp_bandwidth type);
const char *sdp_session_rattr(const struct sdp_session *sess,
const char *name);
const char *sdp_session_rattr_apply(const struct sdp_session *sess,
const char *name,
sdp_attr_h *attrh, void *arg);
const struct list *sdp_session_medial(const struct sdp_session *sess,
bool local);
int sdp_session_debug(struct re_printf *pf, const struct sdp_session *sess);
/* media */
struct sdp_media;
int sdp_media_add(struct sdp_media **mp, struct sdp_session *sess,
const char *name, uint16_t port, const char *proto);
int sdp_media_set_alt_protos(struct sdp_media *m, unsigned protoc, ...);
void sdp_media_set_encode_handler(struct sdp_media *m, sdp_media_enc_h *ench,
void *arg);
void sdp_media_set_fmt_ignore(struct sdp_media *m, bool fmt_ignore);
void sdp_media_set_disabled(struct sdp_media *m, bool disabled);
void sdp_media_set_lport(struct sdp_media *m, uint16_t port);
void sdp_media_set_laddr(struct sdp_media *m, const struct sa *laddr);
void sdp_media_set_lbandwidth(struct sdp_media *m, enum sdp_bandwidth type,
int32_t bw);
void sdp_media_set_lport_rtcp(struct sdp_media *m, uint16_t port);
void sdp_media_set_laddr_rtcp(struct sdp_media *m, const struct sa *laddr);
void sdp_media_set_ldir(struct sdp_media *m, enum sdp_dir dir);
int sdp_media_set_lattr(struct sdp_media *m, bool replace,
const char *name, const char *value, ...);
void sdp_media_del_lattr(struct sdp_media *m, const char *name);
const char *sdp_media_proto(const struct sdp_media *m);
uint16_t sdp_media_rport(const struct sdp_media *m);
const struct sa *sdp_media_raddr(const struct sdp_media *m);
const struct sa *sdp_media_laddr(const struct sdp_media *m);
void sdp_media_raddr_rtcp(const struct sdp_media *m, struct sa *raddr);
int32_t sdp_media_rbandwidth(const struct sdp_media *m,
enum sdp_bandwidth type);
enum sdp_dir sdp_media_ldir(const struct sdp_media *m);
enum sdp_dir sdp_media_rdir(const struct sdp_media *m);
enum sdp_dir sdp_media_dir(const struct sdp_media *m);
const struct sdp_format *sdp_media_lformat(const struct sdp_media *m, int pt);
const struct sdp_format *sdp_media_rformat(const struct sdp_media *m,
const char *name);
struct sdp_format *sdp_media_format(const struct sdp_media *m,
bool local, const char *id,
int pt, const char *name,
int32_t srate, int8_t ch);
struct sdp_format *sdp_media_format_apply(const struct sdp_media *m,
bool local, const char *id,
int pt, const char *name,
int32_t srate, int8_t ch,
sdp_format_h *fmth, void *arg);
const struct list *sdp_media_format_lst(const struct sdp_media *m, bool local);
const char *sdp_media_rattr(const struct sdp_media *m, const char *name);
const char *sdp_media_session_rattr(const struct sdp_media *m,
const struct sdp_session *sess,
const char *name);
const char *sdp_media_rattr_apply(const struct sdp_media *m, const char *name,
sdp_attr_h *attrh, void *arg);
const char *sdp_media_name(const struct sdp_media *m);
int sdp_media_debug(struct re_printf *pf, const struct sdp_media *m);
/* format */
int sdp_format_add(struct sdp_format **fmtp, struct sdp_media *m,
bool prepend, const char *id, const char *name,
uint32_t srate, uint8_t ch, sdp_fmtp_enc_h *ench,
sdp_fmtp_cmp_h *cmph, void *data, bool ref,
const char *params, ...);
int sdp_format_set_params(struct sdp_format *fmt, const char *params, ...);
bool sdp_format_cmp(const struct sdp_format *fmt1,
const struct sdp_format *fmt2);
int sdp_format_debug(struct re_printf *pf, const struct sdp_format *fmt);
/* encode/decode */
int sdp_encode(struct mbuf **mbp, struct sdp_session *sess, bool offer);
int sdp_decode(struct sdp_session *sess, struct mbuf *mb, bool offer);
/* strings */
const char *sdp_dir_name(enum sdp_dir dir);
const char *sdp_bandwidth_name(enum sdp_bandwidth type);
extern const char sdp_attr_fmtp[];
extern const char sdp_attr_maxptime[];
extern const char sdp_attr_ptime[];
extern const char sdp_attr_rtcp[];
extern const char sdp_attr_rtpmap[];
extern const char sdp_media_audio[];
extern const char sdp_media_video[];
extern const char sdp_media_text[];
extern const char sdp_proto_rtpavp[];
extern const char sdp_proto_rtpsavp[];
/* utility functions */
/** RTP Header Extensions, as defined in RFC 5285 */
struct sdp_extmap {
struct pl name;
struct pl attrs;
enum sdp_dir dir;
bool dir_set;
uint32_t id;
};
int sdp_extmap_decode(struct sdp_extmap *ext, const char *val);

View file

@ -0,0 +1,34 @@
/**
* @file re_sha.h Interface to SHA (Secure Hash Standard) functions
*
* Copyright (C) 2010 Creytiv.com
*/
#ifdef USE_OPENSSL
#include <openssl/sha.h>
#else
/* public api for steve reid's public domain SHA-1 implementation */
/* this file is in the public domain */
/** SHA-1 Context */
typedef struct {
uint32_t state[5]; /**< Context state */
uint32_t count[2]; /**< Counter */
uint8_t buffer[64]; /**< SHA-1 buffer */
} SHA1_CTX;
/** SHA-1 Context (OpenSSL compat) */
typedef SHA1_CTX SHA_CTX;
/** SHA-1 Digest size in bytes */
#define SHA1_DIGEST_SIZE 20
/** SHA-1 Digest size in bytes (OpenSSL compat) */
#define SHA_DIGEST_LENGTH SHA1_DIGEST_SIZE
void SHA1_Init(SHA1_CTX* context);
void SHA1_Update(SHA1_CTX* context, const void *p, size_t len);
void SHA1_Final(uint8_t digest[SHA1_DIGEST_SIZE], SHA1_CTX* context);
#endif

View file

@ -0,0 +1,370 @@
/**
* @file re_sip.h Session Initiation Protocol
*
* Copyright (C) 2010 Creytiv.com
*/
enum {
SIP_PORT = 5060,
SIP_PORT_TLS = 5061,
};
/** SIP Transport */
enum sip_transp {
SIP_TRANSP_NONE = -1,
SIP_TRANSP_UDP = 0,
SIP_TRANSP_TCP,
SIP_TRANSP_TLS,
SIP_TRANSPC,
};
/** SIP Header ID (perfect hash value) */
enum sip_hdrid {
SIP_HDR_ACCEPT = 3186,
SIP_HDR_ACCEPT_CONTACT = 232,
SIP_HDR_ACCEPT_ENCODING = 708,
SIP_HDR_ACCEPT_LANGUAGE = 2867,
SIP_HDR_ACCEPT_RESOURCE_PRIORITY = 1848,
SIP_HDR_ALERT_INFO = 274,
SIP_HDR_ALLOW = 2429,
SIP_HDR_ALLOW_EVENTS = 66,
SIP_HDR_ANSWER_MODE = 2905,
SIP_HDR_AUTHENTICATION_INFO = 3144,
SIP_HDR_AUTHORIZATION = 2503,
SIP_HDR_CALL_ID = 3095,
SIP_HDR_CALL_INFO = 586,
SIP_HDR_CONTACT = 229,
SIP_HDR_CONTENT_DISPOSITION = 1425,
SIP_HDR_CONTENT_ENCODING = 580,
SIP_HDR_CONTENT_LANGUAGE = 3371,
SIP_HDR_CONTENT_LENGTH = 3861,
SIP_HDR_CONTENT_TYPE = 809,
SIP_HDR_CSEQ = 746,
SIP_HDR_DATE = 1027,
SIP_HDR_ENCRYPTION = 3125,
SIP_HDR_ERROR_INFO = 21,
SIP_HDR_EVENT = 3286,
SIP_HDR_EXPIRES = 1983,
SIP_HDR_FLOW_TIMER = 584,
SIP_HDR_FROM = 1963,
SIP_HDR_HIDE = 283,
SIP_HDR_HISTORY_INFO = 2582,
SIP_HDR_IDENTITY = 2362,
SIP_HDR_IDENTITY_INFO = 980,
SIP_HDR_IN_REPLY_TO = 1577,
SIP_HDR_JOIN = 3479,
SIP_HDR_MAX_BREADTH = 3701,
SIP_HDR_MAX_FORWARDS = 3549,
SIP_HDR_MIME_VERSION = 3659,
SIP_HDR_MIN_EXPIRES = 1121,
SIP_HDR_MIN_SE = 2847,
SIP_HDR_ORGANIZATION = 3247,
SIP_HDR_P_ACCESS_NETWORK_INFO = 1662,
SIP_HDR_P_ANSWER_STATE = 42,
SIP_HDR_P_ASSERTED_IDENTITY = 1233,
SIP_HDR_P_ASSOCIATED_URI = 900,
SIP_HDR_P_CALLED_PARTY_ID = 3347,
SIP_HDR_P_CHARGING_FUNCTION_ADDRESSES = 2171,
SIP_HDR_P_CHARGING_VECTOR = 25,
SIP_HDR_P_DCS_TRACE_PARTY_ID = 3027,
SIP_HDR_P_DCS_OSPS = 1788,
SIP_HDR_P_DCS_BILLING_INFO = 2017,
SIP_HDR_P_DCS_LAES = 693,
SIP_HDR_P_DCS_REDIRECT = 1872,
SIP_HDR_P_EARLY_MEDIA = 2622,
SIP_HDR_P_MEDIA_AUTHORIZATION = 1035,
SIP_HDR_P_PREFERRED_IDENTITY = 1263,
SIP_HDR_P_PROFILE_KEY = 1904,
SIP_HDR_P_REFUSED_URI_LIST = 1047,
SIP_HDR_P_SERVED_USER = 1588,
SIP_HDR_P_USER_DATABASE = 2827,
SIP_HDR_P_VISITED_NETWORK_ID = 3867,
SIP_HDR_PATH = 2741,
SIP_HDR_PERMISSION_MISSING = 1409,
SIP_HDR_PRIORITY = 3520,
SIP_HDR_PRIV_ANSWER_MODE = 2476,
SIP_HDR_PRIVACY = 3150,
SIP_HDR_PROXY_AUTHENTICATE = 116,
SIP_HDR_PROXY_AUTHORIZATION = 2363,
SIP_HDR_PROXY_REQUIRE = 3562,
SIP_HDR_RACK = 2523,
SIP_HDR_REASON = 3732,
SIP_HDR_RECORD_ROUTE = 278,
SIP_HDR_REFER_SUB = 2458,
SIP_HDR_REFER_TO = 1521,
SIP_HDR_REFERRED_BY = 3456,
SIP_HDR_REJECT_CONTACT = 285,
SIP_HDR_REPLACES = 2534,
SIP_HDR_REPLY_TO = 2404,
SIP_HDR_REQUEST_DISPOSITION = 3715,
SIP_HDR_REQUIRE = 3905,
SIP_HDR_RESOURCE_PRIORITY = 1643,
SIP_HDR_RESPONSE_KEY = 1548,
SIP_HDR_RETRY_AFTER = 409,
SIP_HDR_ROUTE = 661,
SIP_HDR_RSEQ = 445,
SIP_HDR_SECURITY_CLIENT = 1358,
SIP_HDR_SECURITY_SERVER = 811,
SIP_HDR_SECURITY_VERIFY = 519,
SIP_HDR_SERVER = 973,
SIP_HDR_SERVICE_ROUTE = 1655,
SIP_HDR_SESSION_EXPIRES = 1979,
SIP_HDR_SIP_ETAG = 1997,
SIP_HDR_SIP_IF_MATCH = 3056,
SIP_HDR_SUBJECT = 1043,
SIP_HDR_SUBSCRIPTION_STATE = 2884,
SIP_HDR_SUPPORTED = 119,
SIP_HDR_TARGET_DIALOG = 3450,
SIP_HDR_TIMESTAMP = 938,
SIP_HDR_TO = 1449,
SIP_HDR_TRIGGER_CONSENT = 3180,
SIP_HDR_UNSUPPORTED = 982,
SIP_HDR_USER_AGENT = 4064,
SIP_HDR_VIA = 3961,
SIP_HDR_WARNING = 2108,
SIP_HDR_WWW_AUTHENTICATE = 2763,
SIP_HDR_NONE = -1
};
enum {
SIP_T1 = 500,
SIP_T2 = 4000,
SIP_T4 = 5000,
};
/** SIP Via header */
struct sip_via {
struct pl sentby;
struct sa addr;
struct pl params;
struct pl branch;
struct pl val;
enum sip_transp tp;
};
/** SIP Address */
struct sip_addr {
struct pl dname;
struct pl auri;
struct uri uri;
struct pl params;
};
/** SIP Tag address */
struct sip_taddr {
struct pl dname;
struct pl auri;
struct uri uri;
struct pl params;
struct pl tag;
struct pl val;
};
/** SIP CSeq header */
struct sip_cseq {
struct pl met;
uint32_t num;
};
/** SIP Header */
struct sip_hdr {
struct le le; /**< Linked-list element */
struct le he; /**< Hash-table element */
struct pl name; /**< SIP Header name */
struct pl val; /**< SIP Header value */
enum sip_hdrid id; /**< SIP Header id (unique) */
};
/** SIP Message */
struct sip_msg {
struct sa src; /**< Source network address */
struct sa dst; /**< Destination network address */
struct pl ver; /**< SIP Version number */
struct pl met; /**< Request method */
struct pl ruri; /**< Raw request URI */
struct uri uri; /**< Parsed request URI */
uint16_t scode; /**< Response status code */
struct pl reason; /**< Response reason phrase */
struct list hdrl; /**< List of SIP Headers (struct sip_hdr) */
struct sip_via via; /**< Parsed first Via header */
struct sip_taddr to; /**< Parsed To header */
struct sip_taddr from; /**< Parsed From header */
struct sip_cseq cseq; /**< Parsed CSeq header */
struct msg_ctype ctyp; /**< Content Type */
struct pl callid; /**< Cached Call-ID header */
struct pl maxfwd; /**< Cached Max-Forwards header */
struct pl expires; /**< Cached Expires header */
struct pl clen; /**< Cached Content-Length header */
struct hash *hdrht; /**< Hash-table with all SIP headers */
struct mbuf *mb; /**< Buffer containing the SIP message */
void *sock; /**< Transport socket */
uint64_t tag; /**< Opaque tag */
enum sip_transp tp; /**< SIP Transport */
bool req; /**< True if Request, False if Response */
};
/** SIP Loop-state */
struct sip_loopstate {
uint32_t failc;
uint16_t last_scode;
};
/** SIP Contact */
struct sip_contact {
const char *uri;
const struct sa *addr;
enum sip_transp tp;
};
struct sip;
struct sip_lsnr;
struct sip_request;
struct sip_strans;
struct sip_auth;
struct sip_dialog;
struct sip_keepalive;
struct dnsc;
typedef bool(sip_msg_h)(const struct sip_msg *msg, void *arg);
typedef int(sip_send_h)(enum sip_transp tp, const struct sa *src,
const struct sa *dst, struct mbuf *mb, void *arg);
typedef void(sip_resp_h)(int err, const struct sip_msg *msg, void *arg);
typedef void(sip_cancel_h)(void *arg);
typedef void(sip_exit_h)(void *arg);
typedef int(sip_auth_h)(char **username, char **password, const char *realm,
void *arg);
typedef bool(sip_hdr_h)(const struct sip_hdr *hdr, const struct sip_msg *msg,
void *arg);
typedef void(sip_keepalive_h)(int err, void *arg);
/* sip */
int sip_alloc(struct sip **sipp, struct dnsc *dnsc, uint32_t ctsz,
uint32_t stsz, uint32_t tcsz, const char *software,
sip_exit_h *exith, void *arg);
void sip_close(struct sip *sip, bool force);
int sip_listen(struct sip_lsnr **lsnrp, struct sip *sip, bool req,
sip_msg_h *msgh, void *arg);
int sip_debug(struct re_printf *pf, const struct sip *sip);
int sip_send(struct sip *sip, void *sock, enum sip_transp tp,
const struct sa *dst, struct mbuf *mb);
/* transport */
int sip_transp_add(struct sip *sip, enum sip_transp tp,
const struct sa *laddr, ...);
void sip_transp_flush(struct sip *sip);
bool sip_transp_isladdr(const struct sip *sip, enum sip_transp tp,
const struct sa *laddr);
const char *sip_transp_name(enum sip_transp tp);
const char *sip_transp_param(enum sip_transp tp);
uint16_t sip_transp_port(enum sip_transp tp, uint16_t port);
int sip_transp_laddr(struct sip *sip, struct sa *laddr, enum sip_transp tp,
const struct sa *dst);
/* request */
int sip_request(struct sip_request **reqp, struct sip *sip, bool stateful,
const char *met, int metl, const char *uri, int uril,
const struct uri *route, struct mbuf *mb, size_t sortkey,
sip_send_h *sendh, sip_resp_h *resph, void *arg);
int sip_requestf(struct sip_request **reqp, struct sip *sip, bool stateful,
const char *met, const char *uri, const struct uri *route,
struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph,
void *arg, const char *fmt, ...);
int sip_drequestf(struct sip_request **reqp, struct sip *sip, bool stateful,
const char *met, struct sip_dialog *dlg, uint32_t cseq,
struct sip_auth *auth, sip_send_h *sendh, sip_resp_h *resph,
void *arg, const char *fmt, ...);
void sip_request_cancel(struct sip_request *req);
bool sip_request_loops(struct sip_loopstate *ls, uint16_t scode);
void sip_loopstate_reset(struct sip_loopstate *ls);
/* reply */
int sip_strans_alloc(struct sip_strans **stp, struct sip *sip,
const struct sip_msg *msg, sip_cancel_h *cancelh,
void *arg);
int sip_strans_reply(struct sip_strans **stp, struct sip *sip,
const struct sip_msg *msg, const struct sa *dst,
uint16_t scode, struct mbuf *mb);
int sip_treplyf(struct sip_strans **stp, struct mbuf **mbp, struct sip *sip,
const struct sip_msg *msg, bool rec_route, uint16_t scode,
const char *reason, const char *fmt, ...);
int sip_treply(struct sip_strans **stp, struct sip *sip,
const struct sip_msg *msg, uint16_t scode, const char *reason);
int sip_replyf(struct sip *sip, const struct sip_msg *msg, uint16_t scode,
const char *reason, const char *fmt, ...);
int sip_reply(struct sip *sip, const struct sip_msg *msg, uint16_t scode,
const char *reason);
void sip_reply_addr(struct sa *addr, const struct sip_msg *msg, bool rport);
/* auth */
int sip_auth_authenticate(struct sip_auth *auth, const struct sip_msg *msg);
int sip_auth_alloc(struct sip_auth **authp, sip_auth_h *authh,
void *arg, bool ref);
void sip_auth_reset(struct sip_auth *auth);
/* contact */
void sip_contact_set(struct sip_contact *contact, const char *uri,
const struct sa *addr, enum sip_transp tp);
int sip_contact_print(struct re_printf *pf,
const struct sip_contact *contact);
/* dialog */
int sip_dialog_alloc(struct sip_dialog **dlgp,
const char *uri, const char *to_uri,
const char *from_name, const char *from_uri,
const char *routev[], uint32_t routec);
int sip_dialog_accept(struct sip_dialog **dlgp, const struct sip_msg *msg);
int sip_dialog_create(struct sip_dialog *dlg, const struct sip_msg *msg);
int sip_dialog_fork(struct sip_dialog **dlgp, struct sip_dialog *odlg,
const struct sip_msg *msg);
int sip_dialog_update(struct sip_dialog *dlg, const struct sip_msg *msg);
bool sip_dialog_rseq_valid(struct sip_dialog *dlg, const struct sip_msg *msg);
const char *sip_dialog_callid(const struct sip_dialog *dlg);
uint32_t sip_dialog_lseq(const struct sip_dialog *dlg);
bool sip_dialog_established(const struct sip_dialog *dlg);
bool sip_dialog_cmp(const struct sip_dialog *dlg, const struct sip_msg *msg);
bool sip_dialog_cmp_half(const struct sip_dialog *dlg,
const struct sip_msg *msg);
/* msg */
int sip_msg_decode(struct sip_msg **msgp, struct mbuf *mb);
const struct sip_hdr *sip_msg_hdr(const struct sip_msg *msg,
enum sip_hdrid id);
const struct sip_hdr *sip_msg_hdr_apply(const struct sip_msg *msg,
bool fwd, enum sip_hdrid id,
sip_hdr_h *h, void *arg);
const struct sip_hdr *sip_msg_xhdr(const struct sip_msg *msg,
const char *name);
const struct sip_hdr *sip_msg_xhdr_apply(const struct sip_msg *msg,
bool fwd, const char *name,
sip_hdr_h *h, void *arg);
uint32_t sip_msg_hdr_count(const struct sip_msg *msg, enum sip_hdrid id);
uint32_t sip_msg_xhdr_count(const struct sip_msg *msg, const char *name);
bool sip_msg_hdr_has_value(const struct sip_msg *msg, enum sip_hdrid id,
const char *value);
bool sip_msg_xhdr_has_value(const struct sip_msg *msg, const char *name,
const char *value);
struct tcp_conn *sip_msg_tcpconn(const struct sip_msg *msg);
void sip_msg_dump(const struct sip_msg *msg);
int sip_addr_decode(struct sip_addr *addr, const struct pl *pl);
int sip_via_decode(struct sip_via *via, const struct pl *pl);
int sip_cseq_decode(struct sip_cseq *cseq, const struct pl *pl);
/* keepalive */
int sip_keepalive_start(struct sip_keepalive **kap, struct sip *sip,
const struct sip_msg *msg, uint32_t interval,
sip_keepalive_h *kah, void *arg);

View file

@ -0,0 +1,123 @@
/**
* @file re_sipevent.h SIP Event Framework
*
* Copyright (C) 2010 Creytiv.com
*/
/* Message Components */
struct sipevent_event {
struct pl event;
struct pl params;
struct pl id;
};
enum sipevent_subst {
SIPEVENT_ACTIVE = 0,
SIPEVENT_PENDING,
SIPEVENT_TERMINATED,
};
enum sipevent_reason {
SIPEVENT_DEACTIVATED = 0,
SIPEVENT_PROBATION,
SIPEVENT_REJECTED,
SIPEVENT_TIMEOUT,
SIPEVENT_GIVEUP,
SIPEVENT_NORESOURCE,
};
struct sipevent_substate {
enum sipevent_subst state;
enum sipevent_reason reason;
struct pl expires;
struct pl retry_after;
struct pl params;
};
int sipevent_event_decode(struct sipevent_event *se, const struct pl *pl);
int sipevent_substate_decode(struct sipevent_substate *ss,
const struct pl *pl);
const char *sipevent_substate_name(enum sipevent_subst state);
const char *sipevent_reason_name(enum sipevent_reason reason);
/* Listener Socket */
struct sipevent_sock;
int sipevent_listen(struct sipevent_sock **sockp, struct sip *sip,
uint32_t htsize_not, uint32_t htsize_sub,
sip_msg_h *subh, void *arg);
/* Notifier */
struct sipnot;
typedef void (sipnot_close_h)(int err, const struct sip_msg *msg, void *arg);
int sipevent_accept(struct sipnot **notp, struct sipevent_sock *sock,
const struct sip_msg *msg, struct sip_dialog *dlg,
const struct sipevent_event *event,
uint16_t scode, const char *reason, uint32_t expires_min,
uint32_t expires_dfl, uint32_t expires_max,
const char *cuser, const char *ctype,
sip_auth_h *authh, void *aarg, bool aref,
sipnot_close_h *closeh, void *arg, const char *fmt, ...);
int sipevent_notify(struct sipnot *sipnot, struct mbuf *mb,
enum sipevent_subst state, enum sipevent_reason reason,
uint32_t retry_after);
int sipevent_notifyf(struct sipnot *sipnot, struct mbuf **mbp,
enum sipevent_subst state, enum sipevent_reason reason,
uint32_t retry_after, const char *fmt, ...);
/* Subscriber */
struct sipsub;
typedef int (sipsub_fork_h)(struct sipsub **subp, struct sipsub *osub,
const struct sip_msg *msg, void *arg);
typedef void (sipsub_notify_h)(struct sip *sip, const struct sip_msg *msg,
void *arg);
typedef void (sipsub_close_h)(int err, const struct sip_msg *msg,
const struct sipevent_substate *substate,
void *arg);
int sipevent_subscribe(struct sipsub **subp, struct sipevent_sock *sock,
const char *uri, const char *from_name,
const char *from_uri, const char *event, const char *id,
uint32_t expires, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sipsub_fork_h *forkh, sipsub_notify_h *notifyh,
sipsub_close_h *closeh, void *arg,
const char *fmt, ...);
int sipevent_dsubscribe(struct sipsub **subp, struct sipevent_sock *sock,
struct sip_dialog *dlg, const char *event,
const char *id, uint32_t expires, const char *cuser,
sip_auth_h *authh, void *aarg, bool aref,
sipsub_notify_h *notifyh, sipsub_close_h *closeh,
void *arg, const char *fmt, ...);
int sipevent_refer(struct sipsub **subp, struct sipevent_sock *sock,
const char *uri, const char *from_name,
const char *from_uri, const char *cuser,
const char *routev[], uint32_t routec,
sip_auth_h *authh, void *aarg, bool aref,
sipsub_fork_h *forkh, sipsub_notify_h *notifyh,
sipsub_close_h *closeh, void *arg,
const char *fmt, ...);
int sipevent_drefer(struct sipsub **subp, struct sipevent_sock *sock,
struct sip_dialog *dlg, const char *cuser,
sip_auth_h *authh, void *aarg, bool aref,
sipsub_notify_h *notifyh, sipsub_close_h *closeh,
void *arg, const char *fmt, ...);
int sipevent_fork(struct sipsub **subp, struct sipsub *osub,
const struct sip_msg *msg,
sip_auth_h *authh, void *aarg, bool aref,
sipsub_notify_h *notifyh, sipsub_close_h *closeh,
void *arg);

View file

@ -0,0 +1,18 @@
/**
* @file re_sipreg.h SIP Registration
*
* Copyright (C) 2010 Creytiv.com
*/
struct sipreg;
int sipreg_register(struct sipreg **regp, struct sip *sip, const char *reg_uri,
const char *to_uri, const char *from_name,
const char *from_uri, uint32_t expires,
const char *cuser, const char *routev[], uint32_t routec,
int regid, sip_auth_h *authh, void *aarg, bool aref,
sip_resp_h *resph, void *arg,
const char *params, const char *fmt, ...);
const struct sa *sipreg_laddr(const struct sipreg *reg);

View file

@ -0,0 +1,60 @@
/**
* @file re_sipsess.h SIP Session
*
* Copyright (C) 2010 Creytiv.com
*/
struct sipsess_sock;
struct sipsess;
typedef void (sipsess_conn_h)(const struct sip_msg *msg, void *arg);
typedef int (sipsess_offer_h)(struct mbuf **descp, const struct sip_msg *msg,
void *arg);
typedef int (sipsess_answer_h)(const struct sip_msg *msg, void *arg);
typedef void (sipsess_progr_h)(const struct sip_msg *msg, void *arg);
typedef void (sipsess_estab_h)(const struct sip_msg *msg, void *arg);
typedef void (sipsess_info_h)(struct sip *sip, const struct sip_msg *msg,
void *arg);
typedef void (sipsess_refer_h)(struct sip *sip, const struct sip_msg *msg,
void *arg);
typedef void (sipsess_close_h)(int err, const struct sip_msg *msg, void *arg);
int sipsess_listen(struct sipsess_sock **sockp, struct sip *sip,
int htsize, sipsess_conn_h *connh, void *arg);
int sipsess_connect(struct sipsess **sessp, struct sipsess_sock *sock,
const char *to_uri, const char *from_name,
const char *from_uri, const char *cuser,
const char *routev[], uint32_t routec,
const char *ctype, struct mbuf *desc,
sip_auth_h *authh, void *aarg, bool aref,
sipsess_offer_h *offerh, sipsess_answer_h *answerh,
sipsess_progr_h *progrh, sipsess_estab_h *estabh,
sipsess_info_h *infoh, sipsess_refer_h *referh,
sipsess_close_h *closeh, void *arg, const char *fmt, ...);
int sipsess_accept(struct sipsess **sessp, struct sipsess_sock *sock,
const struct sip_msg *msg, uint16_t scode,
const char *reason, const char *cuser, const char *ctype,
struct mbuf *desc,
sip_auth_h *authh, void *aarg, bool aref,
sipsess_offer_h *offerh, sipsess_answer_h *answerh,
sipsess_estab_h *estabh, sipsess_info_h *infoh,
sipsess_refer_h *referh, sipsess_close_h *closeh,
void *arg, const char *fmt, ...);
int sipsess_progress(struct sipsess *sess, uint16_t scode,
const char *reason, struct mbuf *desc,
const char *fmt, ...);
int sipsess_answer(struct sipsess *sess, uint16_t scode, const char *reason,
struct mbuf *desc, const char *fmt, ...);
int sipsess_reject(struct sipsess *sess, uint16_t scode, const char *reason,
const char *fmt, ...);
int sipsess_modify(struct sipsess *sess, struct mbuf *desc);
int sipsess_info(struct sipsess *sess, const char *ctype, struct mbuf *body,
sip_resp_h *resph, void *arg);
int sipsess_set_close_headers(struct sipsess *sess, const char *hdrs, ...);
void sipsess_close_all(struct sipsess_sock *sock);
struct sip_dialog *sipsess_dialog(const struct sipsess *sess);

View file

@ -0,0 +1,30 @@
/**
* @file re_srtp.h Secure Real-time Transport Protocol (SRTP)
*
* Copyright (C) 2010 Creytiv.com
*/
enum srtp_suite {
SRTP_AES_CM_128_HMAC_SHA1_32,
SRTP_AES_CM_128_HMAC_SHA1_80,
SRTP_AES_256_CM_HMAC_SHA1_32,
SRTP_AES_256_CM_HMAC_SHA1_80,
SRTP_AES_128_GCM,
SRTP_AES_256_GCM,
};
enum srtp_flags {
SRTP_UNENCRYPTED_SRTCP = 1<<1,
};
struct srtp;
int srtp_alloc(struct srtp **srtpp, enum srtp_suite suite,
const uint8_t *key, size_t key_bytes, int flags);
int srtp_encrypt(struct srtp *srtp, struct mbuf *mb);
int srtp_decrypt(struct srtp *srtp, struct mbuf *mb);
int srtcp_encrypt(struct srtp *srtp, struct mbuf *mb);
int srtcp_decrypt(struct srtp *srtp, struct mbuf *mb);
const char *srtp_suite_name(enum srtp_suite suite);

View file

@ -0,0 +1,294 @@
/**
* @file re_stun.h Session Traversal Utilities for (NAT) (STUN)
*
* Copyright (C) 2010 Creytiv.com
*/
/** STUN Protocol values */
enum {
STUN_PORT = 3478, /**< STUN Port number */
STUNS_PORT = 5349, /**< STUNS Port number */
STUN_HEADER_SIZE = 20, /**< Number of bytes in header */
STUN_ATTR_HEADER_SIZE = 4, /**< Size of attribute header */
STUN_TID_SIZE = 12, /**< Number of bytes in transaction ID */
STUN_DEFAULT_RTO = 500, /**< Default Retrans Timeout in [ms] */
STUN_DEFAULT_RC = 7, /**< Default number of retransmits */
STUN_DEFAULT_RM = 16, /**< Wait time after last request is sent */
STUN_DEFAULT_TI = 39500 /**< Reliable timeout */
};
/** STUN Address Family */
enum stun_af {
STUN_AF_IPv4 = 0x01, /**< IPv4 Address Family */
STUN_AF_IPv6 = 0x02 /**< IPv6 Address Family */
};
/** STUN Transport */
enum stun_transp {
STUN_TRANSP_UDP = IPPROTO_UDP, /**< UDP-transport (struct udp_sock) */
STUN_TRANSP_TCP = IPPROTO_TCP, /**< TCP-transport (struct tcp_conn) */
STUN_TRANSP_DTLS, /**< DTLS-transport (struct tls_conn) */
};
/** STUN Methods */
enum stun_method {
STUN_METHOD_BINDING = 0x001,
STUN_METHOD_ALLOCATE = 0x003,
STUN_METHOD_REFRESH = 0x004,
STUN_METHOD_SEND = 0x006,
STUN_METHOD_DATA = 0x007,
STUN_METHOD_CREATEPERM = 0x008,
STUN_METHOD_CHANBIND = 0x009,
};
/** STUN Message class */
enum stun_msg_class {
STUN_CLASS_REQUEST = 0x0, /**< STUN Request */
STUN_CLASS_INDICATION = 0x1, /**< STUN Indication */
STUN_CLASS_SUCCESS_RESP = 0x2, /**< STUN Success Response */
STUN_CLASS_ERROR_RESP = 0x3 /**< STUN Error Response */
};
/** STUN Attributes */
enum stun_attrib {
/* Comprehension-required range (0x0000-0x7FFF) */
STUN_ATTR_MAPPED_ADDR = 0x0001,
STUN_ATTR_CHANGE_REQ = 0x0003,
STUN_ATTR_USERNAME = 0x0006,
STUN_ATTR_MSG_INTEGRITY = 0x0008,
STUN_ATTR_ERR_CODE = 0x0009,
STUN_ATTR_UNKNOWN_ATTR = 0x000a,
STUN_ATTR_CHANNEL_NUMBER = 0x000c,
STUN_ATTR_LIFETIME = 0x000d,
STUN_ATTR_XOR_PEER_ADDR = 0x0012,
STUN_ATTR_DATA = 0x0013,
STUN_ATTR_REALM = 0x0014,
STUN_ATTR_NONCE = 0x0015,
STUN_ATTR_XOR_RELAY_ADDR = 0x0016,
STUN_ATTR_REQ_ADDR_FAMILY = 0x0017,
STUN_ATTR_EVEN_PORT = 0x0018,
STUN_ATTR_REQ_TRANSPORT = 0x0019,
STUN_ATTR_DONT_FRAGMENT = 0x001a,
STUN_ATTR_XOR_MAPPED_ADDR = 0x0020,
STUN_ATTR_RSV_TOKEN = 0x0022,
STUN_ATTR_PRIORITY = 0x0024,
STUN_ATTR_USE_CAND = 0x0025,
STUN_ATTR_PADDING = 0x0026,
STUN_ATTR_RESP_PORT = 0x0027,
/* Comprehension-optional range (0x8000-0xFFFF) */
STUN_ATTR_SOFTWARE = 0x8022,
STUN_ATTR_ALT_SERVER = 0x8023,
STUN_ATTR_FINGERPRINT = 0x8028,
STUN_ATTR_CONTROLLED = 0x8029,
STUN_ATTR_CONTROLLING = 0x802a,
STUN_ATTR_RESP_ORIGIN = 0x802b,
STUN_ATTR_OTHER_ADDR = 0x802c,
};
struct stun_change_req {
bool ip;
bool port;
};
struct stun_errcode {
uint16_t code;
char *reason;
};
struct stun_unknown_attr {
uint16_t typev[8];
uint32_t typec;
};
struct stun_even_port {
bool r;
};
/** Defines a STUN attribute */
struct stun_attr {
struct le le;
uint16_t type;
union {
/* generic types */
struct sa sa;
char *str;
uint64_t uint64;
uint32_t uint32;
uint16_t uint16;
uint8_t uint8;
struct mbuf mb;
/* actual attributes */
struct sa mapped_addr;
struct stun_change_req change_req;
char *username;
uint8_t msg_integrity[20];
struct stun_errcode err_code;
struct stun_unknown_attr unknown_attr;
uint16_t channel_number;
uint32_t lifetime;
struct sa xor_peer_addr;
struct mbuf data;
char *realm;
char *nonce;
struct sa xor_relay_addr;
uint8_t req_addr_family;
struct stun_even_port even_port;
uint8_t req_transport;
struct sa xor_mapped_addr;
uint64_t rsv_token;
uint32_t priority;
struct mbuf padding;
uint16_t resp_port;
char *software;
struct sa alt_server;
uint32_t fingerprint;
uint64_t controlled;
uint64_t controlling;
struct sa resp_origin;
struct sa other_addr;
} v;
};
/** STUN Configuration */
struct stun_conf {
uint32_t rto; /**< RTO Retransmission TimeOut [ms] */
uint32_t rc; /**< Rc Retransmission count (default 7) */
uint32_t rm; /**< Rm Max retransmissions (default 16) */
uint32_t ti; /**< Ti Timeout for reliable transport [ms] */
uint8_t tos; /**< Type-of-service field */
};
extern const char *stun_software;
struct stun;
struct stun_msg;
struct stun_ctrans;
typedef void(stun_resp_h)(int err, uint16_t scode, const char *reason,
const struct stun_msg *msg, void *arg);
typedef void(stun_ind_h)(struct stun_msg *msg, void *arg);
typedef bool(stun_attr_h)(const struct stun_attr *attr, void *arg);
int stun_alloc(struct stun **stunp, const struct stun_conf *conf,
stun_ind_h *indh, void *arg);
struct stun_conf *stun_conf(struct stun *stun);
int stun_send(int proto, void *sock, const struct sa *dst, struct mbuf *mb);
int stun_recv(struct stun *stun, struct mbuf *mb);
int stun_ctrans_recv(struct stun *stun, const struct stun_msg *msg,
const struct stun_unknown_attr *ua);
struct re_printf;
int stun_debug(struct re_printf *pf, const struct stun *stun);
int stun_request(struct stun_ctrans **ctp, struct stun *stun, int proto,
void *sock, const struct sa *dst, size_t presz,
uint16_t method, const uint8_t *key, size_t keylen, bool fp,
stun_resp_h *resph, void *arg, uint32_t attrc, ...);
int stun_reply(int proto, void *sock, const struct sa *dst, size_t presz,
const struct stun_msg *req, const uint8_t *key,
size_t keylen, bool fp, uint32_t attrc, ...);
int stun_ereply(int proto, void *sock, const struct sa *dst, size_t presz,
const struct stun_msg *req, uint16_t scode,
const char *reason, const uint8_t *key, size_t keylen,
bool fp, uint32_t attrc, ...);
int stun_indication(int proto, void *sock, const struct sa *dst, size_t presz,
uint16_t method, const uint8_t *key, size_t keylen,
bool fp, uint32_t attrc, ...);
int stun_msg_vencode(struct mbuf *mb, uint16_t method, uint8_t cls,
const uint8_t *tid, const struct stun_errcode *ec,
const uint8_t *key, size_t keylen, bool fp,
uint8_t padding, uint32_t attrc, va_list ap);
int stun_msg_encode(struct mbuf *mb, uint16_t method, uint8_t cls,
const uint8_t *tid, const struct stun_errcode *ec,
const uint8_t *key, size_t keylen, bool fp,
uint8_t padding, uint32_t attrc, ...);
int stun_msg_decode(struct stun_msg **msgpp, struct mbuf *mb,
struct stun_unknown_attr *ua);
uint16_t stun_msg_type(const struct stun_msg *msg);
uint16_t stun_msg_class(const struct stun_msg *msg);
uint16_t stun_msg_method(const struct stun_msg *msg);
bool stun_msg_mcookie(const struct stun_msg *msg);
const uint8_t *stun_msg_tid(const struct stun_msg *msg);
struct stun_attr *stun_msg_attr(const struct stun_msg *msg, uint16_t type);
struct stun_attr *stun_msg_attr_apply(const struct stun_msg *msg,
stun_attr_h *h, void *arg);
int stun_msg_chk_mi(const struct stun_msg *msg, const uint8_t *key,
size_t keylen);
int stun_msg_chk_fingerprint(const struct stun_msg *msg);
void stun_msg_dump(const struct stun_msg *msg);
const char *stun_class_name(uint16_t cls);
const char *stun_method_name(uint16_t method);
const char *stun_attr_name(uint16_t type);
const char *stun_transp_name(enum stun_transp tp);
/* DNS Discovery of a STUN Server */
extern const char *stun_proto_udp;
extern const char *stun_proto_tcp;
extern const char *stun_usage_binding;
extern const char *stuns_usage_binding;
extern const char *stun_usage_relay;
extern const char *stuns_usage_relay;
extern const char *stun_usage_behavior;
extern const char *stuns_usage_behavior;
/**
* Defines the STUN Server Discovery handler
*
* @param err Errorcode
* @param srv IP Address and port of STUN Server
* @param arg Handler argument
*/
typedef void (stun_dns_h)(int err, const struct sa *srv, void *arg);
struct stun_dns;
struct dnsc;
int stun_server_discover(struct stun_dns **dnsp, struct dnsc *dnsc,
const char *service, const char *proto,
int af, const char *domain, uint16_t port,
stun_dns_h *dnsh, void *arg);
/* NAT Keepalives */
struct stun_keepalive;
/**
* Defines the STUN Keepalive Mapped-Address handler
*
* @param err Errorcode
* @param map Mapped Address
* @param arg Handler argument
*/
typedef void (stun_mapped_addr_h)(int err, const struct sa *map, void *arg);
int stun_keepalive_alloc(struct stun_keepalive **skap,
int proto, void *sock, int layer,
const struct sa *dst, const struct stun_conf *conf,
stun_mapped_addr_h *mah, void *arg);
void stun_keepalive_enable(struct stun_keepalive *ska, uint32_t interval);
/* STUN Reason Phrase */
extern const char *stun_reason_300;
extern const char *stun_reason_400;
extern const char *stun_reason_401;
extern const char *stun_reason_403;
extern const char *stun_reason_420;
extern const char *stun_reason_437;
extern const char *stun_reason_438;
extern const char *stun_reason_440;
extern const char *stun_reason_441;
extern const char *stun_reason_442;
extern const char *stun_reason_443;
extern const char *stun_reason_486;
extern const char *stun_reason_500;
extern const char *stun_reason_508;

View file

@ -0,0 +1,73 @@
/**
* @file re_sys.h Interface to system module
*
* Copyright (C) 2010 Creytiv.com
*/
#ifndef VERSION
#define VERSION "?"
#endif
/**
* @def ARCH
*
* Architecture
*/
#ifndef ARCH
#define ARCH "?"
#endif
/**
* @def OS
*
* Operating System
*/
#ifndef OS
#ifdef WIN32
#define OS "win32"
#else
#define OS "?"
#endif
#endif
struct re_printf;
int sys_rel_get(uint32_t *rel, uint32_t *maj, uint32_t *min,
uint32_t *patch);
int sys_kernel_get(struct re_printf *pf, void *unused);
int sys_build_get(struct re_printf *pf, void *unused);
const char *sys_arch_get(void);
const char *sys_os_get(void);
const char *sys_libre_version_get(void);
const char *sys_username(void);
int sys_coredump_set(bool enable);
int sys_daemon(void);
void sys_usleep(unsigned int us);
static inline void sys_msleep(unsigned int ms)
{
sys_usleep(ms * 1000);
}
uint16_t sys_htols(uint16_t v);
uint32_t sys_htoll(uint32_t v);
uint16_t sys_ltohs(uint16_t v);
uint32_t sys_ltohl(uint32_t v);
uint64_t sys_htonll(uint64_t v);
uint64_t sys_ntohll(uint64_t v);
/* Random */
void rand_init(void);
uint16_t rand_u16(void);
uint32_t rand_u32(void);
uint64_t rand_u64(void);
char rand_char(void);
void rand_str(char *str, size_t size);
void rand_bytes(uint8_t *p, size_t size);
/* File-System */
int fs_mkdir(const char *path, uint16_t mode);
int fs_gethome(char *path, size_t sz);

View file

@ -0,0 +1,101 @@
/**
* @file re_tcp.h Interface to Transport Control Protocol
*
* Copyright (C) 2010 Creytiv.com
*/
struct sa;
struct tcp_sock;
struct tcp_conn;
/**
* Defines the incoming TCP connection handler
*
* @param peer Network address of peer
* @param arg Handler argument
*/
typedef void (tcp_conn_h)(const struct sa *peer, void *arg);
/**
* Defines the TCP connection established handler
*
* @param arg Handler argument
*/
typedef void (tcp_estab_h)(void *arg);
/**
* Defines the TCP connection data send handler
*
* @param arg Handler argument
*/
typedef void (tcp_send_h)(void *arg);
/**
* Defines the TCP connection data receive handler
*
* @param mb Buffer with data
* @param arg Handler argument
*/
typedef void (tcp_recv_h)(struct mbuf *mb, void *arg);
/**
* Defines the TCP connection close handler
*
* @param err Error code
* @param arg Handler argument
*/
typedef void (tcp_close_h)(int err, void *arg);
/* TCP Socket */
int tcp_sock_alloc(struct tcp_sock **tsp, const struct sa *local,
tcp_conn_h *ch, void *arg);
int tcp_sock_bind(struct tcp_sock *ts, const struct sa *local);
int tcp_sock_listen(struct tcp_sock *ts, int backlog);
int tcp_accept_sip(struct tcp_conn **tcp, struct tcp_sock *ts, tcp_estab_h *eh,
tcp_recv_h *rh, tcp_close_h *ch, void *arg);
void tcp_reject(struct tcp_sock *ts);
int tcp_sock_local_get(const struct tcp_sock *ts, struct sa *local);
/* TCP Connection */
int tcp_conn_alloc(struct tcp_conn **tcp, const struct sa *peer,
tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch,
void *arg);
int tcp_conn_bind(struct tcp_conn *tc, const struct sa *local);
int tcp_conn_connect(struct tcp_conn *tc, const struct sa *peer);
int tcp_send(struct tcp_conn *tc, struct mbuf *mb);
int tcp_set_send(struct tcp_conn *tc, tcp_send_h *sendh);
void tcp_set_handlers(struct tcp_conn *tc, tcp_estab_h *eh, tcp_recv_h *rh,
tcp_close_h *ch, void *arg);
void tcp_conn_rxsz_set(struct tcp_conn *tc, size_t rxsz);
void tcp_conn_txqsz_set(struct tcp_conn *tc, size_t txqsz);
int tcp_conn_local_get(const struct tcp_conn *tc, struct sa *local);
int tcp_conn_peer_get(const struct tcp_conn *tc, struct sa *peer);
int tcp_conn_fd(const struct tcp_conn *tc);
size_t tcp_conn_txqsz(const struct tcp_conn *tc);
/* High-level API */
int tcp_listen(struct tcp_sock **tsp, const struct sa *local,
tcp_conn_h *ch, void *arg);
int tcp_connect_sip(struct tcp_conn **tcp, const struct sa *peer,
tcp_estab_h *eh, tcp_recv_h *rh, tcp_close_h *ch, void *arg);
int tcp_local_get(const struct tcp_sock *ts, struct sa *local);
/* Helper API */
typedef bool (tcp_helper_estab_h)(int *err, bool active, void *arg);
typedef bool (tcp_helper_send_h)(int *err, struct mbuf *mb, void *arg);
typedef bool (tcp_helper_recv_h)(int *err, struct mbuf *mb, bool *estab,
void *arg);
struct tcp_helper;
int tcp_register_helper(struct tcp_helper **thp, struct tcp_conn *tc,
int layer,
tcp_helper_estab_h *eh, tcp_helper_send_h *sh,
tcp_helper_recv_h *rh, void *arg);
int tcp_send_helper(struct tcp_conn *tc, struct mbuf *mb,
struct tcp_helper *th);

View file

@ -0,0 +1,23 @@
/**
* @file re_telev.h Interface to Telephony Events (RFC 4733)
*
* Copyright (C) 2010 Creytiv.com
*/
enum {
TELEV_PTIME = 50,
TELEV_SRATE = 8000
};
struct telev;
extern const char telev_rtpfmt[];
int telev_alloc(struct telev **tp, uint32_t ptime);
int telev_set_srate(struct telev *tel, uint32_t srate);
int telev_send(struct telev *tel, int event, bool end);
int telev_recv(struct telev *tel, struct mbuf *mb, int *event, bool *end);
int telev_poll(struct telev *tel, bool *marker, struct mbuf *mb);
int telev_digit2code(int digit);
int telev_code2digit(int code);

View file

@ -0,0 +1,101 @@
/**
* @file re_tls.h Interface to Transport Layer Security
*
* Copyright (C) 2010 Creytiv.com
*/
struct tls;
struct tls_conn;
struct tcp_conn;
struct udp_sock;
/** Defines the TLS method */
enum tls_method {
TLS_METHOD_SSLV23,
TLS_METHOD_DTLSV1,
TLS_METHOD_DTLS, /* DTLS 1.0 and 1.2 */
TLS_METHOD_DTLSV1_2, /* DTLS 1.2 */
};
enum tls_fingerprint {
TLS_FINGERPRINT_SHA1,
TLS_FINGERPRINT_SHA256,
};
enum tls_keytype {
TLS_KEYTYPE_RSA,
TLS_KEYTYPE_EC,
};
int tls_alloc(struct tls **tlsp, enum tls_method method, const char *keyfile,
const char *pwd);
int tls_add_ca(struct tls *tls, const char *capath);
int tls_set_selfsigned(struct tls *tls, const char *cn);
int tls_set_certificate_pem(struct tls *tls, const char *cert, size_t len_cert,
const char *key, size_t len_key);
int tls_set_certificate_der(struct tls *tls, enum tls_keytype keytype,
const uint8_t *cert, size_t len_cert,
const uint8_t *key, size_t len_key);
int tls_set_certificate(struct tls *tls, const char *cert, size_t len);
void tls_set_verify_client(struct tls *tls);
int tls_set_srtp(struct tls *tls, const char *suites);
int tls_fingerprint(const struct tls *tls, enum tls_fingerprint type,
uint8_t *md, size_t size);
int tls_peer_fingerprint(const struct tls_conn *tc, enum tls_fingerprint type,
uint8_t *md, size_t size);
int tls_peer_common_name(const struct tls_conn *tc, char *cn, size_t size);
int tls_peer_verify(const struct tls_conn *tc);
int tls_srtp_keyinfo(const struct tls_conn *tc, enum srtp_suite *suite,
uint8_t *cli_key, size_t cli_key_size,
uint8_t *srv_key, size_t srv_key_size);
const char *tls_cipher_name(const struct tls_conn *tc);
int tls_set_ciphers(struct tls *tls, const char *cipherv[], size_t count);
int tls_set_servername(struct tls_conn *tc, const char *servername);
/* TCP */
int tls_start_tcp(struct tls_conn **ptc, struct tls *tls,
struct tcp_conn *tcp, int layer);
/* UDP (DTLS) */
typedef void (dtls_conn_h)(const struct sa *peer, void *arg);
typedef void (dtls_estab_h)(void *arg);
typedef void (dtls_recv_h)(struct mbuf *mb, void *arg);
typedef void (dtls_close_h)(int err, void *arg);
struct dtls_sock;
int dtls_listen(struct dtls_sock **sockp, const struct sa *laddr,
struct udp_sock *us, uint32_t htsize, int layer,
dtls_conn_h *connh, void *arg);
struct udp_sock *dtls_udp_sock(struct dtls_sock *sock);
void dtls_set_mtu(struct dtls_sock *sock, size_t mtu);
int dtls_connect(struct tls_conn **ptc, struct tls *tls,
struct dtls_sock *sock, const struct sa *peer,
dtls_estab_h *estabh, dtls_recv_h *recvh,
dtls_close_h *closeh, void *arg);
int dtls_accept(struct tls_conn **ptc, struct tls *tls,
struct dtls_sock *sock,
dtls_estab_h *estabh, dtls_recv_h *recvh,
dtls_close_h *closeh, void *arg);
int dtls_send(struct tls_conn *tc, struct mbuf *mb);
void dtls_set_handlers(struct tls_conn *tc, dtls_estab_h *estabh,
dtls_recv_h *recvh, dtls_close_h *closeh, void *arg);
const struct sa *dtls_peer(const struct tls_conn *tc);
void dtls_set_peer(struct tls_conn *tc, const struct sa *peer);
void dtls_recv_packet(struct dtls_sock *sock, const struct sa *src,
struct mbuf *mb);
#ifdef USE_OPENSSL
struct ssl_ctx_st;
struct ssl_ctx_st *tls_openssl_context(const struct tls *tls);
#endif

View file

@ -0,0 +1,46 @@
/**
* @file re_tmr.h Interface to timer implementation
*
* Copyright (C) 2010 Creytiv.com
*/
/**
* Defines the timeout handler
*
* @param arg Handler argument
*/
typedef void (tmr_h)(void *arg);
/** Defines a timer */
struct tmr {
struct le le; /**< Linked list element */
tmr_h *th; /**< Timeout handler */
void *arg; /**< Handler argument */
uint64_t jfs; /**< Jiffies for timeout */
};
void tmr_poll(struct list *tmrl);
uint64_t tmr_jiffies(void);
uint64_t tmr_next_timeout(struct list *tmrl);
void tmr_debug(void);
int tmr_status(struct re_printf *pf, void *unused);
void tmr_init(struct tmr *tmr);
void tmr_start(struct tmr *tmr, uint64_t delay, tmr_h *th, void *arg);
void tmr_cancel(struct tmr *tmr);
uint64_t tmr_get_expire(const struct tmr *tmr);
/**
* Check if the timer is running
*
* @param tmr Timer to check
*
* @return true if running, false if not running
*/
static inline bool tmr_isrunning(const struct tmr *tmr)
{
return tmr ? NULL != tmr->th : false;
}

View file

@ -0,0 +1,33 @@
/**
* @file re_turn.h Interface to TURN implementation
*
* Copyright (C) 2010 Creytiv.com
*/
/** TURN Protocol values */
enum {
TURN_DEFAULT_LIFETIME = 600, /**< Default lifetime is 10 minutes */
TURN_MAX_LIFETIME = 3600 /**< Maximum lifetime is 1 hour */
};
typedef void(turnc_h)(int err, uint16_t scode, const char *reason,
const struct sa *relay_addr,
const struct sa *mapped_addr,
const struct stun_msg *msg,
void *arg);
typedef void(turnc_perm_h)(void *arg);
typedef void(turnc_chan_h)(void *arg);
struct turnc;
int turnc_alloc(struct turnc **turncp, const struct stun_conf *conf, int proto,
void *sock, int layer, const struct sa *srv,
const char *username, const char *password,
uint32_t lifetime, turnc_h *th, void *arg);
int turnc_send(struct turnc *turnc, const struct sa *dst, struct mbuf *mb);
int turnc_recv(struct turnc *turnc, struct sa *src, struct mbuf *mb);
int turnc_add_perm(struct turnc *turnc, const struct sa *peer,
turnc_perm_h *ph, void *arg);
int turnc_add_chan(struct turnc *turnc, const struct sa *peer,
turnc_chan_h *ch, void *arg);

View file

@ -0,0 +1,288 @@
/**
* @file re_types.h Defines basic types
*
* Copyright (C) 2010 Creytiv.com
*/
#if defined(CONFIG_PLATFORM_8195BHP)
#include <stddef.h>
#include <stdio.h>
#include "lwipopts.h"
#include <lwip/arch.h>
#include <lwip/sockets.h>
#include "netdb.h"
#ifndef __u_char_defined
/* Type definitions for BSD code. */
typedef unsigned long u_long;
typedef unsigned int u_int;
typedef unsigned short u_short;
typedef unsigned char u_char;
#endif
#define FILE void
#define stderr NULL
#define stdout NULL
#else
#include <sys/types.h>
#endif
#if defined(CONFIG_PLATFORM_8195BHP)
#define SIPTEST_DEBUG 0
#if SIPTEST_DEBUG
#define SIP_PRINTF(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#define SIP_ERROR(fmt, args...) printf("\n\r%s: " fmt, __FUNCTION__, ## args)
#else
#define SIP_PRINTF(fmt, args...)
#define SIP_ERROR(fmt, args...)
#endif
#endif
#ifdef _MSC_VER
#include <stdlib.h>
#endif
/*
* Basic integral types from C99
*/
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#else
#ifndef __int8_t_defined
#define __int8_t_defined
/* Hack for OpenBSD */
#ifndef __BIT_TYPES_DEFINED__
#if defined(_CHAR_IS_SIGNED)
typedef char int8_t;
#elif defined(__STDC__)
typedef signed char int8_t;
#else
typedef char int8_t;
#endif
typedef signed short int int16_t;
typedef signed int int32_t;
typedef signed long long int int64_t;
#ifndef __uint32_t_defined
#define __uint32_t_defined
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long int uint64_t;
#endif
#endif /* __BIT_TYPES_DEFINED__ */
#endif /* __int8_t_defined */
#ifndef __ssize_t_defined
typedef long ssize_t;
#define __ssize_t_defined
#endif
#ifndef WIN32
typedef uint32_t socklen_t;
#endif
#endif
/*
* Hack for Solaris which does not define int64_t/uint64_t for strict ANSI C
*/
#ifdef SOLARIS
#if !(__STDC__ - 0 == 0 && !defined(_NO_LONGLONG))
typedef signed long long int int64_t;
typedef unsigned long long int uint64_t;
#endif
#endif
/*
* Boolean type
* see http://www.opengroup.org/onlinepubs/000095399/basedefs/stdbool.h.html
* www.gnu.org/software/autoconf/manual/html_node/Particular-Headers.html
*/
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#else
# ifndef HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
# define _Bool signed char
# endif
# endif
# define bool _Bool
# define false 0
# define true 1
# define __bool_true_false_are_defined 1
#endif
/* Needed for MS compiler */
#ifdef _MSC_VER
#ifndef __cplusplus
#define inline _inline
#endif
#endif
/*
* Misc macros
*/
/** Defines the NULL pointer */
#ifndef NULL
#define NULL ((void *)0)
#endif
/** Get number of elements in an array */
#undef ARRAY_SIZE
#define ARRAY_SIZE(a) ((sizeof(a))/(sizeof((a)[0])))
/** Align a value to the boundary of mask */
#define ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
/** Get the minimal value */
#undef MIN
#define MIN(a,b) (((a)<(b)) ? (a) : (b))
/** Get the maximal value */
#undef MAX
#define MAX(a,b) (((a)>(b)) ? (a) : (b))
#ifndef __cplusplus
/** Get the minimal value */
#undef min
#define min(x,y) MIN(x, y)
/** Get the maximal value */
#undef max
#define max(x,y) MAX(x, y)
#endif
/** Defines a soft breakpoint */
#if (defined(__i386__) || defined(__x86_64__))
#define BREAKPOINT __asm__("int $0x03")
#else
#define BREAKPOINT
#endif
/* Error codes */
#include <errno.h>
/* Duplication of error codes. Values are from linux asm-generic/errno.h */
/** No data available */
#ifndef ENODATA
#define ENODATA 200
#endif
/** Protocol error */
#ifndef EPROTO
#define EPROTO 201
#endif
/** Not a data message */
#ifndef EBADMSG
#define EBADMSG 202
#endif
/** Value too large for defined data type */
#ifndef EOVERFLOW
#define EOVERFLOW 203
#endif
/** Accessing a corrupted shared library */
#ifndef ELIBBAD
#define ELIBBAD 204
#endif
/** Destination address required */
#ifndef EDESTADDRREQ
#define EDESTADDRREQ 205
#endif
/** Protocol not supported */
#ifndef EPROTONOSUPPORT
#define EPROTONOSUPPORT 206
#endif
/** Operation not supported */
#ifndef ENOTSUP
#define ENOTSUP 207
#endif
/** Address family not supported by protocol */
#ifndef EAFNOSUPPORT
#define EAFNOSUPPORT 208
#endif
/** Cannot assign requested address */
#ifndef EADDRNOTAVAIL
#define EADDRNOTAVAIL 209
#endif
/** Software caused connection abort */
#ifndef ECONNABORTED
#define ECONNABORTED 210
#endif
/** Connection reset by peer */
#ifndef ECONNRESET
#define ECONNRESET 211
#endif
/** Transport endpoint is not connected */
#ifndef ENOTCONN
#define ENOTCONN 212
#endif
/** Connection timed out */
#ifndef ETIMEDOUT
#define ETIMEDOUT 213
#endif
/** Connection refused */
#ifndef ECONNREFUSED
#define ECONNREFUSED 214
#endif
/** Operation already in progress */
#ifndef EALREADY
#define EALREADY 215
#endif
/** Operation now in progress */
#ifndef EINPROGRESS
#define EINPROGRESS 216
#endif
/** Authentication error */
#ifndef EAUTH
#define EAUTH 217
#endif
/** No STREAM resources */
#ifndef ENOSR
#define ENOSR 218
#endif
/*
* Any C compiler conforming to C99 or later MUST support __func__
*/
#if __STDC_VERSION__ >= 199901L
#define __REFUNC__ (const char *)__func__
#else
#define __REFUNC__ __FUNCTION__
#endif

View file

@ -0,0 +1,65 @@
/**
* @file re_udp.h Interface to User Datagram Protocol
*
* Copyright (C) 2010 Creytiv.com
*/
struct sa;
struct udp_sock;
/**
* Defines the UDP Receive handler
*
* @param src Source address
* @param mb Datagram buffer
* @param arg Handler argument
*/
typedef void (udp_recv_h)(const struct sa *src, struct mbuf *mb, void *arg);
typedef void (udp_error_h)(int err, void *arg);
#if 0 //def ENABLE_SIP_MMFV2
int get_udp_fd(struct udp_sock *us);
#endif
int udp_listen(struct udp_sock **usp, const struct sa *local,
udp_recv_h *rh, void *arg);
int udp_connect_sip(struct udp_sock *us, const struct sa *peer);
int udp_send_sip(struct udp_sock *us, const struct sa *dst, struct mbuf *mb);
int udp_send_anon(const struct sa *dst, struct mbuf *mb);
int udp_local_get(const struct udp_sock *us, struct sa *local);
int udp_setsockopt(struct udp_sock *us, int level, int optname,
const void *optval, uint32_t optlen);
int udp_sockbuf_set(struct udp_sock *us, int size);
void udp_rxsz_set(struct udp_sock *us, size_t rxsz);
void udp_rxbuf_presz_set(struct udp_sock *us, size_t rx_presz);
void udp_handler_set(struct udp_sock *us, udp_recv_h *rh, void *arg);
void udp_error_handler_set(struct udp_sock *us, udp_error_h *eh);
int udp_thread_attach(struct udp_sock *us);
void udp_thread_detach(struct udp_sock *us);
int udp_sock_fd(const struct udp_sock *us, int af);
int udp_multicast_join(struct udp_sock *us, const struct sa *group);
int udp_multicast_leave(struct udp_sock *us, const struct sa *group);
/* Helper API */
typedef bool (udp_helper_send_h)(int *err, struct sa *dst,
struct mbuf *mb, void *arg);
typedef bool (udp_helper_recv_h)(struct sa *src,
struct mbuf *mb, void *arg);
struct udp_helper;
int udp_register_helper(struct udp_helper **uhp, struct udp_sock *us,
int layer,
udp_helper_send_h *sh, udp_helper_recv_h *rh,
void *arg);
int udp_send_helper(struct udp_sock *us, const struct sa *dst,
struct mbuf *mb, struct udp_helper *uh);
struct udp_helper *udp_helper_find(const struct udp_sock *us, int layer);

View file

@ -0,0 +1,43 @@
/**
* @file re_uri.h Interface to URI module
*
* Copyright (C) 2010 Creytiv.com
*/
/** Defines a URI - Uniform Resource Identifier */
struct uri {
struct pl scheme; /**< URI scheme e.g. "sip:" "sips:" */
struct pl user; /**< Username */
struct pl password; /**< Optional password */
struct pl host; /**< Hostname or IP-address */
int af; /**< Address family of host IP-address */
uint16_t port; /**< Port number */
struct pl params; /**< Optional URI-parameters */
struct pl headers; /**< Optional URI-headers */
};
typedef int (uri_apply_h)(const struct pl *name, const struct pl *val,
void *arg);
struct re_printf;
int uri_encode(struct re_printf *pf, const struct uri *uri);
int uri_decode(struct uri *uri, const struct pl *pl);
int uri_param_get(const struct pl *pl, const struct pl *pname,
struct pl *pvalue);
int uri_params_apply(const struct pl *pl, uri_apply_h *ah, void *arg);
int uri_header_get(const struct pl *pl, const struct pl *hname,
struct pl *hvalue);
int uri_headers_apply(const struct pl *pl, uri_apply_h *ah, void *arg);
bool uri_cmp(const struct uri *l, const struct uri *r);
/* Special URI escaping/unescaping */
int uri_user_escape(struct re_printf *pf, const struct pl *pl);
int uri_user_unescape(struct re_printf *pf, const struct pl *pl);
int uri_password_escape(struct re_printf *pf, const struct pl *pl);
int uri_password_unescape(struct re_printf *pf, const struct pl *pl);
int uri_param_escape(struct re_printf *pf, const struct pl *pl);
int uri_param_unescape(struct re_printf *pf, const struct pl *pl);
int uri_header_escape(struct re_printf *pf, const struct pl *pl);
int uri_header_unescape(struct re_printf *pf, const struct pl *pl);

View file

@ -0,0 +1,74 @@
/**
* @file re_websock.h The WebSocket Protocol
*
* Copyright (C) 2010 Creytiv.com
*/
enum {
WEBSOCK_VERSION = 13,
};
enum websock_opcode {
/* Data frames */
WEBSOCK_CONT = 0x0,
WEBSOCK_TEXT = 0x1,
WEBSOCK_BIN = 0x2,
/* Control frames */
WEBSOCK_CLOSE = 0x8,
WEBSOCK_PING = 0x9,
WEBSOCK_PONG = 0xa,
};
enum websock_scode {
WEBSOCK_NORMAL_CLOSURE = 1000,
WEBSOCK_GOING_AWAY = 1001,
WEBSOCK_PROTOCOL_ERROR = 1002,
WEBSOCK_UNSUPPORTED_DATA = 1003,
WEBSOCK_INVALID_PAYLOAD = 1007,
WEBSOCK_POLICY_VIOLATION = 1008,
WEBSOCK_MESSAGE_TOO_BIG = 1009,
WEBSOCK_EXTENSION_ERROR = 1010,
WEBSOCK_INTERNAL_ERROR = 1011,
};
struct websock_hdr {
unsigned fin:1;
unsigned rsv1:1;
unsigned rsv2:1;
unsigned rsv3:1;
unsigned opcode:4;
unsigned mask:1;
uint64_t len;
uint8_t mkey[4];
};
struct websock;
struct websock_conn;
typedef void (websock_estab_h)(void *arg);
typedef void (websock_recv_h)(const struct websock_hdr *hdr, struct mbuf *mb,
void *arg);
typedef void (websock_close_h)(int err, void *arg);
int websock_connect(struct websock_conn **connp, struct websock *sock,
struct http_cli *cli, const char *uri, unsigned kaint,
websock_estab_h *estabh, websock_recv_h *recvh,
websock_close_h *closeh, void *arg,
const char *fmt, ...);
int websock_accept(struct websock_conn **connp, struct websock *sock,
struct http_conn *htconn, const struct http_msg *msg,
unsigned kaint, websock_recv_h *recvh,
websock_close_h *closeh, void *arg);
int websock_send(struct websock_conn *conn, enum websock_opcode opcode,
const char *fmt, ...);
int websock_close(struct websock_conn *conn, enum websock_scode scode,
const char *fmt, ...);
const struct sa *websock_peer(const struct websock_conn *conn);
typedef void (websock_shutdown_h)(void *arg);
int websock_alloc(struct websock **sockp, websock_shutdown_h *shuth,
void *arg);
void websock_shutdown(struct websock *sock);

View file

@ -0,0 +1,225 @@
/**
* @file test.h Selftest for Baresip core -- internal API
*
* Copyright (C) 2010 Creytiv.com
*/
#define ASSERT_TRUE(cond) \
if (!(cond)) { \
warning("selftest: ASSERT_TRUE: %s:%u:\n", \
__FILE__, __LINE__); \
err = EINVAL; \
goto out; \
}
#define ASSERT_EQ(expected, actual) \
if ((expected) != (actual)) { \
warning("selftest: ASSERT_EQ: %s:%u:" \
" expected=%d, actual=%d\n", \
__FILE__, __LINE__, \
(int)(expected), (int)(actual)); \
err = EINVAL; \
goto out; \
}
#define ASSERT_DOUBLE_EQ(expected, actual, prec) \
if (!test_cmp_double((expected), (actual), (prec))) { \
warning("selftest: ASSERT_DOUBLE_EQ: %s:%u:" \
" expected=%f, actual=%f\n", \
__FILE__, __LINE__, \
(double)(expected), (double)(actual)); \
err = EINVAL; \
goto out; \
}
#define ASSERT_STREQ(expected, actual) \
if (0 != str_cmp((expected), (actual))) { \
warning("selftest: ASSERT_STREQ: %s:%u:" \
" expected = '%s', actual = '%s'\n", \
__FILE__, __LINE__, \
(expected), (actual)); \
err = EBADMSG; \
goto out; \
}
#define TEST_ERR(err) \
if ((err)) { \
(void)re_fprintf(stderr, "\n"); \
warning("TEST_ERR: %s:%u:" \
" (%m)\n", \
__FILE__, __LINE__, \
(err)); \
goto out; \
}
#define TEST_MEMCMP(expected, expn, actual, actn) \
if (expn != actn || \
0 != memcmp((expected), (actual), (expn))) { \
(void)re_fprintf(stderr, "\n"); \
warning("TEST_MEMCMP: %s:%u:" \
" %s(): failed\n", \
__FILE__, __LINE__, __func__); \
test_hexdump_dual(stderr, \
expected, expn, \
actual, actn); \
err = EINVAL; \
goto out; \
}
#define TEST_STRCMP(expected, expn, actual, actn) \
if (expn != actn || \
0 != memcmp((expected), (actual), (expn))) { \
(void)re_fprintf(stderr, "\n"); \
warning("TEST_STRCMP: %s:%u:" \
" failed\n", \
__FILE__, __LINE__); \
(void)re_fprintf(stderr, \
"expected string: (%zu bytes)\n" \
"\"%b\"\n", \
(size_t)(expn), \
(expected), (size_t)(expn)); \
(void)re_fprintf(stderr, \
"actual string: (%zu bytes)\n" \
"\"%b\"\n", \
(size_t)(actn), \
(actual), (size_t)(actn)); \
err = EINVAL; \
goto out; \
}
/* helpers */
int re_main_timeout(uint32_t timeout_ms);
bool test_cmp_double(double a, double b, double precision);
void test_hexdump_dual(FILE *f,
const void *ep, size_t elen,
const void *ap, size_t alen);
#ifdef USE_TLS
extern const char test_certificate[];
#endif
/*
* Mock DNS-Server
*/
struct dns_server {
struct udp_sock *us;
struct sa addr;
struct list rrl;
bool rotate;
};
int dns_server_alloc(struct dns_server **srvp, bool rotate);
int dns_server_add_a(struct dns_server *srv,
const char *name, uint32_t addr);
int dns_server_add_srv(struct dns_server *srv, const char *name,
uint16_t pri, uint16_t weight, uint16_t port,
const char *target);
/*
* Mock Audio-codec
*/
void mock_aucodec_register(void);
void mock_aucodec_unregister(void);
/*
* Mock Audio-source
*/
struct ausrc;
int mock_ausrc_register(struct ausrc **ausrcp);
/*
* Mock Audio-player
*/
struct auplay;
typedef void (mock_sample_h)(const void *sampv, size_t sampc, void *arg);
int mock_auplay_register(struct auplay **auplayp,
mock_sample_h *sampleh, void *arg);
/*
* Mock Video-source
*/
struct vidsrc;
int mock_vidsrc_register(struct vidsrc **vidsrcp);
/*
* Mock Video-codec
*/
void mock_vidcodec_register(void);
void mock_vidcodec_unregister(void);
/*
* Mock Video-display
*/
struct vidisp;
int mock_vidisp_register(struct vidisp **vidispp);
/* test cases */
int test_account(void);
int test_aulevel(void);
int test_cmd(void);
int test_cmd_long(void);
int test_event(void);
int test_contact(void);
int test_ua_alloc(void);
int test_uag_find_param(void);
int test_ua_register(void);
int test_ua_register_dns(void);
int test_ua_register_auth(void);
int test_ua_register_auth_dns(void);
int test_ua_options(void);
int test_message(void);
int test_mos(void);
int test_network(void);
int test_play(void);
int test_call_answer(void);
int test_call_reject(void);
int test_call_af_mismatch(void);
int test_call_answer_hangup_a(void);
int test_call_answer_hangup_b(void);
int test_call_rtp_timeout(void);
int test_call_multiple(void);
int test_call_max(void);
int test_call_dtmf(void);
int test_call_video(void);
int test_call_aulevel(void);
int test_call_progress(void);
int test_call_format_float(void);
#ifdef USE_VIDEO
int test_video(void);
#endif
#ifdef __cplusplus
extern "C" {
#endif
int test_cplusplus(void);
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,69 @@
#ifndef _RTP_SIP_API_H_
#define _RTP_SIP_API_H_
#include "rtsp/rtp_api.h"
#include <stdint.h>
#include "dlist.h"
#include "osdep_service.h"
#include "avcodec.h"
#include <lwip/def.h> //for host network byte order convertion
/* from error_base.h */
#define EIO 5 /* I/O error */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EINVAL 22 /* Invalid argument */
#define RTP_BIG_ENDIAN 0
#define RTP_HDR_SZ 12
#define RTP_SERVER_PORT_BASE 55608
#define RTP_PORT_BASE 50020
#define RTP_CLIENT_PORT_BASE 51020
/*
* RTP data header from RFC1889
*/
/*
*
*
* The RTP header has the following format:
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |V=2|P|X| CC |M| PT | sequence number |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | timestamp |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | synchronization source (SSRC) identifier |
* +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
* | contributing source (CSRC) identifiers |
* | .... |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* RTP data header
*/
struct rtp_hdr_t;
struct connect_context;
struct rtp_statistics;
struct rtp_periodic_report_s;
enum rtp_object_state;
struct ua_stream_context;
struct rtp_object;
void sip_rtp_object_init(struct rtp_object *payload);
void sip_rtp_object_deinit(struct rtp_object *payload);
void sip_rtp_object_set_fs(struct rtp_object *payload, int flag);
void sip_rtp_object_set_fe(struct rtp_object *payload, int flag);
void sip_rtp_object_set_fk(struct rtp_object *payload, int flag);
void sip_rtp_object_set_fd(struct rtp_object *payload, int size);
void sip_rtp_fill_header(rtp_hdr_t *rtphdr, int version, int padding, int extension, int cc, int marker, int pt, uint16_t seq, uint32_t ts, uint32_t ssrc);
int sip_rtp_parse_header(uint8_t *src, rtp_hdr_t *rtphdr, int is_nbo);
void sip_rtp_dump_header(rtp_hdr_t *rtphdr, int is_nbo);
void sip_rtp_report(struct ua_stream_context *stream_ctx);
void sip_rtp_load_o_handler_by_codec_id(struct rtp_object *payload, int id);
#endif

View file

@ -0,0 +1,171 @@
#ifndef _UA_API_H_
#define _UA_API_H_
#include "dlist.h"
#include "basic_types.h"
#include "osdep_service.h"
#if defined(CONFIG_PLATFORM_8195A)
#include "mmf_dbg.h"
#endif
#if defined(CONFIG_PLATFORM_8195BHP)
#include "mmf2_dbg.h"
#endif
#include "rtsp/rtp_api.h"
//#include "sip/rtp_sip_api.h"
#include "avcodec.h"
#include "re/inc/baresip.h"
#define ENABLE_PROXY_SEVER 0
#if ENABLE_PROXY_SEVER
#define PROXY_SERVER_IP "52.198.104.214"
#define PROXY_SERVER_PORT 5000
#endif
/* clock usage */
#define UA_DEPEND_CLK_HZ configTICK_RATE_HZ
#define UA_SERVICE_PRIORITY 3
#define UA_MAX_STREAM_NUM 2
#define UA_REQUEST_BUF_SIZE 512
#define UA_RESPONSE_BUF_SIZE MAX_SDP_SIZE //max size for response buffer
#define DEF_SIP_PORT 5060
#define UA_SERVICE_PRIORITY 3
#define SIP_MAX_STREAM_NUM 2
/*rtsp cast mode list*/
#define UNICAST_UDP_MODE 1
#define UNICAST_TCP_MODE 2
#define MULTICAST_MODE 3
struct __internal_sip_payload{
int codec_id;
struct rtp_object payload;
};
struct ua_stream_context
{
struct ua_context *parent;
int stream_id; //sync with stream_flow id
struct list_head input_queue;
_mutex input_lock;
struct list_head output_queue;
_mutex output_lock;
struct codec_info *codec;
uint8_t media_type;
uint8_t framerate;
uint32_t bitrate;
uint32_t samplerate;
uint32_t channel;
uint32_t old_depend_clock_tick;
uint32_t rtp_timestamp;
uint8_t use_rtp_tick_inc;
uint8_t index;
struct rtp_statistics statistics;
struct rtp_periodic_report_s periodic_report;
struct __internal_sip_payload rtpobj;
};
struct ua_session
{
uint32_t id;
uint8_t version;
uint32_t start_time;
uint32_t end_time;
uint8_t *user;
uint8_t *name;
};
struct ua_sip_transport
{
uint8_t isRtp; //transport protocol
uint8_t isTcp; //lower transport protocol
uint8_t castMode; //unicast UDP(1) or unicast TCP(2) or multicast(3)
int port_low;
int port_high;
int clientport_low;
int clientport_high;
int serverport_low;
int serverport_high;
uint8_t ttl; //multicast time to live
//to be added if necessary
};
#if 1
struct ua_context
{
int id;
uint8_t is_connected_to_proxy;
int proxy_socket;
int proxy_port;
u16 rtpseq[SIP_MAX_STREAM_NUM];
char *peer_uri;
struct ua *user_agent;
struct call *call;
struct ua_sip_transport transport[SIP_MAX_STREAM_NUM]; /*<<mmfv2 connect info for RTP and encoder setting >>*/
struct connect_context connect_ctx; /*<mmfv2 connect info for RTP and encoder setting >*/
uint8_t is_ua_start;
uint8_t is_rtp_start; /*<RTP mmfv2 flag>*/
_sema start_rtp_sema; /*<RTP mmfv2 RTP send Semaphore, when up, start to RTP packet send>*/
_sema start_ua_sema;
void (* rtp_service_handle) (struct ua_context* ua_ctx);
_sema start_proxy_connect_sema;
_sema rtp_input_sema;
_sema rtp_output_sema;
#ifdef SUPPORT_RTCP
uint8_t is_rtcp_start;
_sema start_rtcp_sema;
void (* rtcp_service_handle) (struct ua_context* ua_ctx);
#endif
#ifdef SUPPORT_HTTP
//to be added
#endif
uint8_t nb_streams_setup;
uint8_t nb_streams;
struct ua_stream_context *stream_ctx;
uint32_t pre_filter_packet;
};
#endif
void ua_time_sync_disable(void);
void ua_time_sync_enable(void);
void ua_transport_init(struct ua_context *ua_ctx);
void ua_stream_context_init(struct ua_context *ua_ctx, struct ua_stream_context *stream_ctx);
void ua_stream_context_clear(struct ua_stream_context *stream_ctx);
void ua_enable_stream(struct call *call);
void ua_disable_stream(struct call *call);
void ua_rtp_stream_statistics_sync(struct ua_stream_context *stream_ctx);
uint32_t ua_get_timestamp(struct ua_stream_context *stream_ctx, uint32_t current_clock_tick);
struct ua_context *ua_context_create(uint8_t nb_streams);
void ua_context_free(struct ua_context *ua_ctx);
int ua_is_stream_enabled(struct ua_context *ua_ctx);
int ua_is_service_enabled(struct ua_context *ua_ctx);
int ua_open(struct ua_context *ua_ctx);
void ua_close(struct ua_context *ua_ctx);
void ua_start(struct ua_context *ua_ctx);
void ua_stop(struct ua_context *ua_ctx);
void ua_rtp_object_in_stream_queue(struct rtp_object *payload, struct ua_stream_context *stream_ctx);
struct rtp_object *ua_rtp_object_out_stream_queue(struct ua_stream_context *stream_ctx);
#endif