提交 658ce0ba authored 作者: Mathieu Rene's avatar Mathieu Rene

work out contexts, cleanup rtp endpoint in preparation for mg-based setup

上级 c82c11b0
...@@ -46,6 +46,97 @@ void megaco_peer_profile_release(mg_peer_profile_t *profile) ...@@ -46,6 +46,97 @@ void megaco_peer_profile_release(mg_peer_profile_t *profile)
switch_thread_rwlock_unlock(profile->rwlock); switch_thread_rwlock_unlock(profile->rwlock);
} }
mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id)
{
mg_context_t *result = NULL;
if (context_id > MG_MAX_CONTEXTS) {
return NULL;
}
switch_thread_rwlock_rdlock(profile->contexts_rwlock);
/* Context exists */
if (profile->contexts_bitmap[context_id % 8] & (1 << (context_id / 8))) {
for (result = profile->contexts[context_id % MG_CONTEXT_MODULO]; result; result = result->next) {
if (result->context_id == context_id) {
break;
}
}
}
switch_thread_rwlock_unlock(profile->contexts_rwlock);
return result;
}
/* Returns a fresh new context */
mg_context_t *megaco_choose_context(megaco_profile_t *profile)
{
mg_context_t *ctx;
switch_thread_rwlock_wrlock(profile->contexts_rwlock);
/* Try the next one */
if (profile->next_context_id >= MG_MAX_CONTEXTS) {
profile->next_context_id = 1;
}
/* Look for an available context */
for (; profile->next_context_id < MG_MAX_CONTEXTS; profile->next_context_id++) {
if ((profile->contexts_bitmap[profile->next_context_id % 8] & (1 << (profile->next_context_id / 8))) == 0) {
/* Found! */
profile->contexts_bitmap[profile->next_context_id % 8] |= 1 << (profile->next_context_id / 8);
int i = profile->next_context_id % MG_CONTEXT_MODULO;
ctx = malloc(sizeof *ctx);
ctx->context_id = profile->next_context_id;
ctx->profile = profile;
if (!profile->contexts[i]) {
profile->contexts[i] = ctx;
} else {
mg_context_t *it;
for (it = profile->contexts[i]; it && it->next; it = it->next)
;
it->next = ctx;
}
profile->next_context_id++;
break;
}
}
switch_thread_rwlock_unlock(profile->contexts_rwlock);
return ctx;
}
void megaco_release_context(mg_context_t *ctx)
{
uint32_t context_id = ctx->context_id;
megaco_profile_t *profile = ctx->profile;
int i = context_id % MG_CONTEXT_MODULO;
switch_thread_rwlock_wrlock(profile->contexts_rwlock);
if (profile->contexts[i] == ctx) {
profile->contexts[i] = ctx->next;
} else {
mg_context_t *it = profile->contexts[i]->next, *prev = profile->contexts[i];
for (; it; prev = it, it = it->next) {
if (it == ctx) {
prev->next = it->next;
break;
}
}
}
profile->contexts_bitmap[context_id % 8] &= ~(1 << (context_id / 8));
memset(ctx, 0, sizeof *ctx);
free(ctx);
switch_thread_rwlock_unlock(profile->contexts_rwlock);
}
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;
...@@ -59,9 +150,14 @@ switch_status_t megaco_profile_start(const char *profilename) ...@@ -59,9 +150,14 @@ switch_status_t megaco_profile_start(const char *profilename)
profile = switch_core_alloc(pool, sizeof(*profile)); profile = switch_core_alloc(pool, sizeof(*profile));
profile->pool = pool; profile->pool = pool;
profile->name = switch_core_strdup(pool, profilename); profile->name = switch_core_strdup(pool, profilename);
profile->next_context_id++;
switch_thread_rwlock_create(&profile->rwlock, pool); switch_thread_rwlock_create(&profile->rwlock, pool);
switch_thread_rwlock_create(&profile->contexts_rwlock, pool);
// switch_core_hash_init(&profile->contexts_hash, pool);
if (SWITCH_STATUS_SUCCESS != config_profile(profile, SWITCH_FALSE)) { if (SWITCH_STATUS_SUCCESS != config_profile(profile, SWITCH_FALSE)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error configuring profile %s\n", profile->name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error configuring profile %s\n", profile->name);
goto fail; goto fail;
...@@ -94,6 +190,8 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile) ...@@ -94,6 +190,8 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile)
if(SWITCH_STATUS_FALSE == sng_mgco_stop((*profile))) { if(SWITCH_STATUS_FALSE == sng_mgco_stop((*profile))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error stopping MEGACO Stack for profile %s\n", (*profile)->name); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error stopping MEGACO Stack for profile %s\n", (*profile)->name);
} }
/* TODO: Cleanup contexts */
switch_thread_rwlock_unlock((*profile)->rwlock); switch_thread_rwlock_unlock((*profile)->rwlock);
...@@ -104,7 +202,7 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile) ...@@ -104,7 +202,7 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile)
switch_core_destroy_memory_pool(&(*profile)->pool); switch_core_destroy_memory_pool(&(*profile)->pool);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
switch_status_t megaco_peer_profile_destroy(mg_peer_profile_t **profile) switch_status_t megaco_peer_profile_destroy(mg_peer_profile_t **profile)
......
...@@ -131,6 +131,7 @@ switch_status_t mg_config_cleanup(megaco_profile_t* profile) ...@@ -131,6 +131,7 @@ switch_status_t mg_config_cleanup(megaco_profile_t* profile)
{ {
switch_xml_config_item_t *instructions = (profile ? get_instructions(profile) : NULL); switch_xml_config_item_t *instructions = (profile ? get_instructions(profile) : NULL);
switch_xml_config_cleanup(instructions); switch_xml_config_cleanup(instructions);
free(instructions);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
...@@ -140,6 +141,7 @@ switch_status_t mg_peer_config_cleanup(mg_peer_profile_t* profile) ...@@ -140,6 +141,7 @@ switch_status_t mg_peer_config_cleanup(mg_peer_profile_t* profile)
{ {
switch_xml_config_item_t *instructions = (profile ? get_peer_instructions(profile) : NULL); switch_xml_config_item_t *instructions = (profile ? get_peer_instructions(profile) : NULL);
switch_xml_config_cleanup(instructions); switch_xml_config_cleanup(instructions);
free(instructions);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#define MG_MAX_PEERS 5 #define MG_MAX_PEERS 5
#define MG_CONTEXT_MAX_TERMS 3
#define MEGACO_CLI_SYNTAX "profile|logging" #define MEGACO_CLI_SYNTAX "profile|logging"
#define MEGACO_LOGGING_CLI_SYNTAX "logging [enable|disable]" #define MEGACO_LOGGING_CLI_SYNTAX "logging [enable|disable]"
#define MEGACO_FUNCTION_SYNTAX "profile [name] [start | stop] [status] [xmlstatus] [peerxmlstatus]" #define MEGACO_FUNCTION_SYNTAX "profile [name] [start | stop] [status] [xmlstatus] [peerxmlstatus]"
...@@ -50,10 +52,57 @@ typedef struct mg_peer_profile_s{ ...@@ -50,10 +52,57 @@ typedef struct mg_peer_profile_s{
char* mid; /* Peer H.248 MID */ char* mid; /* Peer H.248 MID */
char* transport_type; /* UDP/TCP */ char* transport_type; /* UDP/TCP */
char* encoding_type; /* Encoding TEXT/Binary */ char* encoding_type; /* Encoding TEXT/Binary */
}mg_peer_profile_t; } mg_peer_profile_t;
typedef enum {
MG_TERM_FREE = 0,
MG_TERM_TDM,
MG_TERM_RTP
} mg_termination_type_t;
typedef struct megaco_profile_s megaco_profile_t;
typedef struct mg_context_s mg_context_t;
typedef struct mg_termination_s {
mg_termination_type_t type;
const char *uuid;
mg_context_t *context;
union {
struct {
const char *codec;
int ptime;
const char *remote_address;
switch_port_t remote_port;
switch_port_t local_port;
CmSdpInfoSet *local_sdp;
CmSdpInfoSet *remote_sdp;
unsigned mode:2;
unsigned :0;
} rtp;
struct {
int span;
int channel;
} tdm;
} u;
} mg_termination_t;
struct mg_context_s {
uint32_t context_id;
mg_termination_t terminations[MG_CONTEXT_MAX_TERMS];
megaco_profile_t *profile;
mg_context_t *next;
switch_memory_pool_t *pool;
};
#define MG_CONTEXT_MODULO 16
#define MG_MAX_CONTEXTS 32768
typedef struct megaco_profile_s { struct megaco_profile_s {
char *name; char *name;
switch_memory_pool_t *pool; switch_memory_pool_t *pool;
switch_thread_rwlock_t *rwlock; /* < Reference counting rwlock */ switch_thread_rwlock_t *rwlock; /* < Reference counting rwlock */
...@@ -71,7 +120,12 @@ typedef struct megaco_profile_s { ...@@ -71,7 +120,12 @@ typedef struct megaco_profile_s {
char* rtp_termination_id_prefix; char* rtp_termination_id_prefix;
int rtp_termination_id_len; int rtp_termination_id_len;
char* peer_list[MG_MAX_PEERS]; /* MGC Peer ID LIST */ char* peer_list[MG_MAX_PEERS]; /* MGC Peer ID LIST */
} megaco_profile_t;
switch_thread_rwlock_t *contexts_rwlock;
uint32_t next_context_id;
uint8_t contexts_bitmap[MG_MAX_CONTEXTS/8]; /* Availability matrix, enough bits for a 32768 bitmap */
mg_context_t *contexts[MG_CONTEXT_MODULO];
};
megaco_profile_t *megaco_profile_locate(const char *name); megaco_profile_t *megaco_profile_locate(const char *name);
...@@ -80,6 +134,11 @@ void megaco_profile_release(megaco_profile_t *profile); ...@@ -80,6 +134,11 @@ 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);
mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id);
mg_context_t *megaco_choose_context(megaco_profile_t *profile);
void megaco_release_context(mg_context_t *ctx);
switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload); switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload);
switch_status_t sng_mgco_start(megaco_profile_t* profile); switch_status_t sng_mgco_start(megaco_profile_t* profile);
switch_status_t sng_mgco_stop(megaco_profile_t* profile); switch_status_t sng_mgco_stop(megaco_profile_t* profile);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论