add management interface and some rtp goodies
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4464 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
30a9513b5a
commit
5131ee1cae
|
@ -47,6 +47,10 @@
|
|||
#include <switch_am_config.h>
|
||||
#endif
|
||||
|
||||
#define FREESWITCH_PEN "27880"
|
||||
#define FREESWITCH_MIB ".1.3.6.1.4.1." FREESWITCH_PEN
|
||||
#define FREESWITCH_ITAD "543"
|
||||
|
||||
#include <switch_platform.h>
|
||||
#include <assert.h>
|
||||
#include <setjmp.h>
|
||||
|
|
|
@ -1405,6 +1405,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_directory_close(switch_directory_han
|
|||
*/
|
||||
SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel);
|
||||
|
||||
/*!
|
||||
\brief Execute a management operation.
|
||||
\param relative_oid the relative oid of the operation.
|
||||
\param action the action to perform.
|
||||
\param data input/output string.
|
||||
\param datalen size in bytes of data.
|
||||
\return SUCCESS on sucess.
|
||||
*/
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid,
|
||||
switch_management_action_t action,
|
||||
char *data,
|
||||
switch_size_t datalen);
|
||||
|
||||
|
||||
/*!
|
||||
\brief Set the maximum priority the process can obtain
|
||||
|
|
|
@ -76,9 +76,11 @@ struct switch_loadable_module_interface {
|
|||
/*! the table of chat interfaces the module has implmented */
|
||||
const switch_chat_interface_t *chat_interface;
|
||||
/*! the table of say interfaces the module has implmented */
|
||||
const switch_say_interface_t *say_interface;
|
||||
const switch_say_interface_t *say_interface;
|
||||
/*! the table of asr interfaces the module has implmented */
|
||||
const switch_asr_interface_t *asr_interface;
|
||||
/*! the table of management interfaces the module has implmented */
|
||||
const switch_management_interface_t *management_interface;
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -190,6 +192,12 @@ SWITCH_DECLARE(switch_chat_interface_t *) switch_loadable_module_get_chat_interf
|
|||
*/
|
||||
SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interface(char *name);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the management interface by it's registered name
|
||||
\param relative_oid the relative oid of the management interface
|
||||
\return the desired management interface
|
||||
*/
|
||||
SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(char *relative_oid);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the list of loaded codecs into an array
|
||||
|
|
|
@ -430,6 +430,15 @@ struct switch_chat_interface {
|
|||
const struct switch_chat_interface *next;
|
||||
};
|
||||
|
||||
/*! \brief Abstract interface to a management module */
|
||||
struct switch_management_interface {
|
||||
/*! the name of the interface */
|
||||
const char *relative_oid;
|
||||
/*! function to open the directory interface */
|
||||
switch_status_t (*management_function)(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen);
|
||||
const struct switch_management_interface *next;
|
||||
};
|
||||
|
||||
/*! \brief Abstract interface to a directory module */
|
||||
struct switch_directory_interface {
|
||||
/*! the name of the interface */
|
||||
|
|
|
@ -375,6 +375,13 @@ SWITCH_DECLARE(void) switch_rtp_set_private(switch_rtp_t *rtp_session, void *pri
|
|||
*/
|
||||
SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, switch_payload_t te);
|
||||
|
||||
/*!
|
||||
\brief Set the payload type for comfort noise
|
||||
\param rtp_session the RTP session to modify
|
||||
\param pt the payload type
|
||||
*/
|
||||
SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the private data from a given RTP session
|
||||
\param rtp_session the RTP session to retrieve the data from
|
||||
|
|
|
@ -187,6 +187,11 @@ typedef enum {
|
|||
SST_NAME_PHONETIC,
|
||||
} switch_say_type_t;
|
||||
|
||||
typedef enum {
|
||||
SMA_NONE,
|
||||
SMA_GET,
|
||||
SMA_SET
|
||||
} switch_management_action_t;
|
||||
|
||||
typedef enum {
|
||||
SMF_NONE = 0,
|
||||
|
@ -248,6 +253,7 @@ SWITCH_DECLARE_DATA extern switch_directories SWITCH_GLOBAL_dirs;
|
|||
#define SWITCH_TRUE 1
|
||||
#define SWITCH_FALSE 0
|
||||
#define SWITCH_CORE_QUEUE_LEN 100000
|
||||
#define SWITCH_MAX_MANAGEMENT_BUFFER_LEN 1024 * 8
|
||||
|
||||
typedef enum {
|
||||
SWITCH_CPF_SCREEN = (1 << 0),
|
||||
|
@ -289,6 +295,7 @@ typedef enum {
|
|||
SWITCH_VAD_FLAG_CNG = ( 1 << 3)
|
||||
} switch_vad_flag_t;
|
||||
|
||||
#define SWITCH_RTP_CNG_PAYLOAD 13
|
||||
|
||||
/*!
|
||||
\enum switch_rtp_flag_t
|
||||
|
@ -307,7 +314,8 @@ typedef enum {
|
|||
SWITCH_RTP_FLAG_MINI - Use mini RTP when possible
|
||||
SWITCH_RTP_FLAG_DATAWAIT - Do not return from reads unless there is data even when non blocking
|
||||
SWITCH_RTP_FLAG_BUGGY_2833 - Emulate the bug in cisco equipment to allow interop
|
||||
SWITCH_RTP_FLAG_PASS_RFC2833 - Pass 2833 (ignore it)
|
||||
SWITCH_RTP_FLAG_PASS_RFC2833 - Pass 2833 (ignore it)
|
||||
SWITCH_RTP_FLAG_AUTO_CNG - Generate outbound CNG frames when idle
|
||||
</pre>
|
||||
*/
|
||||
typedef enum {
|
||||
|
@ -324,7 +332,8 @@ typedef enum {
|
|||
SWITCH_RTP_FLAG_MINI = ( 1 << 10),
|
||||
SWITCH_RTP_FLAG_DATAWAIT = (1 << 11),
|
||||
SWITCH_RTP_FLAG_BUGGY_2833 = (1 << 12),
|
||||
SWITCH_RTP_FLAG_PASS_RFC2833 = (1 << 13)
|
||||
SWITCH_RTP_FLAG_PASS_RFC2833 = (1 << 13),
|
||||
SWITCH_RTP_FLAG_AUTO_CNG = (1 << 14)
|
||||
} switch_rtp_flag_t;
|
||||
|
||||
/*!
|
||||
|
@ -985,6 +994,7 @@ typedef struct switch_speech_interface switch_speech_interface_t;
|
|||
typedef struct switch_asr_interface switch_asr_interface_t;
|
||||
typedef struct switch_directory_interface switch_directory_interface_t;
|
||||
typedef struct switch_chat_interface switch_chat_interface_t;
|
||||
typedef struct switch_management_interface switch_management_interface_t;
|
||||
typedef struct switch_core_port_allocator switch_core_port_allocator_t;
|
||||
typedef struct switch_media_bug switch_media_bug_t;
|
||||
typedef void (*switch_media_bug_callback_t)(switch_media_bug_t *, void *, switch_abc_type_t);
|
||||
|
|
|
@ -753,6 +753,8 @@ static int activate_rtp(struct private_object *tech_pvt)
|
|||
flags |= SWITCH_RTP_FLAG_USE_TIMER;
|
||||
}
|
||||
|
||||
flags |= SWITCH_RTP_FLAG_AUTO_CNG;
|
||||
|
||||
if (!(tech_pvt->rtp_session = switch_rtp_new(tech_pvt->profile->ip,
|
||||
tech_pvt->local_port,
|
||||
tech_pvt->remote_ip,
|
||||
|
@ -1357,7 +1359,7 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc
|
|||
|
||||
samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
|
||||
tech_pvt->timestamp_send += samples;
|
||||
if (switch_rtp_write_frame(tech_pvt->rtp_session, frame, tech_pvt->timestamp_send) < 0) {
|
||||
if (switch_rtp_write_frame(tech_pvt->rtp_session, frame, 0) < 0) {
|
||||
terminate_session(&session, __LINE__, SWITCH_CAUSE_NORMAL_CLEARING);
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
|
|
@ -252,6 +252,7 @@ struct sofia_profile {
|
|||
su_root_t *s_root;
|
||||
sip_alias_node_t *aliases;
|
||||
switch_payload_t te;
|
||||
switch_payload_t cng_pt;
|
||||
uint32_t codec_flags;
|
||||
switch_mutex_t *ireg_mutex;
|
||||
switch_mutex_t *oreg_mutex;
|
||||
|
@ -319,6 +320,8 @@ struct private_object {
|
|||
switch_mutex_t *flag_mutex;
|
||||
switch_payload_t te;
|
||||
switch_payload_t bte;
|
||||
switch_payload_t cng_pt;
|
||||
switch_payload_t bcng_pt;
|
||||
nua_handle_t *nh;
|
||||
nua_handle_t *nh2;
|
||||
su_home_t *home;
|
||||
|
@ -747,6 +750,14 @@ static void set_local_sdp(private_object_t *tech_pvt, char *ip, uint32_t port, c
|
|||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %d", tech_pvt->te);
|
||||
}
|
||||
|
||||
if (tech_pvt->read_codec.implementation->samples_per_second == 8000) {
|
||||
tech_pvt->cng_pt = SWITCH_RTP_CNG_PAYLOAD;
|
||||
}
|
||||
|
||||
if (tech_pvt->cng_pt) {
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " %d", tech_pvt->cng_pt);
|
||||
}
|
||||
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "\n");
|
||||
|
||||
if (tech_pvt->rm_encoding) {
|
||||
|
@ -776,6 +787,8 @@ static void set_local_sdp(private_object_t *tech_pvt, char *ip, uint32_t port, c
|
|||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d telephone-event/8000\na=fmtp:%d 0-16\n", tech_pvt->te, tech_pvt->te);
|
||||
}
|
||||
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=rtpmap:%d CN/%d\n", tech_pvt->cng_pt, tech_pvt->read_codec.implementation->samples_per_second);
|
||||
|
||||
if (ptime) {
|
||||
snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=ptime:%d\n", ptime);
|
||||
}
|
||||
|
@ -870,9 +883,16 @@ static void attach_private(switch_core_session_t *session,
|
|||
} else {
|
||||
tech_pvt->te = profile->te;
|
||||
}
|
||||
|
||||
if (tech_pvt->bcng_pt) {
|
||||
tech_pvt->cng_pt = tech_pvt->bcng_pt;
|
||||
} else {
|
||||
tech_pvt->cng_pt = profile->cng_pt;
|
||||
}
|
||||
|
||||
tech_pvt->session = session;
|
||||
tech_pvt->home = su_home_new(sizeof(*tech_pvt->home));
|
||||
|
||||
|
||||
switch_core_session_set_private(session, tech_pvt);
|
||||
|
||||
|
||||
|
@ -1543,6 +1563,10 @@ static switch_status_t activate_rtp(private_object_t *tech_pvt)
|
|||
flags |= SWITCH_RTP_FLAG_PASS_RFC2833;
|
||||
}
|
||||
|
||||
if (tech_pvt->cng_pt) {
|
||||
flags |= SWITCH_RTP_FLAG_AUTO_CNG;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
|
||||
switch_channel_get_name(channel),
|
||||
tech_pvt->local_sdp_audio_ip,
|
||||
|
@ -1602,6 +1626,12 @@ static switch_status_t activate_rtp(private_object_t *tech_pvt)
|
|||
switch_channel_get_name(switch_core_session_get_channel(tech_pvt->session)),
|
||||
vad_in ? "in" : "", vad_out ? "out" : "");
|
||||
}
|
||||
|
||||
switch_rtp_set_telephony_event(tech_pvt->rtp_session, tech_pvt->te);
|
||||
if (tech_pvt->cng_pt) {
|
||||
switch_rtp_set_cng_pt(tech_pvt->rtp_session, tech_pvt->cng_pt);
|
||||
}
|
||||
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RTP REPORTS ERROR: [%s]\n", err);
|
||||
terminate_session(&tech_pvt->session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
|
||||
|
@ -1881,7 +1911,8 @@ static switch_status_t sofia_write_frame(switch_core_session_t *session, switch_
|
|||
#endif
|
||||
|
||||
tech_pvt->timestamp_send += samples;
|
||||
switch_rtp_write_frame(tech_pvt->rtp_session, frame, tech_pvt->timestamp_send);
|
||||
//switch_rtp_write_frame(tech_pvt->rtp_session, frame, tech_pvt->timestamp_send);
|
||||
switch_rtp_write_frame(tech_pvt->rtp_session, frame, 0);
|
||||
|
||||
switch_clear_flag_locked(tech_pvt, TFLAG_WRITING);
|
||||
return status;
|
||||
|
@ -2347,6 +2378,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
|
|||
ctech_pvt = switch_core_session_get_private(session);
|
||||
assert(ctech_pvt != NULL);
|
||||
tech_pvt->bte = ctech_pvt->te;
|
||||
tech_pvt->bcng_pt = ctech_pvt->cng_pt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5181,6 +5213,8 @@ static switch_status_t config_sofia(int reload)
|
|||
switch_set_flag(profile, TFLAG_LATE_NEGOTIATION);
|
||||
} else if (!strcasecmp(var, "rfc2833-pt")) {
|
||||
profile->te = (switch_payload_t) atoi(val);
|
||||
} else if (!strcasecmp(var, "cng-pt")) {
|
||||
profile->cng_pt = (switch_payload_t) atoi(val);
|
||||
} else if (!strcasecmp(var, "sip-port")) {
|
||||
profile->sip_port = atoi(val);
|
||||
} else if (!strcasecmp(var, "vad")) {
|
||||
|
@ -5270,6 +5304,10 @@ static switch_status_t config_sofia(int reload)
|
|||
}
|
||||
}
|
||||
|
||||
if (!profile->cng_pt) {
|
||||
profile->cng_pt = 127;
|
||||
}
|
||||
|
||||
if (!profile->sipip) {
|
||||
profile->sipip = switch_core_strdup(profile->pool, globals.guess_ip);
|
||||
}
|
||||
|
|
|
@ -197,13 +197,13 @@ abyss_bool HandleHook(TSession *r)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
#define CMDLEN 1024 * 256
|
||||
|
||||
static xmlrpc_value *freeswitch_api(xmlrpc_env *const envP, xmlrpc_value *const paramArrayP, void *const userData)
|
||||
{
|
||||
char *command, *arg;
|
||||
char *retbuf = malloc(CMDLEN);
|
||||
switch_stream_handle_t stream = {0};
|
||||
xmlrpc_value *val;
|
||||
xmlrpc_value *val = NULL;
|
||||
|
||||
|
||||
/* Parse our argument array. */
|
||||
xmlrpc_decompose_value(envP, paramArrayP, "(ss)", &command, &arg);
|
||||
|
@ -211,16 +211,67 @@ static xmlrpc_value *freeswitch_api(xmlrpc_env *const envP, xmlrpc_value *const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
memset(retbuf, 0, CMDLEN);
|
||||
stream.data = retbuf;
|
||||
stream.end = stream.data;
|
||||
stream.data_size = CMDLEN;
|
||||
stream.write_function = switch_console_stream_write;
|
||||
switch_api_execute(command, arg, NULL, &stream);
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
if (switch_api_execute(command, arg, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
|
||||
/* Return our result. */
|
||||
val = xmlrpc_build_value(envP, "s", stream.data);
|
||||
free(stream.data);
|
||||
} else {
|
||||
val = xmlrpc_build_value(envP, "s", "ERROR!");
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static xmlrpc_value *freeswitch_man(xmlrpc_env *const envP, xmlrpc_value *const paramArrayP, void *const userData)
|
||||
{
|
||||
char *oid, *relative_oid, *s_action, *data;
|
||||
char buf[SWITCH_MAX_MANAGEMENT_BUFFER_LEN] = "";
|
||||
switch_management_action_t action = SMA_NONE;
|
||||
switch_stream_handle_t stream = {0};
|
||||
xmlrpc_value *val;
|
||||
|
||||
/* Parse our argument array. */
|
||||
xmlrpc_decompose_value(envP, paramArrayP, "(sss)", &oid, &s_action, &data);
|
||||
if (envP->fault_occurred) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!strncasecmp(oid, FREESWITCH_MIB, strlen(FREESWITCH_MIB))) {
|
||||
relative_oid = oid + strlen(FREESWITCH_MIB);
|
||||
} else {
|
||||
relative_oid = oid;
|
||||
}
|
||||
|
||||
if (!switch_strlen_zero(data)) {
|
||||
switch_copy_string(buf, data, sizeof(buf));
|
||||
}
|
||||
|
||||
if (!strcasecmp(s_action, "get")) {
|
||||
action = SMA_GET;
|
||||
} else if (!strcasecmp(s_action, "set")) {
|
||||
action = SMA_SET;
|
||||
}
|
||||
|
||||
if (action) {
|
||||
if (switch_core_management_exec(relative_oid, action, buf, sizeof(buf)) == SWITCH_STATUS_SUCCESS) {
|
||||
if (action == SMA_SET) {
|
||||
if (switch_strlen_zero(buf)) {
|
||||
snprintf(buf, sizeof(buf), "OK\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (switch_strlen_zero(buf)) {
|
||||
snprintf(buf, sizeof(buf), "ERROR\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "Invalid Action %s\n", s_action);
|
||||
}
|
||||
|
||||
/* Return our result. */
|
||||
val = xmlrpc_build_value(envP, "s", retbuf);
|
||||
free(retbuf);
|
||||
val = xmlrpc_build_value(envP, "s", buf);
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -240,6 +291,8 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void)
|
|||
|
||||
xmlrpc_registry_add_method(&env, registryP, NULL, "freeswitch.api", &freeswitch_api, NULL);
|
||||
xmlrpc_registry_add_method(&env, registryP, NULL,"freeswitch_api", &freeswitch_api, NULL);
|
||||
xmlrpc_registry_add_method(&env, registryP, NULL, "freeswitch.management", &freeswitch_man, NULL);
|
||||
xmlrpc_registry_add_method(&env, registryP, NULL,"freeswitch_management", &freeswitch_man, NULL);
|
||||
|
||||
MIMETypeInit();
|
||||
MIMETypeAdd("text/html", "html");
|
||||
|
|
|
@ -447,6 +447,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_port_allocator_new(switch_port_t sta
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_core_management_exec(char *relative_oid,
|
||||
switch_management_action_t action,
|
||||
char *data,
|
||||
switch_size_t datalen)
|
||||
{
|
||||
const switch_management_interface_t *ptr;
|
||||
switch_status_t status = SWITCH_STATUS_FALSE;
|
||||
|
||||
if ((ptr = switch_loadable_module_get_management_interface(relative_oid))) {
|
||||
status = ptr->management_function(relative_oid, action, data, datalen);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
SWITCH_DECLARE(switch_port_t) switch_core_port_allocator_request_port(switch_core_port_allocator_t *alloc)
|
||||
{
|
||||
switch_port_t port;
|
||||
|
|
|
@ -55,6 +55,7 @@ struct switch_loadable_module_container {
|
|||
switch_hash_t *directory_hash;
|
||||
switch_hash_t *chat_hash;
|
||||
switch_hash_t *say_hash;
|
||||
switch_hash_t *management_hash;
|
||||
switch_memory_pool_t *pool;
|
||||
};
|
||||
|
||||
|
@ -332,6 +333,24 @@ static switch_status_t switch_loadable_module_process(char *key, switch_loadable
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new_module->module_interface->management_interface) {
|
||||
const switch_management_interface_t *ptr;
|
||||
|
||||
for (ptr = new_module->module_interface->management_interface; ptr; ptr = ptr->next) {
|
||||
if (!ptr->relative_oid) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to load management interface from %s due to no interface name.\n", key);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Management interface '%s'\n", ptr->relative_oid);
|
||||
if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "management");
|
||||
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->relative_oid);
|
||||
switch_event_fire(&event);
|
||||
}
|
||||
switch_core_hash_insert(loadable_modules.management_hash, ptr->relative_oid, (const void *) ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
@ -585,6 +604,7 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_init()
|
|||
switch_core_hash_init(&loadable_modules.directory_hash, loadable_modules.pool);
|
||||
switch_core_hash_init(&loadable_modules.chat_hash, loadable_modules.pool);
|
||||
switch_core_hash_init(&loadable_modules.say_hash, loadable_modules.pool);
|
||||
switch_core_hash_init(&loadable_modules.management_hash, loadable_modules.pool);
|
||||
switch_core_hash_init(&loadable_modules.dialplan_hash, loadable_modules.pool);
|
||||
|
||||
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||
|
@ -767,6 +787,11 @@ SWITCH_DECLARE(switch_say_interface_t *) switch_loadable_module_get_say_interfac
|
|||
return switch_core_hash_find(loadable_modules.say_hash, name);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_management_interface_t *) switch_loadable_module_get_management_interface(char *relative_oid)
|
||||
{
|
||||
return switch_core_hash_find(loadable_modules.management_hash, relative_oid);
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(int) switch_loadable_module_get_codecs(switch_memory_pool_t *pool, const switch_codec_implementation_t **array,
|
||||
int arraylen)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#define rtp_header_len 12
|
||||
#define RTP_START_PORT 16384
|
||||
#define RTP_END_PORT 32768
|
||||
#define SWITCH_RTP_CNG_PAYLOAD 13
|
||||
#define MAX_KEY_LEN 64
|
||||
#define MASTER_KEY_LEN 30
|
||||
#define RTP_MAGIC_NUMBER 42
|
||||
|
@ -131,11 +130,10 @@ struct switch_rtp {
|
|||
uint16_t rseq;
|
||||
switch_payload_t payload;
|
||||
switch_payload_t rpayload;
|
||||
|
||||
switch_rtp_invalid_handler_t invalid_handler;
|
||||
void *private_data;
|
||||
|
||||
uint32_t ts;
|
||||
uint32_t auto_write_ts;
|
||||
uint32_t last_write_ts;
|
||||
uint16_t last_write_seq;
|
||||
uint32_t last_write_ssrc;
|
||||
|
@ -157,6 +155,7 @@ struct switch_rtp {
|
|||
struct switch_rtp_vad_data vad_data;
|
||||
struct switch_rtp_rfc2833_data dtmf_data;
|
||||
switch_payload_t te;
|
||||
switch_payload_t cng_pt;
|
||||
switch_mutex_t *flag_mutex;
|
||||
switch_timer_t timer;
|
||||
uint8_t ready;
|
||||
|
@ -164,6 +163,7 @@ struct switch_rtp {
|
|||
};
|
||||
|
||||
static int global_init = 0;
|
||||
static int rtp_common_write(switch_rtp_t *rtp_session, void *data, uint32_t datalen, uint8_t m, switch_payload_t payload, switch_frame_flag_t *flags);
|
||||
|
||||
static switch_status_t ice_out(switch_rtp_t *rtp_session)
|
||||
{
|
||||
|
@ -536,6 +536,13 @@ SWITCH_DECLARE(void) switch_rtp_set_telephony_event(switch_rtp_t *rtp_session, s
|
|||
}
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(void) switch_rtp_set_cng_pt(switch_rtp_t *rtp_session, switch_payload_t pt)
|
||||
{
|
||||
|
||||
rtp_session->cng_pt = pt;
|
||||
|
||||
}
|
||||
|
||||
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin)
|
||||
{
|
||||
char ice_user[80];
|
||||
|
@ -773,15 +780,16 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
switch_core_timer_step(&rtp_session->timer);
|
||||
}
|
||||
|
||||
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BREAK)) {
|
||||
if (!bytes && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_BREAK)) {
|
||||
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_BREAK);
|
||||
|
||||
memset(&rtp_session->recv_msg, 0, SWITCH_RTP_CNG_PAYLOAD);
|
||||
memset(&rtp_session->recv_msg.body, 0, 2);
|
||||
rtp_session->recv_msg.body[0] = 127;
|
||||
rtp_session->recv_msg.header.pt = SWITCH_RTP_CNG_PAYLOAD;
|
||||
*flags |= SFF_CNG;
|
||||
/* Return a CNG frame */
|
||||
*payload_type = SWITCH_RTP_CNG_PAYLOAD;
|
||||
return SWITCH_RTP_CNG_PAYLOAD + rtp_header_len;
|
||||
return 2 + rtp_header_len;
|
||||
}
|
||||
|
||||
if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) {
|
||||
|
@ -807,8 +815,25 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
|
|||
|
||||
if (rtp_session->timer.interval) {
|
||||
check = (uint8_t)(switch_core_timer_check(&rtp_session->timer) == SWITCH_STATUS_SUCCESS);
|
||||
|
||||
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTO_CNG) &&
|
||||
rtp_session->timer.samplecount >= (rtp_session->auto_write_ts + (rtp_session->packet_size * 5))) {
|
||||
uint8_t data[2] = {0};
|
||||
switch_frame_flag_t flags = SFF_NONE;
|
||||
data[0] = 127;
|
||||
|
||||
rtp_session->auto_write_ts = rtp_session->timer.samplecount;
|
||||
rtp_session->seq = ntohs(rtp_session->seq) + 1;
|
||||
rtp_session->seq = htons(rtp_session->seq);
|
||||
rtp_session->send_msg.header.seq = rtp_session->seq;
|
||||
rtp_session->send_msg.header.ts = htonl(rtp_session->auto_write_ts);
|
||||
|
||||
rtp_common_write(rtp_session, (void *) data, sizeof(data), 0, rtp_session->cng_pt, &flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (check) {
|
||||
do_2833(rtp_session);
|
||||
|
||||
|
@ -1047,6 +1072,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
|
|||
frame->packetlen = bytes;
|
||||
frame->source = __FILE__;
|
||||
frame->flags |= SFF_RAW_RTP;
|
||||
frame->timestamp = ntohl(rtp_session->recv_msg.header.ts);
|
||||
|
||||
if (bytes < 0) {
|
||||
frame->datalen = 0;
|
||||
|
@ -1309,7 +1335,11 @@ SWITCH_DECLARE(int) switch_rtp_write(switch_rtp_t *rtp_session, void *data, uint
|
|||
return -1;
|
||||
}
|
||||
|
||||
rtp_session->ts = ts;
|
||||
if (!ts && rtp_session->timer.timer_interface) {
|
||||
rtp_session->auto_write_ts = rtp_session->ts = rtp_session->timer.samplecount;
|
||||
} else {
|
||||
rtp_session->ts = ts;
|
||||
}
|
||||
|
||||
if (rtp_session->ts > rtp_session->last_write_ts + rtp_session->packet_size || rtp_session->ts == rtp_session->packet_size) {
|
||||
mark++;
|
||||
|
@ -1345,6 +1375,8 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
|
|||
|
||||
if (frame->timestamp) {
|
||||
rtp_session->ts = (uint32_t) frame->timestamp;
|
||||
} else if (!ts && rtp_session->timer.timer_interface) {
|
||||
rtp_session->auto_write_ts = rtp_session->ts = rtp_session->timer.samplecount;
|
||||
} else {
|
||||
rtp_session->ts = ts;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue