stream-deploy/ZLM/3rdpart/media-server/libsip/include/sip-header.h

237 lines
7.7 KiB
C++

#ifndef _sip_header_h_
#define _sip_header_h_
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include "cstring.h"
#include "darray.h"
#if defined(__cplusplus)
extern "C" {
#endif
// 10.2.6 Discovering a Registrar (p62)
#define SIP_MULTICAST_HOST "sip.mcast.net"
#define SIP_MULTICAST_ADDRESS "224.0.1.75"
#define DARRAY_DECLARE(name) \
struct name##s_t \
{ \
struct darray_t arr; \
}; \
\
void name##s_init(struct name##s_t* p); \
void name##s_free(struct name##s_t* p); \
int name##s_count(const struct name##s_t* p); \
int name##s_push(struct name##s_t* p, struct name##_t* item); \
struct name##_t* name##s_get(const struct name##s_t* p, int index);
#define DARRAY_IMPLEMENT(name, N) \
static inline void name##s_arrfree(struct darray_t *arr) \
{ \
int i; \
struct name##s_t* p; \
p = (struct name##s_t*)(((char*)arr) - offsetof(struct name##s_t, arr)); \
for(i = 0; i < darray_count(arr); i++) \
name##_free(name##s_get(p, i)); \
if(arr && arr->elements) \
free(arr->elements); \
} \
\
static inline void* name##s_arralloc(struct darray_t *arr, size_t size) \
{ \
return realloc(arr->elements, size);\
} \
\
void name##s_init(struct name##s_t* p) \
{ \
p->arr.free = name##s_arrfree; \
p->arr.alloc = name##s_arralloc; \
darray_init(&p->arr, sizeof(struct name##_t), N); \
} \
\
void name##s_free(struct name##s_t* p) \
{ \
darray_free(&p->arr); \
} \
\
int name##s_push(struct name##s_t* p, struct name##_t* item) \
{ \
return darray_insert(&p->arr, -1, item); \
} \
\
struct name##_t* name##s_get(const struct name##s_t* p, int index) \
{ \
return (struct name##_t*)darray_get(&((struct name##s_t*)p)->arr, index); \
} \
\
int name##s_count(const struct name##s_t* p) \
{ \
return darray_count(&p->arr); \
}
struct sip_param_t
{
struct cstring_t name;
struct cstring_t value;
};
DARRAY_DECLARE(sip_param);
struct sip_uri_t
{
struct cstring_t scheme;
struct cstring_t host; // userinfo@host:port
struct sip_params_t parameters;
struct cstring_t transport; // udp/tcp/sctp/tls/other
struct cstring_t method;
struct cstring_t maddr; // the server address to be contacted for this user, overriding any address derived from the host field
struct cstring_t user; // phone/ip
int ttl;
int lr;
int rport; // 0-not found, -1-no-value, other-value
struct sip_params_t headers;
};
DARRAY_DECLARE(sip_uri);
struct sip_requestline_t
{
struct cstring_t method;
struct sip_uri_t uri;
};
struct sip_statusline_t
{
int code;
int verminor, vermajor;
char protocol[64];
struct cstring_t reason;
};
struct sip_contact_t
{
struct sip_uri_t uri;
struct cstring_t nickname;
// parameters
struct cstring_t tag; // TO/FROM
double q; // c-p-q
int64_t expires; // delta-seconds, default 3600
struct sip_params_t params; // include tag/q/expires
};
DARRAY_DECLARE(sip_contact);
struct sip_via_t
{
struct cstring_t protocol;
struct cstring_t version;
struct cstring_t transport;
struct cstring_t host; // sent-by host:port
// parameters
struct cstring_t branch; // token
struct cstring_t maddr; // host
struct cstring_t received; // IPv4address / IPv6address
int ttl; // 0-255
int rport; // 0-not found, -1-no-value, other-value
struct sip_params_t params; // include branch/maddr/received/ttl/rport
};
DARRAY_DECLARE(sip_via);
struct sip_cseq_t
{
uint32_t id;
struct cstring_t method;
};
struct sip_substate_t
{
struct cstring_t state;
// parameters
struct cstring_t reason;
uint32_t expires; // expires
uint32_t retry; // retry-after
struct sip_params_t params; // include reason/expires/retry
};
struct sip_event_t
{
struct cstring_t event;
// parameters
struct cstring_t id;
struct sip_params_t params; // include id
};
int sip_header_param(const char* s, const char* end, struct sip_param_t* param);
int sip_header_params(char sep, const char* s, const char* end, struct sip_params_t* params);
int sip_param_write(const struct sip_param_t* param, char* data, const char* end);
int sip_params_write(const struct sip_params_t* params, char* data, const char* end, char sep);
const struct sip_param_t* sip_params_find(const struct sip_params_t* params, const char* name, int bytes);
const struct cstring_t* sip_params_find_string(const struct sip_params_t* params, const char* name, int bytes);
int sip_params_find_int(const struct sip_params_t* params, const char* name, int bytes, int* value);
int sip_params_find_int64(const struct sip_params_t* params, const char* name, int bytes, int64_t* value);
int sip_params_find_double(const struct sip_params_t* params, const char* name, int bytes, double* value);
int sip_params_add_or_update(struct sip_params_t* params, const char* name, int bytes, const struct cstring_t* value);
/// @return 0-ok, other-error
int sip_header_cseq(const char* s, const char* end, struct sip_cseq_t* cseq);
/// @return write length, >0-ok, <0-error
int sip_cseq_write(const struct sip_cseq_t* cseq, char* data, const char* end);
int sip_header_uri(const char* s, const char* end, struct sip_uri_t* uri);
int sip_uri_write(const struct sip_uri_t* uri, char* data, const char* end);
int sip_uri_equal(const struct sip_uri_t* l, const struct sip_uri_t* r);
int sip_uri_username(const struct sip_uri_t* uri, struct cstring_t* user);
int sip_request_uri_write(const struct sip_uri_t* uri, char* data, const char* end);
int sip_header_via(const char* s, const char* end, struct sip_via_t* via);
int sip_header_vias(const char* s, const char* end, struct sip_vias_t* vias);
int sip_via_write(const struct sip_via_t* via, char* data, const char* end);
const struct cstring_t* sip_vias_top_branch(const struct sip_vias_t* vias);
int sip_header_route(const char* s, const char* end, struct sip_uri_t* route);
int sip_header_routes(const char* s, const char* end, struct sip_uris_t* route);
int sip_route_write(const struct sip_uri_t* route, char* data, const char* end);
int sip_header_contact(const char* s, const char* end, struct sip_contact_t* contact);
int sip_header_contacts(const char* s, const char* end, struct sip_contacts_t* contacts);
int sip_contact_write(const struct sip_contact_t* contact, char* data, const char* end);
int sip_contacts_match_any(const struct sip_contacts_t* contacts);
char* cstring_clone(char* ptr, const char* end, struct cstring_t* clone, const char* s, size_t n);
char* sip_uri_clone(char* ptr, const char* end, struct sip_uri_t* clone, const struct sip_uri_t* uri);
char* sip_via_clone(char* ptr, const char* end, struct sip_via_t* clone, const struct sip_via_t* via);
char* sip_contact_clone(char* ptr, const char* end, struct sip_contact_t* clone, const struct sip_contact_t* contact);
void sip_uri_free(struct sip_uri_t* uri);
void sip_via_free(struct sip_via_t* via);
void sip_contact_free(struct sip_contact_t* contact);
void sip_substate_free(struct sip_substate_t* substate);
void sip_event_free(struct sip_event_t* event);
/// @return 0-ok, other-error
int sip_header_substate(const char* s, const char* end, struct sip_substate_t* substate);
/// @return write length, >0-ok, <0-error
int sip_substate_write(const struct sip_substate_t* substate, char* data, const char* end);
/// @return 0-ok, other-error
int sip_header_event(const char* s, const char* end, struct sip_event_t* evt);
/// @return write length, >0-ok, <0-error
int sip_event_write(const struct sip_event_t* evt, char* data, const char* end);
/// @return 1-true, 0-false
int sip_event_equal(const struct sip_event_t* l, const struct sip_event_t* r);
#if defined(__cplusplus)
}
#endif
#endif /* !_sip_header_h_ */