Pre-fill values for rtp terms (local address + reserved rtp port). Add functions to pick rtp term ids, add a memory pool in the termination struct.
This commit is contained in:
parent
d6d1365053
commit
dd633cfbfd
|
@ -145,16 +145,40 @@ done:
|
||||||
mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const char *prefix)
|
mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const char *prefix)
|
||||||
{
|
{
|
||||||
mg_termination_type_t termtype;
|
mg_termination_type_t termtype;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
mg_termination_t *term = NULL;
|
||||||
|
char name[100];
|
||||||
|
int term_id;
|
||||||
|
|
||||||
/* Check the termination type by prefix */
|
/* Check the termination type by prefix */
|
||||||
if (strncasecmp(prefix, profile->rtp_termination_id_prefix, strlen(profile->rtp_termination_id_prefix)) == 0) {
|
if (strncasecmp(prefix, profile->rtp_termination_id_prefix, strlen(profile->rtp_termination_id_prefix)) == 0) {
|
||||||
termtype = MG_TERM_RTP;
|
termtype = MG_TERM_RTP;
|
||||||
|
term_id = mg_rtp_request_id(profile);
|
||||||
|
switch_snprintf(name, sizeof name, "%s/%d", profile->rtp_termination_id_prefix, term_id);
|
||||||
} else {
|
} else {
|
||||||
/* TODO Math: look through TDM channels */
|
/* TODO Math: look through TDM channels */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_core_new_memory_pool(&pool);
|
||||||
|
term = switch_core_alloc(pool, sizeof *term);
|
||||||
|
term->pool = pool;
|
||||||
|
term->type = termtype;
|
||||||
|
|
||||||
|
if (termtype == MG_TERM_RTP) {
|
||||||
|
/* Fill in local address and reserve an rtp port */
|
||||||
|
term->u.rtp.local_addr = profile->my_ipaddr;
|
||||||
|
term->u.rtp.local_port = switch_rtp_request_port(term->u.rtp.local_addr);
|
||||||
|
term->u.rtp.codec = megaco_codec_str(profile->default_codec);
|
||||||
|
term->u.rtp.term_id = term_id;
|
||||||
|
term->name = switch_core_strdup(term->pool, name);
|
||||||
|
} else if (termtype == MG_TERM_TDM) {
|
||||||
|
/* XXX initialize tdm-specific fields */
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_hash_insert_wrlock(profile->terminations, term->name, term, profile->terminations_rwlock);
|
||||||
|
|
||||||
|
return term;
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name)
|
mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name)
|
||||||
|
@ -177,7 +201,12 @@ void megaco_termination_destroy(mg_termination_t *term)
|
||||||
term->uuid = NULL;
|
term->uuid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (term->type == MG_TERM_RTP && term->u.rtp.local_port != 0) {
|
||||||
|
switch_rtp_release_port(term->u.rtp.local_addr, term->u.rtp.local_port);
|
||||||
|
}
|
||||||
|
|
||||||
switch_core_hash_delete_wrlock(term->profile->terminations, term->name, term->profile->terminations_rwlock);
|
switch_core_hash_delete_wrlock(term->profile->terminations, term->name, term->profile->terminations_rwlock);
|
||||||
|
switch_core_destroy_memory_pool(&term->pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_status_t megaco_context_add_termination(mg_context_t *ctx, mg_termination_t *term)
|
switch_status_t megaco_context_add_termination(mg_context_t *ctx, mg_termination_t *term)
|
||||||
|
@ -210,6 +239,8 @@ switch_status_t megaco_context_add_termination(mg_context_t *ctx, mg_termination
|
||||||
|
|
||||||
switch_ivr_uuid_bridge(ctx->terminations[0]->uuid, ctx->terminations[1]->uuid);
|
switch_ivr_uuid_bridge(ctx->terminations[0]->uuid, ctx->terminations[1]->uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -226,6 +257,8 @@ switch_status_t megaco_context_sub_termination(mg_context_t *ctx, mg_termination
|
||||||
}
|
}
|
||||||
|
|
||||||
megaco_termination_destroy(term);
|
megaco_termination_destroy(term);
|
||||||
|
|
||||||
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -343,6 +376,27 @@ void megaco_release_context(mg_context_t *ctx)
|
||||||
switch_thread_rwlock_unlock(profile->contexts_rwlock);
|
switch_thread_rwlock_unlock(profile->contexts_rwlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t mg_rtp_request_id(megaco_profile_t *profile)
|
||||||
|
{
|
||||||
|
if (profile->rtpid_next >= MG_MAX_RTPID || profile->rtpid_next == 0) {
|
||||||
|
profile->rtpid_next = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; profile->rtpid_next < MG_MAX_RTPID; profile->rtpid_next++) {
|
||||||
|
if ((profile->rtpid_bitmap[profile->rtpid_next % 8] & (1 << (profile->rtpid_next / 8))) == 0) {
|
||||||
|
profile->rtpid_bitmap[profile->rtpid_next % 8] |= 1 << (profile->rtpid_next / 8);
|
||||||
|
return profile->rtpid_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_rtp_release_id(megaco_profile_t *profile, uint32_t id)
|
||||||
|
{
|
||||||
|
profile->rtpid_bitmap[id % 8] &= ~(1 << (id / 8));
|
||||||
|
}
|
||||||
|
|
||||||
switch_status_t megaco_profile_start(const char *profilename)
|
switch_status_t megaco_profile_start(const char *profilename)
|
||||||
{
|
{
|
||||||
switch_memory_pool_t *pool;
|
switch_memory_pool_t *pool;
|
||||||
|
|
|
@ -40,6 +40,9 @@ typedef enum {
|
||||||
MEGACO_CODEC_G729,
|
MEGACO_CODEC_G729,
|
||||||
MEGACO_CODEC_G723_1,
|
MEGACO_CODEC_G723_1,
|
||||||
MEGACO_CODEC_ILBC,
|
MEGACO_CODEC_ILBC,
|
||||||
|
|
||||||
|
/* Nothing below this line */
|
||||||
|
MEGACO_CODEC_INVALID = 0xFFFFFFFF
|
||||||
} megaco_codec_t;
|
} megaco_codec_t;
|
||||||
|
|
||||||
typedef struct mg_peer_profile_s{
|
typedef struct mg_peer_profile_s{
|
||||||
|
@ -81,6 +84,7 @@ typedef struct mg_context_s mg_context_t;
|
||||||
#define kCHAN_ID "chan"
|
#define kCHAN_ID "chan"
|
||||||
|
|
||||||
typedef struct mg_termination_s {
|
typedef struct mg_termination_s {
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
mg_termination_type_t type;
|
mg_termination_type_t type;
|
||||||
const char *name; /*!< Megaco Name */
|
const char *name; /*!< Megaco Name */
|
||||||
const char *uuid; /*!< UUID of the associated FS channel, or NULL if it's not activated */
|
const char *uuid; /*!< UUID of the associated FS channel, or NULL if it's not activated */
|
||||||
|
@ -102,6 +106,7 @@ typedef struct mg_termination_s {
|
||||||
int rfc2833_pt; /*!< If the stream is using rfc2833 for dtmf events, this has to be set to its negotiated payload type */
|
int rfc2833_pt; /*!< If the stream is using rfc2833 for dtmf events, this has to be set to its negotiated payload type */
|
||||||
int rate; /*!< Sampling rate */
|
int rate; /*!< Sampling rate */
|
||||||
const char *codec; /*!< Codec to use, using the freeswitch nomenclature. This could be "PCMU" for G711.U, "PCMA" for G711.A, or "G729" for g729 */
|
const char *codec; /*!< Codec to use, using the freeswitch nomenclature. This could be "PCMU" for G711.U, "PCMA" for G711.A, or "G729" for g729 */
|
||||||
|
int term_id;
|
||||||
} rtp;
|
} rtp;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -122,6 +127,7 @@ struct mg_context_s {
|
||||||
|
|
||||||
#define MG_CONTEXT_MODULO 16
|
#define MG_CONTEXT_MODULO 16
|
||||||
#define MG_MAX_CONTEXTS 32768
|
#define MG_MAX_CONTEXTS 32768
|
||||||
|
#define MG_MAX_RTPID 32768
|
||||||
|
|
||||||
|
|
||||||
struct megaco_profile_s {
|
struct megaco_profile_s {
|
||||||
|
@ -148,10 +154,47 @@ struct megaco_profile_s {
|
||||||
uint8_t contexts_bitmap[MG_MAX_CONTEXTS/8]; /* Availability matrix, enough bits for a 32768 bitmap */
|
uint8_t contexts_bitmap[MG_MAX_CONTEXTS/8]; /* Availability matrix, enough bits for a 32768 bitmap */
|
||||||
mg_context_t *contexts[MG_CONTEXT_MODULO];
|
mg_context_t *contexts[MG_CONTEXT_MODULO];
|
||||||
|
|
||||||
|
uint8_t rtpid_bitmap[MG_MAX_CONTEXTS/8];
|
||||||
|
uint32_t rtpid_next;
|
||||||
switch_hash_t *terminations;
|
switch_hash_t *terminations;
|
||||||
switch_thread_rwlock_t *terminations_rwlock;
|
switch_thread_rwlock_t *terminations_rwlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline const char *megaco_codec_str(megaco_codec_t codec)
|
||||||
|
{
|
||||||
|
switch (codec) {
|
||||||
|
case MEGACO_CODEC_PCMU:
|
||||||
|
return "PCMU";
|
||||||
|
case MEGACO_CODEC_PCMA:
|
||||||
|
return "PCMA";
|
||||||
|
case MEGACO_CODEC_G729:
|
||||||
|
return "G729";
|
||||||
|
case MEGACO_CODEC_G723_1:
|
||||||
|
return "G723"; /* XXX double check this */
|
||||||
|
case MEGACO_CODEC_ILBC:
|
||||||
|
return "ILBC";
|
||||||
|
case MEGACO_CODEC_INVALID:
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline megaco_codec_t megaco_codec_parse(const char *codec) {
|
||||||
|
if (!strcasecmp(codec, "PCMU")) {
|
||||||
|
return MEGACO_CODEC_PCMU;
|
||||||
|
} else if (!strcasecmp(codec, "PCMA")) {
|
||||||
|
return MEGACO_CODEC_PCMA;
|
||||||
|
} else if (!strcasecmp(codec, "G729")) {
|
||||||
|
return MEGACO_CODEC_G729;
|
||||||
|
} else if (!strcasecmp(codec, "G723")) {
|
||||||
|
return MEGACO_CODEC_G723_1;
|
||||||
|
} else if (!strcasecmp(codec, "ILBC")) {
|
||||||
|
return MEGACO_CODEC_ILBC;
|
||||||
|
} else {
|
||||||
|
return MEGACO_CODEC_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
megaco_profile_t *megaco_profile_locate(const char *name);
|
megaco_profile_t *megaco_profile_locate(const char *name);
|
||||||
mg_peer_profile_t *megaco_peer_profile_locate(const char *name);
|
mg_peer_profile_t *megaco_peer_profile_locate(const char *name);
|
||||||
|
@ -160,10 +203,17 @@ void megaco_profile_release(megaco_profile_t *profile);
|
||||||
switch_status_t megaco_profile_start(const char *profilename);
|
switch_status_t megaco_profile_start(const char *profilename);
|
||||||
switch_status_t megaco_profile_destroy(megaco_profile_t **profile);
|
switch_status_t megaco_profile_destroy(megaco_profile_t **profile);
|
||||||
|
|
||||||
|
uint32_t mg_rtp_request_id(megaco_profile_t *profile);
|
||||||
|
void mg_rtp_release_id(megaco_profile_t *profile, uint32_t id);
|
||||||
|
|
||||||
mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id);
|
mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id);
|
||||||
mg_context_t *megaco_choose_context(megaco_profile_t *profile);
|
mg_context_t *megaco_choose_context(megaco_profile_t *profile);
|
||||||
void megaco_release_context(mg_context_t *ctx);
|
void megaco_release_context(mg_context_t *ctx);
|
||||||
|
|
||||||
|
mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const char *prefix);
|
||||||
|
mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name);
|
||||||
|
void megaco_termination_destroy(mg_termination_t *term);
|
||||||
|
|
||||||
megaco_profile_t* megaco_get_profile_by_suId(SuId suId);
|
megaco_profile_t* megaco_get_profile_by_suId(SuId suId);
|
||||||
mg_context_t *megaco_find_context_by_suid(SuId suId, uint32_t context_id);
|
mg_context_t *megaco_find_context_by_suid(SuId suId, uint32_t context_id);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue