Misc (re #1630): Fixing warnings about variable set but not used with recent gcc
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@4728 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
4bf06e69fa
commit
241474d94d
|
@ -45,13 +45,13 @@ struct cli_console_fe
|
|||
pj_cli_sess *sess;
|
||||
pj_thread_t *input_thread;
|
||||
pj_bool_t thread_quit;
|
||||
pj_sem_t *thread_sem;
|
||||
pj_cli_console_cfg cfg;
|
||||
pj_sem_t *thread_sem;
|
||||
pj_cli_console_cfg cfg;
|
||||
|
||||
struct async_input_t
|
||||
{
|
||||
{
|
||||
char *buf;
|
||||
unsigned maxlen;
|
||||
unsigned maxlen;
|
||||
pj_sem_t *sem;
|
||||
} input;
|
||||
};
|
||||
|
@ -126,7 +126,7 @@ PJ_DEF(pj_status_t) pj_cli_console_create(pj_cli_t *cli,
|
|||
NULL);
|
||||
if (!pool)
|
||||
return PJ_ENOMEM;
|
||||
|
||||
|
||||
sess = PJ_POOL_ZALLOC_T(pool, pj_cli_sess);
|
||||
fe = PJ_POOL_ZALLOC_T(pool, struct cli_console_fe);
|
||||
|
||||
|
@ -135,7 +135,7 @@ PJ_DEF(pj_status_t) pj_cli_console_create(pj_cli_t *cli,
|
|||
param = &cfg;
|
||||
}
|
||||
sess->fe = &fe->base;
|
||||
sess->log_level = param->log_level;
|
||||
sess->log_level = param->log_level;
|
||||
sess->op = PJ_POOL_ZALLOC_T(pool, struct pj_cli_sess_op);
|
||||
fe->base.op = PJ_POOL_ZALLOC_T(pool, struct pj_cli_front_end_op);
|
||||
fe->base.cli = cli;
|
||||
|
@ -154,16 +154,16 @@ PJ_DEF(pj_status_t) pj_cli_console_create(pj_cli_t *cli,
|
|||
return status;
|
||||
|
||||
pj_cli_register_front_end(cli, &fe->base);
|
||||
if (param->prompt_str.slen == 0) {
|
||||
if (param->prompt_str.slen == 0) {
|
||||
pj_str_t prompt_sign = pj_str(">>> ");
|
||||
fe->cfg.prompt_str.ptr = pj_pool_alloc(fe->pool, prompt_sign.slen+1);
|
||||
pj_strcpy(&fe->cfg.prompt_str, &prompt_sign);
|
||||
pj_strcpy(&fe->cfg.prompt_str, &prompt_sign);
|
||||
} else {
|
||||
fe->cfg.prompt_str.ptr = pj_pool_alloc(fe->pool,
|
||||
fe->cfg.prompt_str.ptr = pj_pool_alloc(fe->pool,
|
||||
param->prompt_str.slen+1);
|
||||
pj_strcpy(&fe->cfg.prompt_str, ¶m->prompt_str);
|
||||
}
|
||||
fe->cfg.prompt_str.ptr[fe->cfg.prompt_str.slen] = 0;
|
||||
}
|
||||
fe->cfg.prompt_str.ptr[fe->cfg.prompt_str.slen] = 0;
|
||||
|
||||
if (param->quit_command.slen)
|
||||
pj_strdup(fe->pool, &fe->cfg.quit_command, ¶m->quit_command);
|
||||
|
@ -183,15 +183,15 @@ static void send_prompt_str(pj_cli_sess *sess)
|
|||
|
||||
send_data.ptr = data_str;
|
||||
send_data.slen = 0;
|
||||
|
||||
|
||||
pj_strcat(&send_data, &fe->cfg.prompt_str);
|
||||
send_data.ptr[send_data.slen] = 0;
|
||||
|
||||
printf("%s", send_data.ptr);
|
||||
}
|
||||
|
||||
static void send_err_arg(pj_cli_sess *sess,
|
||||
const pj_cli_exec_info *info,
|
||||
static void send_err_arg(pj_cli_sess *sess,
|
||||
const pj_cli_exec_info *info,
|
||||
const pj_str_t *msg,
|
||||
pj_bool_t with_return)
|
||||
{
|
||||
|
@ -218,10 +218,10 @@ static void send_err_arg(pj_cli_sess *sess,
|
|||
pj_strcat(&send_data, &fe->cfg.prompt_str);
|
||||
|
||||
send_data.ptr[send_data.slen] = 0;
|
||||
printf("%s", send_data.ptr);
|
||||
printf("%s", send_data.ptr);
|
||||
}
|
||||
|
||||
static void send_inv_arg(pj_cli_sess *sess,
|
||||
static void send_inv_arg(pj_cli_sess *sess,
|
||||
const pj_cli_exec_info *info,
|
||||
pj_bool_t with_return)
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ static void send_inv_arg(pj_cli_sess *sess,
|
|||
send_err_arg(sess, info, &ERR_MSG, with_return);
|
||||
}
|
||||
|
||||
static void send_too_many_arg(pj_cli_sess *sess,
|
||||
static void send_too_many_arg(pj_cli_sess *sess,
|
||||
const pj_cli_exec_info *info,
|
||||
pj_bool_t with_return)
|
||||
{
|
||||
|
@ -237,7 +237,7 @@ static void send_too_many_arg(pj_cli_sess *sess,
|
|||
send_err_arg(sess, info, &ERR_MSG, with_return);
|
||||
}
|
||||
|
||||
static void send_hint_arg(pj_str_t *send_data,
|
||||
static void send_hint_arg(pj_str_t *send_data,
|
||||
const pj_str_t *desc,
|
||||
pj_ssize_t cmd_len,
|
||||
pj_ssize_t max_len)
|
||||
|
@ -256,7 +256,7 @@ static void send_hint_arg(pj_str_t *send_data,
|
|||
}
|
||||
}
|
||||
|
||||
static void send_ambi_arg(pj_cli_sess *sess,
|
||||
static void send_ambi_arg(pj_cli_sess *sess,
|
||||
const pj_cli_exec_info *info,
|
||||
pj_bool_t with_return)
|
||||
{
|
||||
|
@ -269,12 +269,11 @@ static void send_ambi_arg(pj_cli_sess *sess,
|
|||
out_parse_state parse_state = OP_NORMAL;
|
||||
pj_ssize_t max_length = 0;
|
||||
pj_ssize_t cmd_length = 0;
|
||||
const pj_str_t *cmd_desc = 0;
|
||||
static const pj_str_t sc_type = {"sc", 2};
|
||||
static const pj_str_t choice_type = {"choice", 6};
|
||||
send_data.ptr = data;
|
||||
send_data.slen = 0;
|
||||
|
||||
|
||||
if (with_return)
|
||||
pj_strcat2(&send_data, "\r\n");
|
||||
|
||||
|
@ -283,20 +282,20 @@ static void send_ambi_arg(pj_cli_sess *sess,
|
|||
for (i=0;i<len;++i) {
|
||||
pj_strcat2(&send_data, " ");
|
||||
}
|
||||
pj_strcat2(&send_data, "^");
|
||||
pj_strcat2(&send_data, "^");
|
||||
/* Get the max length of the command name */
|
||||
for (i=0;i<info->hint_cnt;++i) {
|
||||
if ((&hint[i].type) && (hint[i].type.slen > 0)) {
|
||||
if (pj_stricmp(&hint[i].type, &sc_type) == 0) {
|
||||
if ((&hint[i].type) && (hint[i].type.slen > 0)) {
|
||||
if (pj_stricmp(&hint[i].type, &sc_type) == 0) {
|
||||
if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) {
|
||||
cmd_length += (hint[i].name.slen + 3);
|
||||
} else {
|
||||
cmd_length = hint[i].name.slen;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cmd_length = hint[i].name.slen;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
cmd_length = hint[i].name.slen;
|
||||
}
|
||||
|
||||
|
@ -307,7 +306,7 @@ static void send_ambi_arg(pj_cli_sess *sess,
|
|||
|
||||
cmd_length = 0;
|
||||
for (i=0;i<info->hint_cnt;++i) {
|
||||
if ((&hint[i].type) && (hint[i].type.slen > 0)) {
|
||||
if ((&hint[i].type) && (hint[i].type.slen > 0)) {
|
||||
if (pj_stricmp(&hint[i].type, &sc_type) == 0) {
|
||||
parse_state = OP_SHORTCUT;
|
||||
} else if (pj_stricmp(&hint[i].type, &choice_type) == 0) {
|
||||
|
@ -315,7 +314,7 @@ static void send_ambi_arg(pj_cli_sess *sess,
|
|||
} else {
|
||||
parse_state = OP_TYPE;
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
parse_state = OP_NORMAL;
|
||||
}
|
||||
|
||||
|
@ -323,58 +322,57 @@ static void send_ambi_arg(pj_cli_sess *sess,
|
|||
pj_strcat2(&send_data, "\r\n ");
|
||||
cmd_length = hint[i].name.slen;
|
||||
}
|
||||
|
||||
|
||||
switch (parse_state) {
|
||||
case OP_CHOICE:
|
||||
pj_strcat2(&send_data, "[");
|
||||
pj_strcat(&send_data, &hint[i].name);
|
||||
pj_strcat2(&send_data, "]");
|
||||
pj_strcat2(&send_data, "]");
|
||||
break;
|
||||
case OP_TYPE:
|
||||
pj_strcat2(&send_data, "<");
|
||||
pj_strcat(&send_data, &hint[i].type);
|
||||
pj_strcat2(&send_data, ">");
|
||||
pj_strcat2(&send_data, ">");
|
||||
break;
|
||||
case OP_SHORTCUT:
|
||||
/* Format : "Command | sc | description" */
|
||||
{
|
||||
{
|
||||
cmd_length += hint[i].name.slen;
|
||||
if ((i > 0) && (!pj_stricmp(&hint[i-1].desc, &hint[i].desc))) {
|
||||
pj_strcat2(&send_data, " | ");
|
||||
cmd_length += 3;
|
||||
cmd_length += 3;
|
||||
} else {
|
||||
pj_strcat2(&send_data, "\r\n ");
|
||||
}
|
||||
pj_strcat(&send_data, &hint[i].name);
|
||||
pj_strcat(&send_data, &hint[i].name);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pj_strcat(&send_data, &hint[i].name);
|
||||
cmd_desc = &hint[i].desc;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((parse_state == OP_TYPE) || (parse_state == OP_CHOICE) ||
|
||||
|
||||
if ((parse_state == OP_TYPE) || (parse_state == OP_CHOICE) ||
|
||||
((i+1) >= info->hint_cnt) ||
|
||||
(pj_strncmp(&hint[i].desc, &hint[i+1].desc, hint[i].desc.slen)))
|
||||
(pj_strncmp(&hint[i].desc, &hint[i+1].desc, hint[i].desc.slen)))
|
||||
{
|
||||
/* Add description info */
|
||||
send_hint_arg(&send_data, &hint[i].desc, cmd_length, max_length);
|
||||
|
||||
cmd_length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
pj_strcat2(&send_data, "\r\n");
|
||||
pj_strcat(&send_data, &fe->cfg.prompt_str);
|
||||
send_data.ptr[send_data.slen] = 0;
|
||||
printf("%s", send_data.ptr);
|
||||
printf("%s", send_data.ptr);
|
||||
}
|
||||
|
||||
static pj_bool_t handle_hint(pj_cli_sess *sess)
|
||||
{
|
||||
pj_status_t status;
|
||||
pj_bool_t retval = PJ_TRUE;
|
||||
|
||||
|
||||
pj_pool_t *pool;
|
||||
pj_cli_cmd_val *cmd_val;
|
||||
pj_cli_exec_info info;
|
||||
|
@ -387,13 +385,13 @@ static pj_bool_t handle_hint(pj_cli_sess *sess)
|
|||
NULL);
|
||||
|
||||
cmd_val = PJ_POOL_ZALLOC_T(pool, pj_cli_cmd_val);
|
||||
|
||||
status = pj_cli_sess_parse(sess, recv_buf, cmd_val,
|
||||
|
||||
status = pj_cli_sess_parse(sess, recv_buf, cmd_val,
|
||||
pool, &info);
|
||||
|
||||
switch (status) {
|
||||
case PJ_CLI_EINVARG:
|
||||
send_inv_arg(sess, &info, PJ_TRUE);
|
||||
send_inv_arg(sess, &info, PJ_TRUE);
|
||||
break;
|
||||
case PJ_CLI_ETOOMANYARGS:
|
||||
send_too_many_arg(sess, &info, PJ_TRUE);
|
||||
|
@ -402,43 +400,43 @@ static pj_bool_t handle_hint(pj_cli_sess *sess)
|
|||
case PJ_CLI_EAMBIGUOUS:
|
||||
send_ambi_arg(sess, &info, PJ_TRUE);
|
||||
break;
|
||||
case PJ_SUCCESS:
|
||||
if (info.hint_cnt > 0) {
|
||||
/* Compelete command */
|
||||
send_ambi_arg(sess, &info, PJ_TRUE);
|
||||
case PJ_SUCCESS:
|
||||
if (info.hint_cnt > 0) {
|
||||
/* Compelete command */
|
||||
send_ambi_arg(sess, &info, PJ_TRUE);
|
||||
} else {
|
||||
retval = PJ_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pj_pool_release(pool);
|
||||
return retval;
|
||||
pj_pool_release(pool);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static pj_bool_t handle_exec(pj_cli_sess *sess)
|
||||
{
|
||||
pj_status_t status;
|
||||
pj_bool_t retval = PJ_TRUE;
|
||||
|
||||
pj_pool_t *pool;
|
||||
|
||||
pj_pool_t *pool;
|
||||
pj_cli_exec_info info;
|
||||
pj_cli_t *cli = sess->fe->cli;
|
||||
struct cli_console_fe *fe = (struct cli_console_fe *)sess->fe;
|
||||
char *recv_buf = fe->input.buf;
|
||||
|
||||
|
||||
printf("\r\n");
|
||||
|
||||
pool = pj_pool_create(pj_cli_get_param(cli)->pf, "handle_exec",
|
||||
PJ_CLI_CONSOLE_POOL_SIZE, PJ_CLI_CONSOLE_POOL_INC,
|
||||
NULL);
|
||||
|
||||
status = pj_cli_sess_exec(sess, recv_buf,
|
||||
NULL);
|
||||
|
||||
status = pj_cli_sess_exec(sess, recv_buf,
|
||||
pool, &info);
|
||||
|
||||
switch (status) {
|
||||
case PJ_CLI_EINVARG:
|
||||
send_inv_arg(sess, &info, PJ_FALSE);
|
||||
send_inv_arg(sess, &info, PJ_FALSE);
|
||||
break;
|
||||
case PJ_CLI_ETOOMANYARGS:
|
||||
send_too_many_arg(sess, &info, PJ_FALSE);
|
||||
|
@ -451,16 +449,16 @@ static pj_bool_t handle_exec(pj_cli_sess *sess)
|
|||
retval = PJ_FALSE;
|
||||
break;
|
||||
case PJ_SUCCESS:
|
||||
send_prompt_str(sess);
|
||||
send_prompt_str(sess);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pj_pool_release(pool);
|
||||
return retval;
|
||||
pj_pool_release(pool);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int readline_thread(void * p)
|
||||
{
|
||||
{
|
||||
struct cli_console_fe * fe = (struct cli_console_fe *)p;
|
||||
|
||||
printf("%s", fe->cfg.prompt_str.ptr);
|
||||
|
@ -472,7 +470,7 @@ static int readline_thread(void * p)
|
|||
pj_bool_t is_valid = PJ_TRUE;
|
||||
|
||||
if (fgets(recv_buf, fe->input.maxlen, stdin) == NULL) {
|
||||
/*
|
||||
/*
|
||||
* Be friendly to users who redirect commands into
|
||||
* program, when file ends, resume with kbd.
|
||||
* If exit is desired end script with q for quit
|
||||
|
@ -487,10 +485,10 @@ static int readline_thread(void * p)
|
|||
#endif
|
||||
puts("Cannot switch back to console from file redirection");
|
||||
if (fe->cfg.quit_command.slen) {
|
||||
pj_memcpy(recv_buf, fe->cfg.quit_command.ptr,
|
||||
pj_memcpy(recv_buf, fe->cfg.quit_command.ptr,
|
||||
fe->input.maxlen);
|
||||
}
|
||||
recv_buf[fe->cfg.quit_command.slen] = '\0';
|
||||
recv_buf[fe->cfg.quit_command.slen] = '\0';
|
||||
} else {
|
||||
puts("Switched back to console from file redirection");
|
||||
continue;
|
||||
|
@ -505,7 +503,7 @@ static int readline_thread(void * p)
|
|||
if (fe->thread_quit) {
|
||||
break;
|
||||
}
|
||||
input_len = pj_ansi_strlen(fe->input.buf);
|
||||
input_len = pj_ansi_strlen(fe->input.buf);
|
||||
if ((input_len > 1) && (fe->input.buf[input_len-2] == '?')) {
|
||||
fe->input.buf[input_len-1] = 0;
|
||||
is_valid = handle_hint(fe->sess);
|
||||
|
@ -515,14 +513,14 @@ static int readline_thread(void * p)
|
|||
is_valid = handle_exec(fe->sess);
|
||||
}
|
||||
|
||||
pj_sem_post(fe->input.sem);
|
||||
pj_sem_post(fe->input.sem);
|
||||
pj_sem_wait(fe->thread_sem);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PJ_DEF(pj_status_t) pj_cli_console_process(pj_cli_sess *sess,
|
||||
PJ_DEF(pj_status_t) pj_cli_console_process(pj_cli_sess *sess,
|
||||
char *buf,
|
||||
unsigned maxlen)
|
||||
{
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* Contributors:
|
||||
|
@ -164,13 +164,13 @@ PJ_DEF(pj_status_t) pj_init(void)
|
|||
/* Init logging */
|
||||
pj_log_init();
|
||||
|
||||
/* Initialize exception ID for the pool.
|
||||
/* Initialize exception ID for the pool.
|
||||
* Must do so after critical section is configured.
|
||||
*/
|
||||
rc = pj_exception_id_alloc("PJLIB/No memory", &PJ_NO_MEMORY_EXCEPTION);
|
||||
if (rc != PJ_SUCCESS)
|
||||
return rc;
|
||||
|
||||
|
||||
/* Init random seed. */
|
||||
/* Or probably not. Let application in charge of this */
|
||||
/* pj_srand( clock() ); */
|
||||
|
@ -187,7 +187,7 @@ PJ_DEF(pj_status_t) pj_init(void)
|
|||
return rc;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Flag PJLIB as initialized */
|
||||
++initialized;
|
||||
|
@ -382,7 +382,7 @@ PJ_DEF(int) pj_thread_get_prio_max(pj_thread_t *thread)
|
|||
/*
|
||||
* Get native thread handle
|
||||
*/
|
||||
PJ_DEF(void*) pj_thread_get_os_handle(pj_thread_t *thread)
|
||||
PJ_DEF(void*) pj_thread_get_os_handle(pj_thread_t *thread)
|
||||
{
|
||||
PJ_ASSERT_RETURN(thread, NULL);
|
||||
|
||||
|
@ -440,12 +440,12 @@ PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,
|
|||
thread->signature2 = SIGNATURE2;
|
||||
|
||||
if(cstr_thread_name && pj_strlen(&thread_name) < sizeof(thread->obj_name)-1)
|
||||
pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),
|
||||
pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),
|
||||
cstr_thread_name, thread->thread);
|
||||
else
|
||||
pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),
|
||||
pj_ansi_snprintf(thread->obj_name, sizeof(thread->obj_name),
|
||||
"thr%p", (void*)thread->thread);
|
||||
|
||||
|
||||
rc = pj_thread_local_set(thread_tls_id, thread);
|
||||
if (rc != PJ_SUCCESS) {
|
||||
pj_bzero(desc, sizeof(struct pj_thread_t));
|
||||
|
@ -457,7 +457,7 @@ PJ_DEF(pj_status_t) pj_thread_register ( const char *cstr_thread_name,
|
|||
thread->stk_size = 0xFFFFFFFFUL;
|
||||
thread->stk_max_usage = 0;
|
||||
#else
|
||||
stack_ptr = '\0';
|
||||
PJ_UNUSED_ARG(stack_ptr);
|
||||
#endif
|
||||
|
||||
*ptr_thread = thread;
|
||||
|
@ -532,11 +532,11 @@ static void *thread_main(void *param)
|
|||
/*
|
||||
* pj_thread_create(...)
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
||||
PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
||||
const char *thread_name,
|
||||
pj_thread_proc *proc,
|
||||
pj_thread_proc *proc,
|
||||
void *arg,
|
||||
pj_size_t stack_size,
|
||||
pj_size_t stack_size,
|
||||
unsigned flags,
|
||||
pj_thread_t **ptr_thread)
|
||||
{
|
||||
|
@ -554,11 +554,11 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
|||
/* Create thread record and assign name for the thread */
|
||||
rec = (struct pj_thread_t*) pj_pool_zalloc(pool, sizeof(pj_thread_t));
|
||||
PJ_ASSERT_RETURN(rec, PJ_ENOMEM);
|
||||
|
||||
|
||||
/* Set name. */
|
||||
if (!thread_name)
|
||||
if (!thread_name)
|
||||
thread_name = "thr%p";
|
||||
|
||||
|
||||
if (strchr(thread_name, '%')) {
|
||||
pj_ansi_snprintf(rec->obj_name, PJ_MAX_OBJ_NAME, thread_name, rec);
|
||||
} else {
|
||||
|
@ -586,7 +586,7 @@ PJ_DEF(pj_status_t) pj_thread_create( pj_pool_t *pool,
|
|||
} else {
|
||||
pj_assert(rec->suspended_mutex == NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Init thread attributes */
|
||||
pthread_attr_init(&thread_attr);
|
||||
|
@ -667,7 +667,7 @@ PJ_DEF(pj_thread_t*) pj_thread_this(void)
|
|||
{
|
||||
#if PJ_HAS_THREADS
|
||||
pj_thread_t *rec = (pj_thread_t*)pj_thread_local_get(thread_tls_id);
|
||||
|
||||
|
||||
if (rec == NULL) {
|
||||
pj_assert(!"Calling pjlib from unknown/external thread. You must "
|
||||
"register external threads with pj_thread_register() "
|
||||
|
@ -705,8 +705,8 @@ PJ_DEF(pj_status_t) pj_thread_join(pj_thread_t *p)
|
|||
if (result == 0)
|
||||
return PJ_SUCCESS;
|
||||
else {
|
||||
/* Calling pthread_join() on a thread that no longer exists and
|
||||
* getting back ESRCH isn't an error (in this context).
|
||||
/* Calling pthread_join() on a thread that no longer exists and
|
||||
* getting back ESRCH isn't an error (in this context).
|
||||
* Thanks Phil Torre <ptorre@zetron.com>.
|
||||
*/
|
||||
return result==ESRCH ? PJ_SUCCESS : PJ_RETURN_OS_ERROR(result);
|
||||
|
@ -761,9 +761,9 @@ PJ_DEF(pj_status_t) pj_thread_sleep(unsigned msec)
|
|||
|
||||
/* MacOS X (reported on 10.5) seems to always set errno to ETIMEDOUT.
|
||||
* It does so because usleep() is declared to return int, and we're
|
||||
* supposed to check for errno only when usleep() returns non-zero.
|
||||
* supposed to check for errno only when usleep() returns non-zero.
|
||||
* Unfortunately, usleep() is declared to return void in other platforms
|
||||
* so it's not possible to always check for the return value (unless
|
||||
* so it's not possible to always check for the return value (unless
|
||||
* we add a detection routine in autoconf).
|
||||
*
|
||||
* As a workaround, here we check if ETIMEDOUT is returned and
|
||||
|
@ -831,7 +831,7 @@ PJ_DEF(pj_status_t) pj_thread_get_stack_info( pj_thread_t *thread,
|
|||
/*
|
||||
* pj_atomic_create()
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool,
|
||||
PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool,
|
||||
pj_atomic_value_t initial,
|
||||
pj_atomic_t **ptr_atomic)
|
||||
{
|
||||
|
@ -841,7 +841,7 @@ PJ_DEF(pj_status_t) pj_atomic_create( pj_pool_t *pool,
|
|||
atomic_var = PJ_POOL_ZALLOC_T(pool, pj_atomic_t);
|
||||
|
||||
PJ_ASSERT_RETURN(atomic_var, PJ_ENOMEM);
|
||||
|
||||
|
||||
#if PJ_HAS_THREADS
|
||||
rc = pj_mutex_create(pool, "atm%p", PJ_MUTEX_SIMPLE, &atomic_var->mutex);
|
||||
if (rc != PJ_SUCCESS)
|
||||
|
@ -879,7 +879,7 @@ PJ_DEF(void) pj_atomic_set(pj_atomic_t *atomic_var, pj_atomic_value_t value)
|
|||
atomic_var->value = value;
|
||||
#if PJ_HAS_THREADS
|
||||
pj_mutex_unlock( atomic_var->mutex);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -888,7 +888,7 @@ PJ_DEF(void) pj_atomic_set(pj_atomic_t *atomic_var, pj_atomic_value_t value)
|
|||
PJ_DEF(pj_atomic_value_t) pj_atomic_get(pj_atomic_t *atomic_var)
|
||||
{
|
||||
pj_atomic_value_t oldval;
|
||||
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
#if PJ_HAS_THREADS
|
||||
|
@ -958,8 +958,8 @@ PJ_DEF(void) pj_atomic_dec(pj_atomic_t *atomic_var)
|
|||
|
||||
/*
|
||||
* pj_atomic_add_and_get()
|
||||
*/
|
||||
PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
|
||||
*/
|
||||
PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
|
||||
pj_atomic_value_t value )
|
||||
{
|
||||
pj_atomic_value_t new_value;
|
||||
|
@ -967,7 +967,7 @@ PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
|
|||
#if PJ_HAS_THREADS
|
||||
pj_mutex_lock(atomic_var->mutex);
|
||||
#endif
|
||||
|
||||
|
||||
atomic_var->value += value;
|
||||
new_value = atomic_var->value;
|
||||
|
||||
|
@ -980,8 +980,8 @@ PJ_DEF(pj_atomic_value_t) pj_atomic_add_and_get( pj_atomic_t *atomic_var,
|
|||
|
||||
/*
|
||||
* pj_atomic_add()
|
||||
*/
|
||||
PJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var,
|
||||
*/
|
||||
PJ_DEF(void) pj_atomic_add( pj_atomic_t *atomic_var,
|
||||
pj_atomic_value_t value )
|
||||
{
|
||||
pj_atomic_add_and_get(atomic_var, value);
|
||||
|
@ -1011,9 +1011,9 @@ PJ_DEF(pj_status_t) pj_thread_local_alloc(long *p_index)
|
|||
if (tls_flag[i] == 0)
|
||||
break;
|
||||
}
|
||||
if (i == MAX_THREADS)
|
||||
if (i == MAX_THREADS)
|
||||
return PJ_ETOOMANY;
|
||||
|
||||
|
||||
tls_flag[i] = 1;
|
||||
tls[i] = NULL;
|
||||
|
||||
|
@ -1118,7 +1118,7 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
|
|||
#elif (defined(PJ_RTEMS) && PJ_RTEMS!=0) || \
|
||||
defined(PJ_PTHREAD_MUTEXATTR_T_HAS_RECURSIVE)
|
||||
// Phil Torre <ptorre@zetron.com>:
|
||||
// The RTEMS implementation of POSIX mutexes doesn't include
|
||||
// The RTEMS implementation of POSIX mutexes doesn't include
|
||||
// pthread_mutexattr_settype(), so what follows is a hack
|
||||
// until I get RTEMS patched to support the set/get functions.
|
||||
//
|
||||
|
@ -1131,7 +1131,7 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
|
|||
rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if (rc != 0) {
|
||||
return PJ_RETURN_OS_ERROR(rc);
|
||||
}
|
||||
|
@ -1140,7 +1140,7 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
|
|||
if (rc != 0) {
|
||||
return PJ_RETURN_OS_ERROR(rc);
|
||||
}
|
||||
|
||||
|
||||
rc = pthread_mutexattr_destroy(&attr);
|
||||
if (rc != 0) {
|
||||
pj_status_t status = PJ_RETURN_OS_ERROR(rc);
|
||||
|
@ -1175,8 +1175,8 @@ static pj_status_t init_mutex(pj_mutex_t *mutex, const char *name, int type)
|
|||
/*
|
||||
* pj_mutex_create()
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,
|
||||
const char *name,
|
||||
PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,
|
||||
const char *name,
|
||||
int type,
|
||||
pj_mutex_t **ptr_mutex)
|
||||
{
|
||||
|
@ -1191,7 +1191,7 @@ PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,
|
|||
|
||||
if ((rc=init_mutex(mutex, name, type)) != PJ_SUCCESS)
|
||||
return rc;
|
||||
|
||||
|
||||
*ptr_mutex = mutex;
|
||||
return PJ_SUCCESS;
|
||||
#else /* PJ_HAS_THREADS */
|
||||
|
@ -1203,7 +1203,7 @@ PJ_DEF(pj_status_t) pj_mutex_create(pj_pool_t *pool,
|
|||
/*
|
||||
* pj_mutex_create_simple()
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool,
|
||||
PJ_DEF(pj_status_t) pj_mutex_create_simple( pj_pool_t *pool,
|
||||
const char *name,
|
||||
pj_mutex_t **mutex )
|
||||
{
|
||||
|
@ -1232,11 +1232,11 @@ PJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)
|
|||
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
|
||||
|
||||
#if PJ_DEBUG
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting (mutex owner=%s)",
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting (mutex owner=%s)",
|
||||
pj_thread_this()->obj_name,
|
||||
mutex->owner_name));
|
||||
#else
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting",
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is waiting",
|
||||
pj_thread_this()->obj_name));
|
||||
#endif
|
||||
|
||||
|
@ -1250,14 +1250,14 @@ PJ_DEF(pj_status_t) pj_mutex_lock(pj_mutex_t *mutex)
|
|||
++mutex->nesting_level;
|
||||
}
|
||||
|
||||
PJ_LOG(6,(mutex->obj_name,
|
||||
(status==0 ?
|
||||
"Mutex acquired by thread %s (level=%d)" :
|
||||
PJ_LOG(6,(mutex->obj_name,
|
||||
(status==0 ?
|
||||
"Mutex acquired by thread %s (level=%d)" :
|
||||
"Mutex acquisition FAILED by %s (level=%d)"),
|
||||
pj_thread_this()->obj_name,
|
||||
mutex->nesting_level));
|
||||
#else
|
||||
PJ_LOG(6,(mutex->obj_name,
|
||||
PJ_LOG(6,(mutex->obj_name,
|
||||
(status==0 ? "Mutex acquired by thread %s" : "FAILED by %s"),
|
||||
pj_thread_this()->obj_name));
|
||||
#endif
|
||||
|
@ -1290,11 +1290,11 @@ PJ_DEF(pj_status_t) pj_mutex_unlock(pj_mutex_t *mutex)
|
|||
mutex->owner_name[0] = '\0';
|
||||
}
|
||||
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s (level=%d)",
|
||||
pj_thread_this()->obj_name,
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s (level=%d)",
|
||||
pj_thread_this()->obj_name,
|
||||
mutex->nesting_level));
|
||||
#else
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s",
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex released by thread %s",
|
||||
pj_thread_this()->obj_name));
|
||||
#endif
|
||||
|
||||
|
@ -1321,7 +1321,7 @@ PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
|
|||
PJ_CHECK_STACK();
|
||||
PJ_ASSERT_RETURN(mutex, PJ_EINVAL);
|
||||
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is trying",
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s is trying",
|
||||
pj_thread_this()->obj_name));
|
||||
|
||||
status = pthread_mutex_trylock( &mutex->mutex );
|
||||
|
@ -1332,18 +1332,18 @@ PJ_DEF(pj_status_t) pj_mutex_trylock(pj_mutex_t *mutex)
|
|||
pj_ansi_strcpy(mutex->owner_name, mutex->owner->obj_name);
|
||||
++mutex->nesting_level;
|
||||
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s (level=%d)",
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s (level=%d)",
|
||||
pj_thread_this()->obj_name,
|
||||
mutex->nesting_level));
|
||||
#else
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s",
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex acquired by thread %s",
|
||||
pj_thread_this()->obj_name));
|
||||
#endif
|
||||
} else {
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s's trylock() failed",
|
||||
PJ_LOG(6,(mutex->obj_name, "Mutex: thread %s's trylock() failed",
|
||||
pj_thread_this()->obj_name));
|
||||
}
|
||||
|
||||
|
||||
if (status==0)
|
||||
return PJ_SUCCESS;
|
||||
else
|
||||
|
@ -1425,7 +1425,7 @@ PJ_DEF(pj_status_t) pj_rwmutex_create(pj_pool_t *pool, const char *name,
|
|||
pj_status_t status;
|
||||
|
||||
PJ_UNUSED_ARG(name);
|
||||
|
||||
|
||||
rwm = PJ_POOL_ALLOC_T(pool, pj_rwmutex_t);
|
||||
PJ_ASSERT_RETURN(rwm, PJ_ENOMEM);
|
||||
|
||||
|
@ -1515,9 +1515,9 @@ PJ_DEF(pj_status_t) pj_rwmutex_destroy(pj_rwmutex_t *mutex)
|
|||
/*
|
||||
* pj_sem_create()
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
||||
PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
||||
const char *name,
|
||||
unsigned initial,
|
||||
unsigned initial,
|
||||
unsigned max,
|
||||
pj_sem_t **ptr_sem)
|
||||
{
|
||||
|
@ -1536,7 +1536,7 @@ PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
|||
char sem_name[PJ_GUID_MAX_LENGTH+1];
|
||||
pj_str_t nam;
|
||||
|
||||
/* We should use SEM_NAME_LEN, but this doesn't seem to be
|
||||
/* We should use SEM_NAME_LEN, but this doesn't seem to be
|
||||
* declared anywhere? The value here is just from trial and error
|
||||
* to get the longest name supported.
|
||||
*/
|
||||
|
@ -1553,7 +1553,7 @@ PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
|||
}
|
||||
|
||||
/* Create semaphore */
|
||||
sem->sem = sem_open(sem_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR,
|
||||
sem->sem = sem_open(sem_name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR,
|
||||
initial);
|
||||
if (sem->sem == SEM_FAILED)
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
|
@ -1563,10 +1563,10 @@ PJ_DEF(pj_status_t) pj_sem_create( pj_pool_t *pool,
|
|||
}
|
||||
#else
|
||||
sem->sem = PJ_POOL_ALLOC_T(pool, sem_t);
|
||||
if (sem_init( sem->sem, 0, initial) != 0)
|
||||
if (sem_init( sem->sem, 0, initial) != 0)
|
||||
return PJ_RETURN_OS_ERROR(pj_get_native_os_error());
|
||||
#endif
|
||||
|
||||
|
||||
/* Set name. */
|
||||
if (!name) {
|
||||
name = "sem%p";
|
||||
|
@ -1599,16 +1599,16 @@ PJ_DEF(pj_status_t) pj_sem_wait(pj_sem_t *sem)
|
|||
PJ_CHECK_STACK();
|
||||
PJ_ASSERT_RETURN(sem, PJ_EINVAL);
|
||||
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s is waiting",
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s is waiting",
|
||||
pj_thread_this()->obj_name));
|
||||
|
||||
result = sem_wait( sem->sem );
|
||||
|
||||
|
||||
if (result == 0) {
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s",
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s",
|
||||
pj_thread_this()->obj_name));
|
||||
} else {
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s FAILED to acquire",
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore: thread %s FAILED to acquire",
|
||||
pj_thread_this()->obj_name));
|
||||
}
|
||||
|
||||
|
@ -1634,11 +1634,11 @@ PJ_DEF(pj_status_t) pj_sem_trywait(pj_sem_t *sem)
|
|||
PJ_ASSERT_RETURN(sem, PJ_EINVAL);
|
||||
|
||||
result = sem_trywait( sem->sem );
|
||||
|
||||
|
||||
if (result == 0) {
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s",
|
||||
PJ_LOG(6, (sem->obj_name, "Semaphore acquired by thread %s",
|
||||
pj_thread_this()->obj_name));
|
||||
}
|
||||
}
|
||||
if (result == 0)
|
||||
return PJ_SUCCESS;
|
||||
else
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "test.h"
|
||||
#include <pjlib.h>
|
||||
|
@ -38,7 +38,7 @@ pj_pool_factory *mem;
|
|||
int param_echo_sock_type;
|
||||
const char *param_echo_server = ECHO_SERVER_ADDRESS;
|
||||
int param_echo_port = ECHO_SERVER_START_PORT;
|
||||
int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
|
||||
int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
|
||||
PJ_LOG_HAS_MICRO_SEC;
|
||||
|
||||
int null_func()
|
||||
|
@ -63,7 +63,7 @@ int test_inner(void)
|
|||
app_perror("pj_init() error!!", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
//pj_dump_config();
|
||||
pj_caching_pool_init( &caching_pool, NULL, 0 );
|
||||
|
||||
|
@ -98,7 +98,7 @@ int test_inner(void)
|
|||
#if INCLUDE_STRING_TEST
|
||||
DO_TEST( string_test() );
|
||||
#endif
|
||||
|
||||
|
||||
#if INCLUDE_FIFOBUF_TEST
|
||||
DO_TEST( fifobuf_test() );
|
||||
#endif
|
||||
|
@ -184,8 +184,8 @@ int test_inner(void)
|
|||
if (param_echo_sock_type == 0)
|
||||
param_echo_sock_type = pj_SOCK_DGRAM();
|
||||
|
||||
echo_client( param_echo_sock_type,
|
||||
param_echo_server,
|
||||
echo_client( param_echo_sock_type,
|
||||
param_echo_server,
|
||||
param_echo_port);
|
||||
#endif
|
||||
|
||||
|
@ -196,18 +196,18 @@ on_return:
|
|||
pj_caching_pool_destroy( &caching_pool );
|
||||
|
||||
PJ_LOG(3,("test", ""));
|
||||
|
||||
|
||||
pj_thread_get_stack_info(pj_thread_this(), &filename, &line);
|
||||
PJ_LOG(3,("test", "Stack max usage: %u, deepest: %s:%u",
|
||||
PJ_LOG(3,("test", "Stack max usage: %u, deepest: %s:%u",
|
||||
pj_thread_get_stack_max_usage(pj_thread_this()),
|
||||
filename, line));
|
||||
if (rc == 0)
|
||||
PJ_LOG(3,("test", "Looks like everything is okay!.."));
|
||||
else
|
||||
PJ_LOG(3,("test", "Test completed with error(s)"));
|
||||
|
||||
|
||||
pj_shutdown();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -217,14 +217,12 @@ int test_main(void)
|
|||
{
|
||||
PJ_USE_EXCEPTION;
|
||||
|
||||
pj_AF_INET();
|
||||
|
||||
PJ_TRY {
|
||||
return test_inner();
|
||||
}
|
||||
PJ_CATCH_ANY {
|
||||
int id = PJ_GET_EXCEPTION();
|
||||
PJ_LOG(3,("test", "FATAL: unhandled exception id %d (%s)",
|
||||
PJ_LOG(3,("test", "FATAL: unhandled exception id %d (%s)",
|
||||
id, pj_exception_id_name(id)));
|
||||
}
|
||||
PJ_END;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
|||
* - whether multithreading works.
|
||||
* - whether thread timeslicing works, and threads have equal
|
||||
* time-slice proportion.
|
||||
*
|
||||
*
|
||||
* APIs tested:
|
||||
* - pj_thread_create()
|
||||
* - pj_thread_register()
|
||||
|
@ -77,6 +77,7 @@ static void* thread_proc(pj_uint32_t *pcounter)
|
|||
pj_status_t rc;
|
||||
|
||||
id = *pcounter;
|
||||
PJ_UNUSED_ARG(id); /* Warning about unused var if TRACE__ is disabled */
|
||||
TRACE__((THIS_FILE, " thread %d running..", id));
|
||||
|
||||
pj_bzero(desc, sizeof(desc));
|
||||
|
@ -120,9 +121,9 @@ static int simple_thread(const char *title, unsigned flags)
|
|||
pj_thread_t *thread;
|
||||
pj_status_t rc;
|
||||
pj_uint32_t counter = 0;
|
||||
|
||||
|
||||
PJ_LOG(3,(THIS_FILE, "..%s", title));
|
||||
|
||||
|
||||
pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
|
||||
if (!pool)
|
||||
return -1000;
|
||||
|
@ -152,14 +153,14 @@ static int simple_thread(const char *title, unsigned flags)
|
|||
PJ_LOG(3,(THIS_FILE, "...error: thread is not suspended"));
|
||||
return -1015;
|
||||
}
|
||||
|
||||
|
||||
rc = pj_thread_resume(thread);
|
||||
if (rc != PJ_SUCCESS) {
|
||||
app_perror("...error: resume thread error", rc);
|
||||
return -1020;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PJ_LOG(3,(THIS_FILE, "..waiting for thread to quit.."));
|
||||
|
||||
pj_thread_sleep(1500);
|
||||
|
@ -173,7 +174,7 @@ static int simple_thread(const char *title, unsigned flags)
|
|||
PJ_LOG(3,(THIS_FILE, "...error: thread is not running"));
|
||||
return -1025;
|
||||
}
|
||||
|
||||
|
||||
PJ_LOG(3,(THIS_FILE, "...%s success", title));
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
@ -202,10 +203,10 @@ static int timeslice_test(void)
|
|||
/* Create all threads in suspended mode. */
|
||||
for (i=0; i<NUM_THREADS; ++i) {
|
||||
counter[i] = i;
|
||||
rc = pj_thread_create(pool, "thread", (pj_thread_proc*)&thread_proc,
|
||||
&counter[i],
|
||||
PJ_THREAD_DEFAULT_STACK_SIZE,
|
||||
PJ_THREAD_SUSPENDED,
|
||||
rc = pj_thread_create(pool, "thread", (pj_thread_proc*)&thread_proc,
|
||||
&counter[i],
|
||||
PJ_THREAD_DEFAULT_STACK_SIZE,
|
||||
PJ_THREAD_SUSPENDED,
|
||||
&thread[i]);
|
||||
if (rc!=PJ_SUCCESS) {
|
||||
app_perror("...ERROR in pj_thread_create()", rc);
|
||||
|
@ -223,7 +224,7 @@ static int timeslice_test(void)
|
|||
/* Check that all counters are still zero. */
|
||||
for (i=0; i<NUM_THREADS; ++i) {
|
||||
if (counter[i] > i) {
|
||||
PJ_LOG(3,(THIS_FILE, "....ERROR! Thread %d-th is not suspended!",
|
||||
PJ_LOG(3,(THIS_FILE, "....ERROR! Thread %d-th is not suspended!",
|
||||
i));
|
||||
return -30;
|
||||
}
|
||||
|
@ -239,7 +240,7 @@ static int timeslice_test(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* Main thread sleeps for some time to allow threads to run.
|
||||
/* Main thread sleeps for some time to allow threads to run.
|
||||
* The longer we sleep, the more accurate the calculation will be,
|
||||
* but it'll make user waits for longer for the test to finish.
|
||||
*/
|
||||
|
@ -252,7 +253,7 @@ static int timeslice_test(void)
|
|||
|
||||
/* Wait until all threads quit, then destroy. */
|
||||
for (i=0; i<NUM_THREADS; ++i) {
|
||||
TRACE__((THIS_FILE, " Main thread joining thread %d [%p]..",
|
||||
TRACE__((THIS_FILE, " Main thread joining thread %d [%p]..",
|
||||
i, thread[i]));
|
||||
rc = pj_thread_join(thread[i]);
|
||||
if (rc != PJ_SUCCESS) {
|
||||
|
@ -291,14 +292,14 @@ static int timeslice_test(void)
|
|||
*/
|
||||
diff = (highest-lowest)*100 / ((highest+lowest)/2);
|
||||
if ( diff >= 50) {
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
"...ERROR: thread didn't have equal timeslice!"));
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
".....lowest counter=%u, highest counter=%u, diff=%u%%",
|
||||
lowest, highest, diff));
|
||||
return -80;
|
||||
} else {
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
"...info: timeslice diff between lowest & highest=%u%%",
|
||||
diff));
|
||||
}
|
||||
|
@ -314,11 +315,11 @@ int thread_test(void)
|
|||
rc = simple_thread("simple thread test", 0);
|
||||
if (rc != PJ_SUCCESS)
|
||||
return rc;
|
||||
|
||||
|
||||
rc = simple_thread("suspended thread test", PJ_THREAD_SUSPENDED);
|
||||
if (rc != PJ_SUCCESS)
|
||||
return rc;
|
||||
|
||||
|
||||
rc = timeslice_test();
|
||||
if (rc != PJ_SUCCESS)
|
||||
return rc;
|
||||
|
@ -328,7 +329,7 @@ int thread_test(void)
|
|||
|
||||
#else
|
||||
/* To prevent warning about "translation unit is empty"
|
||||
* when this test is disabled.
|
||||
* when this test is disabled.
|
||||
*/
|
||||
int dummy_thread_test;
|
||||
#endif /* INCLUDE_THREAD_TEST */
|
||||
|
|
|
@ -500,7 +500,7 @@ static int pb_thread_func (void *arg)
|
|||
status.status));
|
||||
if (status.status == SND_PCM_STATUS_READY ||
|
||||
status.status == SND_PCM_STATUS_UNDERRUN ||
|
||||
status.status == SND_PCM_STATUS_ERROR )
|
||||
status.status == SND_PCM_STATUS_ERROR )
|
||||
{
|
||||
if (snd_pcm_plugin_prepare (stream->pb_pcm,
|
||||
SND_PCM_CHANNEL_PLAYBACK) < 0)
|
||||
|
@ -777,7 +777,7 @@ static pj_status_t bb10_open_playback (struct bb10_stream *stream,
|
|||
|
||||
TRACE_((THIS_FILE, "bb10_open_playback: pb_frames = %d clock = %d",
|
||||
stream->pb_frames, param->clock_rate));
|
||||
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -863,6 +863,7 @@ static pj_status_t bb10_open_capture (struct bb10_stream *stream,
|
|||
}
|
||||
|
||||
frame_size = setup.buf.block.frag_size;
|
||||
PJ_UNUSED_ARG(frame_size); /* Warning about unused var */
|
||||
|
||||
/* Set clock rate */
|
||||
rate = param->clock_rate;
|
||||
|
@ -961,7 +962,7 @@ static pj_status_t bb10_factory_create_stream(pjmedia_aud_dev_factory *f,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* API: get running parameter
|
||||
* based on ALSA template
|
||||
*/
|
||||
|
@ -980,7 +981,7 @@ static pj_status_t bb10_stream_get_param(pjmedia_aud_stream *s,
|
|||
|
||||
/*
|
||||
* API: get capability
|
||||
* based on ALSA template
|
||||
* based on ALSA template
|
||||
*/
|
||||
static pj_status_t bb10_stream_get_cap(pjmedia_aud_stream *s,
|
||||
pjmedia_aud_dev_cap cap,
|
||||
|
@ -1042,7 +1043,7 @@ static pj_status_t bb10_stream_set_cap(pjmedia_aud_stream *strm,
|
|||
if (route == PJMEDIA_AUD_DEV_ROUTE_LOUDSPEAKER) {
|
||||
ret = bb10_initialize_playback_ctrl(stream,true);
|
||||
} else {
|
||||
ret = bb10_initialize_playback_ctrl(stream,false);
|
||||
ret = bb10_initialize_playback_ctrl(stream,false);
|
||||
}
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <pjmedia/types.h>
|
||||
#include <pjmedia/alaw_ulaw.h>
|
||||
|
@ -77,6 +77,16 @@
|
|||
|
||||
#if 0
|
||||
# define TRACE_(expr) PJ_LOG(5,expr)
|
||||
|
||||
static const char *state_names[] =
|
||||
{
|
||||
"Null",
|
||||
"local talking",
|
||||
"remote silent",
|
||||
"doubletalk",
|
||||
"remote talking"
|
||||
};
|
||||
|
||||
#else
|
||||
# define TRACE_(expr)
|
||||
#endif
|
||||
|
@ -125,23 +135,14 @@ typedef enum talk_state
|
|||
ST_REM_TALK
|
||||
} talk_state_t;
|
||||
|
||||
static const char *state_names[] =
|
||||
{
|
||||
"Null",
|
||||
"local talking",
|
||||
"remote silent",
|
||||
"doubletalk",
|
||||
"remote talking"
|
||||
};
|
||||
|
||||
|
||||
/* Description:
|
||||
|
||||
The echo suppressor tries to find the position of echoed signal by looking
|
||||
at the correlation between signal played to the speaker (played signal)
|
||||
at the correlation between signal played to the speaker (played signal)
|
||||
and the signal captured from the microphone (recorded signal).
|
||||
|
||||
To do this, it first divides the frames (from mic and speaker) into
|
||||
To do this, it first divides the frames (from mic and speaker) into
|
||||
segments, calculate the audio level of the segment, and save the level
|
||||
information in the playback and record history (play_hist and rec_hist
|
||||
respectively).
|
||||
|
@ -150,7 +151,7 @@ static const char *state_names[] =
|
|||
is put in the last position of the array.
|
||||
|
||||
The record history size is as large as the template size (tmpl_cnt), since
|
||||
we will use the record history as the template to find the best matching
|
||||
we will use the record history as the template to find the best matching
|
||||
position in the playback history.
|
||||
|
||||
Here is the record history buffer:
|
||||
|
@ -187,7 +188,7 @@ static const char *state_names[] =
|
|||
to the mic signal. The lower the correlation value the better (i.e. more
|
||||
similar) the signal is. The correlation value is done over the template
|
||||
duration.
|
||||
- the gain scaling factor, that is the ratio between mic signal and
|
||||
- the gain scaling factor, that is the ratio between mic signal and
|
||||
speaker signal. The ES calculates both the minimum and average ratios.
|
||||
|
||||
The ES calculates both the values above for every tail position in the
|
||||
|
@ -209,7 +210,7 @@ static const char *state_names[] =
|
|||
|
||||
Processing:
|
||||
|
||||
Once learning is done, the ES will change the level of the mic signal
|
||||
Once learning is done, the ES will change the level of the mic signal
|
||||
depending on the state of the conversation and according to the ratio that
|
||||
has been found in the learning phase above.
|
||||
|
||||
|
@ -263,7 +264,7 @@ typedef struct echo_supp
|
|||
|
||||
|
||||
/*
|
||||
* Create.
|
||||
* Create.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) echo_supp_create( pj_pool_t *pool,
|
||||
unsigned clock_rate,
|
||||
|
@ -292,32 +293,32 @@ PJ_DEF(pj_status_t) echo_supp_create( pj_pool_t *pool,
|
|||
ec->tail_cnt = (pj_uint16_t)(tail_ms / SEGMENT_PTIME);
|
||||
ec->play_hist_cnt = (pj_uint16_t)(ec->tail_cnt+ec->templ_cnt);
|
||||
|
||||
ec->max_calc = (pj_uint16_t)(MAX_CALC_DURATION_SEC * clock_rate /
|
||||
ec->max_calc = (pj_uint16_t)(MAX_CALC_DURATION_SEC * clock_rate /
|
||||
ec->samples_per_segment);
|
||||
|
||||
ec->rec_hist = (pj_uint16_t*)
|
||||
ec->rec_hist = (pj_uint16_t*)
|
||||
pj_pool_alloc(pool, ec->templ_cnt *
|
||||
sizeof(ec->rec_hist[0]));
|
||||
|
||||
/* Note: play history has twice number of elements */
|
||||
ec->play_hist = (pj_uint16_t*)
|
||||
ec->play_hist = (pj_uint16_t*)
|
||||
pj_pool_alloc(pool, ec->play_hist_cnt *
|
||||
sizeof(ec->play_hist[0]));
|
||||
|
||||
ec->corr_sum = (float*)
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
sizeof(ec->corr_sum[0]));
|
||||
ec->tmp_corr = (float*)
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
sizeof(ec->tmp_corr[0]));
|
||||
ec->min_factor = (float*)
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
sizeof(ec->min_factor[0]));
|
||||
ec->avg_factor = (float*)
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
sizeof(ec->avg_factor[0]));
|
||||
ec->tmp_factor = (float*)
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
pj_pool_alloc(pool, ec->tail_cnt *
|
||||
sizeof(ec->tmp_factor[0]));
|
||||
echo_supp_reset(ec);
|
||||
|
||||
|
@ -327,7 +328,7 @@ PJ_DEF(pj_status_t) echo_supp_create( pj_pool_t *pool,
|
|||
|
||||
|
||||
/*
|
||||
* Destroy.
|
||||
* Destroy.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) echo_supp_destroy(void *state)
|
||||
{
|
||||
|
@ -393,14 +394,14 @@ PJ_DEF(void) echo_supp_soft_reset(void *state)
|
|||
|
||||
|
||||
/* Set state */
|
||||
static void echo_supp_set_state(echo_supp *ec, talk_state_t state,
|
||||
static void echo_supp_set_state(echo_supp *ec, talk_state_t state,
|
||||
unsigned level)
|
||||
{
|
||||
PJ_UNUSED_ARG(level);
|
||||
|
||||
if (state != ec->talk_state) {
|
||||
TRACE_((THIS_FILE, "[%03d.%03d] %s --> %s, level=%u",
|
||||
(ec->update_cnt * SEGMENT_PTIME / 1000),
|
||||
TRACE_((THIS_FILE, "[%03d.%03d] %s --> %s, level=%u",
|
||||
(ec->update_cnt * SEGMENT_PTIME / 1000),
|
||||
((ec->update_cnt * SEGMENT_PTIME) % 1000),
|
||||
state_names[ec->talk_state],
|
||||
state_names[state], level));
|
||||
|
@ -469,9 +470,9 @@ static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
|
|||
ec->sum_rec_level += ec->rec_hist[i];
|
||||
} else {
|
||||
/* Update from previous calculation */
|
||||
ec->sum_rec_level = ec->sum_rec_level - old_rec_frm_level +
|
||||
ec->sum_rec_level = ec->sum_rec_level - old_rec_frm_level +
|
||||
ec->rec_hist[ec->templ_cnt-1];
|
||||
ec->rec_corr = ec->rec_corr - ((float)ec->rec_hist[0] /
|
||||
ec->rec_corr = ec->rec_corr - ((float)ec->rec_hist[0] /
|
||||
old_rec_frm_level) +
|
||||
((float)ec->rec_hist[ec->templ_cnt-1] /
|
||||
ec->rec_hist[ec->templ_cnt-2]);
|
||||
|
@ -482,8 +483,8 @@ static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
|
|||
* array since we may bail out early if the conversation state is not good
|
||||
* to detect echo.
|
||||
*/
|
||||
/*
|
||||
* First phase: do full calculation for the first position
|
||||
/*
|
||||
* First phase: do full calculation for the first position
|
||||
*/
|
||||
if (ec->sum_play_level0 == 0) {
|
||||
/* Buffer has just been filled up, do full calculation */
|
||||
|
@ -500,9 +501,9 @@ static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
|
|||
ec->play_corr0 = play_corr;
|
||||
} else {
|
||||
/* Update from previous calculation */
|
||||
ec->sum_play_level0 = ec->sum_play_level0 - old_play_frm_level +
|
||||
ec->sum_play_level0 = ec->sum_play_level0 - old_play_frm_level +
|
||||
ec->play_hist[ec->templ_cnt-1];
|
||||
ec->play_corr0 = ec->play_corr0 - ((float)ec->play_hist[0] /
|
||||
ec->play_corr0 = ec->play_corr0 - ((float)ec->play_hist[0] /
|
||||
old_play_frm_level) +
|
||||
((float)ec->play_hist[ec->templ_cnt-1] /
|
||||
ec->play_hist[ec->templ_cnt-2]);
|
||||
|
@ -584,7 +585,7 @@ static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
|
|||
/* Update the min and avg gain factor for this tail position */
|
||||
if (ec->tmp_factor[i] < ec->min_factor[i])
|
||||
ec->min_factor[i] = ec->tmp_factor[i];
|
||||
ec->avg_factor[i] = ((ec->avg_factor[i] * ec->tail_cnt) +
|
||||
ec->avg_factor[i] = ((ec->avg_factor[i] * ec->tail_cnt) +
|
||||
ec->tmp_factor[i]) /
|
||||
(ec->tail_cnt + 1);
|
||||
|
||||
|
@ -609,7 +610,7 @@ static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
|
|||
imin = (int)(ec->min_factor[ec->tail_index] * 1000);
|
||||
iavg = (int)(ec->avg_factor[ec->tail_index] * 1000);
|
||||
|
||||
PJ_LOG(4,(THIS_FILE,
|
||||
PJ_LOG(4,(THIS_FILE,
|
||||
"Echo suppressor updated at t=%03d.%03ds, echo tail=%d msec"
|
||||
", factor min/avg=%d.%03d/%d.%03d",
|
||||
(duration/1000), (duration%1000),
|
||||
|
@ -633,7 +634,7 @@ static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
|
|||
imin = (int)(ec->min_factor[ec->tail_index] * 1000);
|
||||
iavg = (int)(ec->avg_factor[ec->tail_index] * 1000);
|
||||
|
||||
PJ_LOG(4,(THIS_FILE,
|
||||
PJ_LOG(4,(THIS_FILE,
|
||||
"Echo suppressor learning done at t=%03d.%03ds, tail=%d ms"
|
||||
", factor min/avg=%d.%03d/%d.%03d",
|
||||
(duration/1000), (duration%1000),
|
||||
|
@ -646,7 +647,7 @@ static void echo_supp_update(echo_supp *ec, pj_int16_t *rec_frm,
|
|||
|
||||
|
||||
/* Amplify frame */
|
||||
static void amplify_frame(pj_int16_t *frm, unsigned length,
|
||||
static void amplify_frame(pj_int16_t *frm, unsigned length,
|
||||
pj_ufloat_t factor)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -656,7 +657,7 @@ static void amplify_frame(pj_int16_t *frm, unsigned length,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Perform echo cancellation.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,
|
||||
|
@ -709,8 +710,8 @@ PJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,
|
|||
/* Lookup in playback history to get max speaker level, to see
|
||||
* if remote user is currently talking
|
||||
*/
|
||||
for (i=ec->play_hist_cnt -lookup_cnt -tail_cnt;
|
||||
i<ec->play_hist_cnt-tail_cnt; ++i)
|
||||
for (i=ec->play_hist_cnt -lookup_cnt -tail_cnt;
|
||||
i<ec->play_hist_cnt-tail_cnt; ++i)
|
||||
{
|
||||
if (ec->play_hist[i] > play_level)
|
||||
play_level = ec->play_hist[i];
|
||||
|
@ -732,7 +733,7 @@ PJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,
|
|||
echo_supp_set_state(ec, ST_DOUBLETALK, rec_level);
|
||||
} else {
|
||||
/* Speaker is active, but we've picked up large signal in
|
||||
* the microphone. Assume that this is an echo, so bring
|
||||
* the microphone. Assume that this is an echo, so bring
|
||||
* the level down to minimum too.
|
||||
*/
|
||||
factor = ec->min_factor[ec->tail_index] / 2;
|
||||
|
@ -762,7 +763,7 @@ PJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,
|
|||
factor = (factor + ec->last_factor*19) / 20;
|
||||
|
||||
/* Amplify frame */
|
||||
amplify_frame(rec_frm, ec->samples_per_frame,
|
||||
amplify_frame(rec_frm, ec->samples_per_frame,
|
||||
pj_ufloat_from_float(factor));
|
||||
ec->last_factor = factor;
|
||||
|
||||
|
@ -774,7 +775,7 @@ PJ_DEF(pj_status_t) echo_supp_cancel_echo( void *state,
|
|||
level = pjmedia_linear2ulaw(level) ^ 0xFF;
|
||||
|
||||
/* Accumulate average echo residue to see the ES effectiveness */
|
||||
ec->residue = ((ec->residue * ec->running_cnt) + level) /
|
||||
ec->residue = ((ec->residue * ec->running_cnt) + level) /
|
||||
(ec->running_cnt + 1);
|
||||
|
||||
++ec->running_cnt;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
* Based on implementation kindly contributed by Switchlab, Ltd.
|
||||
|
@ -35,7 +35,7 @@
|
|||
/* Invalid sequence number, used as the initial value. */
|
||||
#define INVALID_OFFSET -9999
|
||||
|
||||
/* Maximum burst length, whenever an operation is bursting longer than
|
||||
/* Maximum burst length, whenever an operation is bursting longer than
|
||||
* this value, JB will assume that the opposite operation was idle.
|
||||
*/
|
||||
#define MAX_BURST_MSEC 1000
|
||||
|
@ -46,8 +46,8 @@
|
|||
#define INIT_CYCLE 10
|
||||
|
||||
|
||||
/* Minimal difference between JB size and 2*burst-level to perform
|
||||
* JB shrinking in static discard algorithm.
|
||||
/* Minimal difference between JB size and 2*burst-level to perform
|
||||
* JB shrinking in static discard algorithm.
|
||||
*/
|
||||
#define STA_DISC_SAFE_SHRINKING_DIFF 1
|
||||
|
||||
|
@ -67,13 +67,13 @@ typedef struct jb_framelist_t
|
|||
pj_size_t *content_len; /**< frame length array */
|
||||
pj_uint32_t *bit_info; /**< frame bit info array */
|
||||
pj_uint32_t *ts; /**< timestamp array */
|
||||
|
||||
|
||||
/* States */
|
||||
unsigned head; /**< index of head, pointed frame
|
||||
will be returned by next GET */
|
||||
unsigned size; /**< current size of framelist,
|
||||
unsigned size; /**< current size of framelist,
|
||||
including discarded frames. */
|
||||
unsigned discarded_num; /**< current number of discarded
|
||||
unsigned discarded_num; /**< current number of discarded
|
||||
frames. */
|
||||
int origin; /**< original index of flist_head */
|
||||
|
||||
|
@ -91,14 +91,14 @@ struct pjmedia_jbuf
|
|||
pj_str_t jb_name; /**< jitter buffer name */
|
||||
pj_size_t jb_frame_size; /**< frame size */
|
||||
unsigned jb_frame_ptime; /**< frame duration. */
|
||||
pj_size_t jb_max_count; /**< capacity of jitter buffer,
|
||||
pj_size_t jb_max_count; /**< capacity of jitter buffer,
|
||||
in frames */
|
||||
int jb_init_prefetch; /**< Initial prefetch */
|
||||
int jb_min_prefetch; /**< Minimum allowable prefetch */
|
||||
int jb_max_prefetch; /**< Maximum allowable prefetch */
|
||||
int jb_max_burst; /**< maximum possible burst, whenever
|
||||
burst exceeds this value, it
|
||||
won't be included in level
|
||||
burst exceeds this value, it
|
||||
won't be included in level
|
||||
calculation */
|
||||
int jb_min_shrink_gap; /**< How often can we shrink */
|
||||
discard_algo jb_discard_algo; /**< Discard algorithm */
|
||||
|
@ -107,27 +107,27 @@ struct pjmedia_jbuf
|
|||
jb_framelist_t jb_framelist; /**< the buffer */
|
||||
|
||||
/* States */
|
||||
int jb_level; /**< delay between source &
|
||||
destination (calculated according
|
||||
of the number of burst get/put
|
||||
int jb_level; /**< delay between source &
|
||||
destination (calculated according
|
||||
of the number of burst get/put
|
||||
operations) */
|
||||
int jb_max_hist_level; /**< max level during the last level
|
||||
int jb_max_hist_level; /**< max level during the last level
|
||||
calculations */
|
||||
int jb_stable_hist; /**< num of times the delay has been
|
||||
int jb_stable_hist; /**< num of times the delay has been
|
||||
lower then the prefetch num */
|
||||
int jb_last_op; /**< last operation executed
|
||||
int jb_last_op; /**< last operation executed
|
||||
(put/get) */
|
||||
int jb_eff_level; /**< effective burst level */
|
||||
int jb_prefetch; /**< no. of frame to insert before
|
||||
removing some (at the beginning
|
||||
of the framelist->content
|
||||
int jb_prefetch; /**< no. of frame to insert before
|
||||
removing some (at the beginning
|
||||
of the framelist->content
|
||||
operation), the value may be
|
||||
continuously updated based on
|
||||
current frame burst level. */
|
||||
pj_bool_t jb_prefetching; /**< flag if jbuf is prefetching. */
|
||||
int jb_status; /**< status is 'init' until the first
|
||||
int jb_status; /**< status is 'init' until the first
|
||||
'put' operation */
|
||||
int jb_init_cycle_cnt; /**< status is 'init' until the first
|
||||
int jb_init_cycle_cnt; /**< status is 'init' until the first
|
||||
'put' operation */
|
||||
|
||||
int jb_discard_ref; /**< Seq # of last frame deleted or
|
||||
|
@ -136,7 +136,7 @@ struct pjmedia_jbuf
|
|||
to perform discard (in frm) */
|
||||
|
||||
/* Statistics */
|
||||
pj_math_stat jb_delay; /**< Delay statistics of jitter buffer
|
||||
pj_math_stat jb_delay; /**< Delay statistics of jitter buffer
|
||||
(in ms) */
|
||||
pj_math_stat jb_burst; /**< Burst statistics (in frames) */
|
||||
unsigned jb_lost; /**< Number of lost frames. */
|
||||
|
@ -164,7 +164,7 @@ struct pjmedia_jbuf
|
|||
|
||||
|
||||
|
||||
/* Enabling this would log the jitter buffer state about once per
|
||||
/* Enabling this would log the jitter buffer state about once per
|
||||
* second.
|
||||
*/
|
||||
#if 0
|
||||
|
@ -180,7 +180,7 @@ static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
|
|||
static pj_status_t jb_framelist_init( pj_pool_t *pool,
|
||||
jb_framelist_t *framelist,
|
||||
unsigned frame_size,
|
||||
unsigned max_count)
|
||||
unsigned max_count)
|
||||
{
|
||||
PJ_ASSERT_RETURN(pool && framelist, PJ_EINVAL);
|
||||
|
||||
|
@ -188,24 +188,24 @@ static pj_status_t jb_framelist_init( pj_pool_t *pool,
|
|||
|
||||
framelist->frame_size = frame_size;
|
||||
framelist->max_count = max_count;
|
||||
framelist->content = (char*)
|
||||
framelist->content = (char*)
|
||||
pj_pool_alloc(pool,
|
||||
framelist->frame_size*
|
||||
framelist->frame_size*
|
||||
framelist->max_count);
|
||||
framelist->frame_type = (int*)
|
||||
pj_pool_alloc(pool,
|
||||
pj_pool_alloc(pool,
|
||||
sizeof(framelist->frame_type[0])*
|
||||
framelist->max_count);
|
||||
framelist->content_len = (pj_size_t*)
|
||||
pj_pool_alloc(pool,
|
||||
pj_pool_alloc(pool,
|
||||
sizeof(framelist->content_len[0])*
|
||||
framelist->max_count);
|
||||
framelist->bit_info = (pj_uint32_t*)
|
||||
pj_pool_alloc(pool,
|
||||
pj_pool_alloc(pool,
|
||||
sizeof(framelist->bit_info[0])*
|
||||
framelist->max_count);
|
||||
framelist->ts = (pj_uint32_t*)
|
||||
pj_pool_alloc(pool,
|
||||
pj_pool_alloc(pool,
|
||||
sizeof(framelist->ts[0])*
|
||||
framelist->max_count);
|
||||
|
||||
|
@ -213,13 +213,13 @@ static pj_status_t jb_framelist_init( pj_pool_t *pool,
|
|||
|
||||
}
|
||||
|
||||
static pj_status_t jb_framelist_destroy(jb_framelist_t *framelist)
|
||||
static pj_status_t jb_framelist_destroy(jb_framelist_t *framelist)
|
||||
{
|
||||
PJ_UNUSED_ARG(framelist);
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist)
|
||||
static pj_status_t jb_framelist_reset(jb_framelist_t *framelist)
|
||||
{
|
||||
framelist->head = 0;
|
||||
framelist->origin = INVALID_OFFSET;
|
||||
|
@ -227,39 +227,39 @@ static pj_status_t jb_framelist_reset(jb_framelist_t *framelist)
|
|||
framelist->discarded_num = 0;
|
||||
|
||||
|
||||
//pj_bzero(framelist->content,
|
||||
// framelist->frame_size *
|
||||
//pj_bzero(framelist->content,
|
||||
// framelist->frame_size *
|
||||
// framelist->max_count);
|
||||
|
||||
pj_memset(framelist->frame_type,
|
||||
PJMEDIA_JB_MISSING_FRAME,
|
||||
sizeof(framelist->frame_type[0]) *
|
||||
sizeof(framelist->frame_type[0]) *
|
||||
framelist->max_count);
|
||||
|
||||
pj_bzero(framelist->content_len,
|
||||
sizeof(framelist->content_len[0]) *
|
||||
pj_bzero(framelist->content_len,
|
||||
sizeof(framelist->content_len[0]) *
|
||||
framelist->max_count);
|
||||
|
||||
//pj_bzero(framelist->bit_info,
|
||||
// sizeof(framelist->bit_info[0]) *
|
||||
// sizeof(framelist->bit_info[0]) *
|
||||
// framelist->max_count);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static unsigned jb_framelist_size(const jb_framelist_t *framelist)
|
||||
static unsigned jb_framelist_size(const jb_framelist_t *framelist)
|
||||
{
|
||||
return framelist->size;
|
||||
}
|
||||
|
||||
|
||||
static unsigned jb_framelist_eff_size(const jb_framelist_t *framelist)
|
||||
static unsigned jb_framelist_eff_size(const jb_framelist_t *framelist)
|
||||
{
|
||||
return (framelist->size - framelist->discarded_num);
|
||||
}
|
||||
|
||||
static int jb_framelist_origin(const jb_framelist_t *framelist)
|
||||
static int jb_framelist_origin(const jb_framelist_t *framelist)
|
||||
{
|
||||
return framelist->origin;
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
|
|||
pjmedia_jb_frame_type *p_type,
|
||||
pj_uint32_t *bit_info,
|
||||
pj_uint32_t *ts,
|
||||
int *seq)
|
||||
int *seq)
|
||||
{
|
||||
if (framelist->size) {
|
||||
pj_bool_t prev_discarded = PJ_FALSE;
|
||||
|
@ -295,11 +295,11 @@ static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
|
|||
if (bit_info)
|
||||
*bit_info = 0;
|
||||
} else {
|
||||
pj_memcpy(frame,
|
||||
framelist->content +
|
||||
pj_memcpy(frame,
|
||||
framelist->content +
|
||||
framelist->head * framelist->frame_size,
|
||||
framelist->frame_size);
|
||||
*p_type = (pjmedia_jb_frame_type)
|
||||
*p_type = (pjmedia_jb_frame_type)
|
||||
framelist->frame_type[framelist->head];
|
||||
if (size)
|
||||
*size = framelist->content_len[framelist->head];
|
||||
|
@ -311,7 +311,7 @@ static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
|
|||
if (seq)
|
||||
*seq = framelist->origin;
|
||||
|
||||
//pj_bzero(framelist->content +
|
||||
//pj_bzero(framelist->content +
|
||||
// framelist->head * framelist->frame_size,
|
||||
// framelist->frame_size);
|
||||
framelist->frame_type[framelist->head] = PJMEDIA_JB_MISSING_FRAME;
|
||||
|
@ -322,7 +322,7 @@ static pj_bool_t jb_framelist_get(jb_framelist_t *framelist,
|
|||
framelist->origin++;
|
||||
framelist->head = (framelist->head + 1) % framelist->max_count;
|
||||
framelist->size--;
|
||||
|
||||
|
||||
return PJ_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist,
|
|||
pjmedia_jb_frame_type *type,
|
||||
pj_uint32_t *bit_info,
|
||||
pj_uint32_t *ts,
|
||||
int *seq)
|
||||
int *seq)
|
||||
{
|
||||
unsigned pos, idx;
|
||||
|
||||
|
@ -366,7 +366,7 @@ static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist,
|
|||
if (frame)
|
||||
*frame = framelist->content + pos*framelist->frame_size;
|
||||
if (type)
|
||||
*type = (pjmedia_jb_frame_type)
|
||||
*type = (pjmedia_jb_frame_type)
|
||||
framelist->frame_type[pos];
|
||||
if (size)
|
||||
*size = framelist->content_len[pos];
|
||||
|
@ -383,9 +383,9 @@ static pj_bool_t jb_framelist_peek(jb_framelist_t *framelist,
|
|||
|
||||
/* Remove oldest frames as many as param 'count' */
|
||||
static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
|
||||
unsigned count)
|
||||
unsigned count)
|
||||
{
|
||||
if (count > framelist->size)
|
||||
if (count > framelist->size)
|
||||
count = framelist->size;
|
||||
|
||||
if (count) {
|
||||
|
@ -409,7 +409,7 @@ static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
|
|||
}
|
||||
}
|
||||
|
||||
//pj_bzero(framelist->content +
|
||||
//pj_bzero(framelist->content +
|
||||
// framelist->head * framelist->frame_size,
|
||||
// step1*framelist->frame_size);
|
||||
pj_memset(framelist->frame_type+framelist->head,
|
||||
|
@ -439,7 +439,7 @@ static unsigned jb_framelist_remove_head(jb_framelist_t *framelist,
|
|||
framelist->head = (framelist->head + count) % framelist->max_count;
|
||||
framelist->size -= count;
|
||||
}
|
||||
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
@ -548,9 +548,9 @@ enum pjmedia_jb_op
|
|||
};
|
||||
|
||||
|
||||
PJ_DEF(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,
|
||||
PJ_DEF(pj_status_t) pjmedia_jbuf_create(pj_pool_t *pool,
|
||||
const pj_str_t *name,
|
||||
unsigned frame_size,
|
||||
unsigned frame_size,
|
||||
unsigned ptime,
|
||||
unsigned max_count,
|
||||
pjmedia_jbuf **p_jb)
|
||||
|
@ -596,7 +596,7 @@ PJ_DEF(pj_status_t) pjmedia_jbuf_set_fixed( pjmedia_jbuf *jb,
|
|||
PJ_ASSERT_RETURN(jb, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(prefetch <= jb->jb_max_count, PJ_EINVAL);
|
||||
|
||||
jb->jb_min_prefetch = jb->jb_max_prefetch =
|
||||
jb->jb_min_prefetch = jb->jb_max_prefetch =
|
||||
jb->jb_prefetch = jb->jb_init_prefetch = prefetch;
|
||||
|
||||
pjmedia_jbuf_set_discard(jb, PJMEDIA_JB_DISCARD_NONE);
|
||||
|
@ -675,12 +675,12 @@ PJ_DEF(pj_status_t) pjmedia_jbuf_destroy(pjmedia_jbuf *jb)
|
|||
" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n"
|
||||
" burst (min/max/avg/dev)=%d/%d/%d/%d frames\n"
|
||||
" lost=%d discard=%d empty=%d",
|
||||
jb_framelist_size(&jb->jb_framelist),
|
||||
jb_framelist_eff_size(&jb->jb_framelist),
|
||||
jb_framelist_size(&jb->jb_framelist),
|
||||
jb_framelist_eff_size(&jb->jb_framelist),
|
||||
jb->jb_prefetch, jb->jb_eff_level,
|
||||
jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean,
|
||||
jb->jb_delay.min, jb->jb_delay.max, jb->jb_delay.mean,
|
||||
pj_math_stat_get_stddev(&jb->jb_delay),
|
||||
jb->jb_burst.min, jb->jb_burst.max, jb->jb_burst.mean,
|
||||
jb->jb_burst.min, jb->jb_burst.max, jb->jb_burst.mean,
|
||||
pj_math_stat_get_stddev(&jb->jb_burst),
|
||||
jb->jb_lost, jb->jb_discard, jb->jb_empty));
|
||||
|
||||
|
@ -704,14 +704,14 @@ static void jbuf_calculate_jitter(pjmedia_jbuf *jb)
|
|||
if (jb->jb_level < jb->jb_eff_level) {
|
||||
|
||||
enum { STABLE_HISTORY_LIMIT = 20 };
|
||||
|
||||
|
||||
jb->jb_stable_hist++;
|
||||
|
||||
/* Only update the effective level (and prefetch) if 'stable'
|
||||
|
||||
/* Only update the effective level (and prefetch) if 'stable'
|
||||
* condition is reached (not just short time impulse)
|
||||
*/
|
||||
if (jb->jb_stable_hist > STABLE_HISTORY_LIMIT) {
|
||||
|
||||
|
||||
diff = (jb->jb_eff_level - jb->jb_max_hist_level) / 3;
|
||||
|
||||
if (diff < 1)
|
||||
|
@ -723,7 +723,7 @@ static void jbuf_calculate_jitter(pjmedia_jbuf *jb)
|
|||
/* Update prefetch based on level */
|
||||
if (jb->jb_init_prefetch) {
|
||||
jb->jb_prefetch = jb->jb_eff_level;
|
||||
if (jb->jb_prefetch < jb->jb_min_prefetch)
|
||||
if (jb->jb_prefetch < jb->jb_min_prefetch)
|
||||
jb->jb_prefetch = jb->jb_min_prefetch;
|
||||
if (jb->jb_prefetch > jb->jb_max_prefetch)
|
||||
jb->jb_prefetch = jb->jb_max_prefetch;
|
||||
|
@ -735,6 +735,7 @@ static void jbuf_calculate_jitter(pjmedia_jbuf *jb)
|
|||
|
||||
TRACE__((jb->jb_name.ptr,"jb updated(1), lvl=%d pre=%d, size=%d",
|
||||
jb->jb_eff_level, jb->jb_prefetch, cur_size));
|
||||
PJ_UNUSED_ARG(cur_size); /* Warning about unused var */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -758,7 +759,7 @@ static void jbuf_calculate_jitter(pjmedia_jbuf *jb)
|
|||
/* Do not reset max_hist_level. */
|
||||
//jb->jb_max_hist_level = 0;
|
||||
|
||||
TRACE__((jb->jb_name.ptr,"jb updated(2), lvl=%d pre=%d, size=%d",
|
||||
TRACE__((jb->jb_name.ptr,"jb updated(2), lvl=%d pre=%d, size=%d",
|
||||
jb->jb_eff_level, jb->jb_prefetch, cur_size));
|
||||
}
|
||||
|
||||
|
@ -777,11 +778,11 @@ static void jbuf_discard_static(pjmedia_jbuf *jb)
|
|||
* its size is twice of current burst level, there can be drift.
|
||||
*
|
||||
* Moreover, normally drift level is quite low, so JB shouldn't need
|
||||
* to shrink aggresively, it will shrink maximum one frame per
|
||||
* PJMEDIA_JBUF_DISC_MIN_GAP ms. Theoritically, JB may handle drift level
|
||||
* to shrink aggresively, it will shrink maximum one frame per
|
||||
* PJMEDIA_JBUF_DISC_MIN_GAP ms. Theoritically, JB may handle drift level
|
||||
* as much as = FRAME_PTIME/PJMEDIA_JBUF_DISC_MIN_GAP * 100%
|
||||
*
|
||||
* Whenever there is drift, where PUT > GET, this method will keep
|
||||
* Whenever there is drift, where PUT > GET, this method will keep
|
||||
* the latency (JB size) as much as twice of burst level.
|
||||
*/
|
||||
|
||||
|
@ -796,8 +797,8 @@ static void jbuf_discard_static(pjmedia_jbuf *jb)
|
|||
if (diff >= STA_DISC_SAFE_SHRINKING_DIFF) {
|
||||
int seq_origin;
|
||||
|
||||
/* Check and adjust jb_discard_ref, in case there was
|
||||
* seq restart
|
||||
/* Check and adjust jb_discard_ref, in case there was
|
||||
* seq restart
|
||||
*/
|
||||
seq_origin = jb_framelist_origin(&jb->jb_framelist);
|
||||
if (seq_origin < jb->jb_discard_ref)
|
||||
|
@ -813,7 +814,7 @@ static void jbuf_discard_static(pjmedia_jbuf *jb)
|
|||
jb->jb_discard_ref = jb_framelist_origin(&jb->jb_framelist);
|
||||
jb->jb_discard += diff;
|
||||
|
||||
TRACE__((jb->jb_name.ptr,
|
||||
TRACE__((jb->jb_name.ptr,
|
||||
"JB shrinking %d frame(s), cur size=%d", diff,
|
||||
jb_framelist_eff_size(&jb->jb_framelist)));
|
||||
}
|
||||
|
@ -845,7 +846,7 @@ static void jbuf_discard_progressive(pjmedia_jbuf *jb)
|
|||
else if (burst_level >= PJMEDIA_JBUF_PRO_DISC_MAX_BURST)
|
||||
T = PJMEDIA_JBUF_PRO_DISC_T2;
|
||||
else
|
||||
T = PJMEDIA_JBUF_PRO_DISC_T1 +
|
||||
T = PJMEDIA_JBUF_PRO_DISC_T1 +
|
||||
(PJMEDIA_JBUF_PRO_DISC_T2 - PJMEDIA_JBUF_PRO_DISC_T1) *
|
||||
(burst_level - PJMEDIA_JBUF_PRO_DISC_MIN_BURST) /
|
||||
(PJMEDIA_JBUF_PRO_DISC_MAX_BURST-PJMEDIA_JBUF_PRO_DISC_MIN_BURST);
|
||||
|
@ -873,14 +874,14 @@ static void jbuf_discard_progressive(pjmedia_jbuf *jb)
|
|||
/* Check if we need to discard now */
|
||||
if (last_seq >= (jb->jb_discard_ref + (int)jb->jb_discard_dist)) {
|
||||
int discard_seq;
|
||||
|
||||
|
||||
discard_seq = jb->jb_discard_ref + jb->jb_discard_dist;
|
||||
if (discard_seq < jb_framelist_origin(&jb->jb_framelist))
|
||||
discard_seq = jb_framelist_origin(&jb->jb_framelist);
|
||||
|
||||
jb_framelist_discard(&jb->jb_framelist, discard_seq);
|
||||
|
||||
TRACE__((jb->jb_name.ptr,
|
||||
TRACE__((jb->jb_name.ptr,
|
||||
"Discard #%d: ref=#%d dist=%d orig=%d size=%d/%d "
|
||||
"burst=%d/%d",
|
||||
discard_seq,
|
||||
|
@ -896,7 +897,7 @@ static void jbuf_discard_progressive(pjmedia_jbuf *jb)
|
|||
jb->jb_discard_ref = discard_seq;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)
|
||||
{
|
||||
|
@ -904,8 +905,8 @@ PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)
|
|||
jb->jb_last_op = oper;
|
||||
|
||||
if (jb->jb_status == JB_STATUS_INITIALIZING) {
|
||||
/* Switch status 'initializing' -> 'processing' after some OP
|
||||
* switch cycles and current OP is GET (burst level is calculated
|
||||
/* Switch status 'initializing' -> 'processing' after some OP
|
||||
* switch cycles and current OP is GET (burst level is calculated
|
||||
* based on PUT burst), so burst calculation is guaranted to be
|
||||
* performed right after the status switching.
|
||||
*/
|
||||
|
@ -921,10 +922,10 @@ PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)
|
|||
}
|
||||
}
|
||||
|
||||
/* Perform jitter calculation based on PUT burst-level only, since
|
||||
/* Perform jitter calculation based on PUT burst-level only, since
|
||||
* GET burst-level may not be accurate, e.g: when VAD is active.
|
||||
* Note that when burst-level is too big, i.e: exceeds jb_max_burst,
|
||||
* the GET op may be idle, in this case, we better skip the jitter
|
||||
* the GET op may be idle, in this case, we better skip the jitter
|
||||
* calculation.
|
||||
*/
|
||||
if (oper == JB_OP_GET && jb->jb_level <= jb->jb_max_burst)
|
||||
|
@ -939,28 +940,28 @@ PJ_INLINE(void) jbuf_update(pjmedia_jbuf *jb, int oper)
|
|||
}
|
||||
}
|
||||
|
||||
PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,
|
||||
const void *frame,
|
||||
pj_size_t frame_size,
|
||||
PJ_DEF(void) pjmedia_jbuf_put_frame( pjmedia_jbuf *jb,
|
||||
const void *frame,
|
||||
pj_size_t frame_size,
|
||||
int frame_seq)
|
||||
{
|
||||
pjmedia_jbuf_put_frame3(jb, frame, frame_size, 0, frame_seq, 0, NULL);
|
||||
}
|
||||
|
||||
PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
|
||||
const void *frame,
|
||||
pj_size_t frame_size,
|
||||
PJ_DEF(void) pjmedia_jbuf_put_frame2(pjmedia_jbuf *jb,
|
||||
const void *frame,
|
||||
pj_size_t frame_size,
|
||||
pj_uint32_t bit_info,
|
||||
int frame_seq,
|
||||
pj_bool_t *discarded)
|
||||
{
|
||||
pjmedia_jbuf_put_frame3(jb, frame, frame_size, bit_info, frame_seq, 0,
|
||||
pjmedia_jbuf_put_frame3(jb, frame, frame_size, bit_info, frame_seq, 0,
|
||||
discarded);
|
||||
}
|
||||
|
||||
PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,
|
||||
const void *frame,
|
||||
pj_size_t frame_size,
|
||||
PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,
|
||||
const void *frame,
|
||||
pj_size_t frame_size,
|
||||
pj_uint32_t bit_info,
|
||||
int frame_seq,
|
||||
pj_uint32_t ts,
|
||||
|
@ -977,7 +978,7 @@ PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,
|
|||
status = jb_framelist_put_at(&jb->jb_framelist, frame_seq, frame,
|
||||
(unsigned)min_frame_size, bit_info, ts,
|
||||
PJMEDIA_JB_NORMAL_FRAME);
|
||||
|
||||
|
||||
/* Jitter buffer is full, remove some older frames */
|
||||
while (status == PJ_ETOOMANY) {
|
||||
int distance;
|
||||
|
@ -1009,7 +1010,7 @@ PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,
|
|||
|
||||
if (status == PJ_SUCCESS) {
|
||||
if (jb->jb_prefetching) {
|
||||
TRACE__((jb->jb_name.ptr, "PUT prefetch_cnt=%d/%d",
|
||||
TRACE__((jb->jb_name.ptr, "PUT prefetch_cnt=%d/%d",
|
||||
new_size, jb->jb_prefetch));
|
||||
if (new_size >= jb->jb_prefetch)
|
||||
jb->jb_prefetching = PJ_FALSE;
|
||||
|
@ -1023,8 +1024,8 @@ PJ_DEF(void) pjmedia_jbuf_put_frame3(pjmedia_jbuf *jb,
|
|||
/*
|
||||
* Get frame from jitter buffer.
|
||||
*/
|
||||
PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
|
||||
void *frame,
|
||||
PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
|
||||
void *frame,
|
||||
char *p_frame_type)
|
||||
{
|
||||
pjmedia_jbuf_get_frame3(jb, frame, NULL, p_frame_type, NULL,
|
||||
|
@ -1034,8 +1035,8 @@ PJ_DEF(void) pjmedia_jbuf_get_frame( pjmedia_jbuf *jb,
|
|||
/*
|
||||
* Get frame from jitter buffer.
|
||||
*/
|
||||
PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
|
||||
void *frame,
|
||||
PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
|
||||
void *frame,
|
||||
pj_size_t *size,
|
||||
char *p_frame_type,
|
||||
pj_uint32_t *bit_info)
|
||||
|
@ -1047,8 +1048,8 @@ PJ_DEF(void) pjmedia_jbuf_get_frame2(pjmedia_jbuf *jb,
|
|||
/*
|
||||
* Get frame from jitter buffer.
|
||||
*/
|
||||
PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
|
||||
void *frame,
|
||||
PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
|
||||
void *frame,
|
||||
pj_size_t *size,
|
||||
char *p_frame_type,
|
||||
pj_uint32_t *bit_info,
|
||||
|
@ -1077,7 +1078,7 @@ PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
|
|||
pj_bool_t res;
|
||||
|
||||
/* Try to retrieve a frame from frame list */
|
||||
res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,
|
||||
res = jb_framelist_get(&jb->jb_framelist, frame, size, &ftype,
|
||||
bit_info, ts, seq);
|
||||
if (res) {
|
||||
/* We've successfully retrieved a frame from the frame list, but
|
||||
|
@ -1096,7 +1097,7 @@ PJ_DEF(void) pjmedia_jbuf_get_frame3(pjmedia_jbuf *jb,
|
|||
|
||||
/* We've just retrieved one frame, so add one to cur_size */
|
||||
cur_size = jb_framelist_eff_size(&jb->jb_framelist) + 1;
|
||||
pj_math_stat_update(&jb->jb_delay,
|
||||
pj_math_stat_update(&jb->jb_delay,
|
||||
cur_size*jb->jb_frame_ptime);
|
||||
}
|
||||
} else {
|
||||
|
@ -1128,16 +1129,16 @@ PJ_DEF(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
|
|||
state->frame_size = (unsigned)jb->jb_frame_size;
|
||||
state->min_prefetch = jb->jb_min_prefetch;
|
||||
state->max_prefetch = jb->jb_max_prefetch;
|
||||
|
||||
|
||||
state->burst = jb->jb_eff_level;
|
||||
state->prefetch = jb->jb_prefetch;
|
||||
state->size = jb_framelist_eff_size(&jb->jb_framelist);
|
||||
|
||||
|
||||
state->avg_delay = jb->jb_delay.mean;
|
||||
state->min_delay = jb->jb_delay.min;
|
||||
state->max_delay = jb->jb_delay.max;
|
||||
state->dev_delay = pj_math_stat_get_stddev(&jb->jb_delay);
|
||||
|
||||
|
||||
state->avg_burst = jb->jb_burst.mean;
|
||||
state->empty = jb->jb_empty;
|
||||
state->discard = jb->jb_discard;
|
||||
|
@ -1149,8 +1150,8 @@ PJ_DEF(pj_status_t) pjmedia_jbuf_get_state( const pjmedia_jbuf *jb,
|
|||
|
||||
PJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb,
|
||||
unsigned offset,
|
||||
const void **frame,
|
||||
pj_size_t *size,
|
||||
const void **frame,
|
||||
pj_size_t *size,
|
||||
char *p_frm_type,
|
||||
pj_uint32_t *bit_info,
|
||||
pj_uint32_t *ts,
|
||||
|
@ -1170,7 +1171,7 @@ PJ_DEF(void) pjmedia_jbuf_peek_frame( pjmedia_jbuf *jb,
|
|||
}
|
||||
|
||||
|
||||
PJ_DEF(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,
|
||||
PJ_DEF(unsigned) pjmedia_jbuf_remove_frame(pjmedia_jbuf *jb,
|
||||
unsigned frame_cnt)
|
||||
{
|
||||
unsigned count, last_discard_num;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <pjmedia/stream.h>
|
||||
#include <pjmedia/errno.h>
|
||||
|
@ -184,16 +184,16 @@ struct pjmedia_stream
|
|||
* This happens for example with G.722 and MPEG audio codecs.
|
||||
*/
|
||||
pj_bool_t has_g722_mpeg_bug;
|
||||
/**< Flag to specify whether
|
||||
normalization process
|
||||
/**< Flag to specify whether
|
||||
normalization process
|
||||
is needed */
|
||||
unsigned rtp_tx_ts_len_per_pkt;
|
||||
/**< Normalized ts length per packet
|
||||
transmitted according to
|
||||
transmitted according to
|
||||
'erroneous' definition */
|
||||
unsigned rtp_rx_ts_len_per_frame;
|
||||
/**< Normalized ts length per frame
|
||||
received according to
|
||||
received according to
|
||||
'erroneous' definition */
|
||||
unsigned rtp_rx_last_cnt;/**< Nb of frames in last pkt */
|
||||
unsigned rtp_rx_check_cnt;
|
||||
|
@ -202,11 +202,11 @@ struct pjmedia_stream
|
|||
#endif
|
||||
|
||||
#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
|
||||
pj_uint32_t rtcp_xr_last_tx; /**< RTCP XR tx time
|
||||
pj_uint32_t rtcp_xr_last_tx; /**< RTCP XR tx time
|
||||
in timestamp. */
|
||||
pj_uint32_t rtcp_xr_interval; /**< Interval, in timestamp. */
|
||||
pj_sockaddr rtcp_xr_dest; /**< Additional remote RTCP XR
|
||||
dest. If sin_family is
|
||||
pj_sockaddr rtcp_xr_dest; /**< Additional remote RTCP XR
|
||||
dest. If sin_family is
|
||||
zero, it will be ignored*/
|
||||
unsigned rtcp_xr_dest_len; /**< Length of RTCP XR dest
|
||||
address */
|
||||
|
@ -230,8 +230,8 @@ struct pjmedia_stream
|
|||
|
||||
|
||||
/* RFC 2833 digit */
|
||||
static const char digitmap[16] = { '0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
static const char digitmap[16] = { '0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', '*', '#',
|
||||
'A', 'B', 'C', 'D'};
|
||||
|
||||
|
@ -284,7 +284,7 @@ PJ_INLINE(int) trace_jb_print_timestamp(char **buf, pj_ssize_t len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
PJ_INLINE(int) trace_jb_print_state(pjmedia_stream *stream,
|
||||
PJ_INLINE(int) trace_jb_print_state(pjmedia_stream *stream,
|
||||
char **buf, pj_ssize_t len)
|
||||
{
|
||||
char *p = *buf;
|
||||
|
@ -459,7 +459,7 @@ static void send_keep_alive_packet(pjmedia_stream *stream)
|
|||
pkt_len);
|
||||
|
||||
#else
|
||||
|
||||
|
||||
PJ_UNUSED_ARG(stream);
|
||||
|
||||
#endif
|
||||
|
@ -497,12 +497,12 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
samples_required = PJMEDIA_PIA_SPF(&stream->port.info);
|
||||
samples_per_frame = stream->codec_param.info.frm_ptime *
|
||||
stream->codec_param.info.clock_rate *
|
||||
stream->codec_param.info.channel_cnt /
|
||||
stream->codec_param.info.channel_cnt /
|
||||
1000;
|
||||
p_out_samp = (pj_int16_t*) frame->buf;
|
||||
|
||||
for (samples_count=0; samples_count < samples_required;
|
||||
samples_count += samples_per_frame)
|
||||
for (samples_count=0; samples_count < samples_required;
|
||||
samples_count += samples_per_frame)
|
||||
{
|
||||
char frame_type;
|
||||
pj_size_t frame_size;
|
||||
|
@ -517,11 +517,11 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
#endif
|
||||
|
||||
if (frame_type == PJMEDIA_JB_MISSING_FRAME) {
|
||||
|
||||
|
||||
/* Activate PLC */
|
||||
if (stream->codec->op->recover &&
|
||||
if (stream->codec->op->recover &&
|
||||
stream->codec_param.setting.plc &&
|
||||
stream->plc_cnt < stream->max_plc_cnt)
|
||||
stream->plc_cnt < stream->max_plc_cnt)
|
||||
{
|
||||
pjmedia_frame frame_out;
|
||||
|
||||
|
@ -560,16 +560,16 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
|
||||
/* Jitter buffer is empty. If this is the first "empty" state,
|
||||
* activate PLC to smoothen the fade-out, otherwise zero
|
||||
* the frame.
|
||||
* the frame.
|
||||
*/
|
||||
//Using this "if" will only invoke PLC for the first packet
|
||||
//lost and not the subsequent ones.
|
||||
//if (frame_type != stream->jb_last_frm) {
|
||||
if (1) {
|
||||
/* Activate PLC to smoothen the missing frame */
|
||||
if (stream->codec->op->recover &&
|
||||
if (stream->codec->op->recover &&
|
||||
stream->codec_param.setting.plc &&
|
||||
stream->plc_cnt < stream->max_plc_cnt)
|
||||
stream->plc_cnt < stream->max_plc_cnt)
|
||||
{
|
||||
pjmedia_frame frame_out;
|
||||
|
||||
|
@ -589,7 +589,7 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
stream->plc_cnt < stream->max_plc_cnt);
|
||||
|
||||
with_plc = ", plc invoked";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (samples_count < samples_required) {
|
||||
|
@ -603,8 +603,8 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
|
||||
/* Report changing frame type event */
|
||||
pjmedia_jbuf_get_state(stream->jb, &jb_state);
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer empty (prefetch=%d)%s",
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer empty (prefetch=%d)%s",
|
||||
jb_state.prefetch, with_plc));
|
||||
|
||||
stream->jb_last_frm = frame_type;
|
||||
|
@ -622,9 +622,9 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME);
|
||||
|
||||
/* Always activate PLC when it's available.. */
|
||||
if (stream->codec->op->recover &&
|
||||
if (stream->codec->op->recover &&
|
||||
stream->codec_param.setting.plc &&
|
||||
stream->plc_cnt < stream->max_plc_cnt)
|
||||
stream->plc_cnt < stream->max_plc_cnt)
|
||||
{
|
||||
pjmedia_frame frame_out;
|
||||
|
||||
|
@ -644,7 +644,7 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
stream->plc_cnt < stream->max_plc_cnt);
|
||||
|
||||
with_plc = ", plc invoked";
|
||||
}
|
||||
}
|
||||
|
||||
if (samples_count < samples_required) {
|
||||
pjmedia_zero_samples(p_out_samp + samples_count,
|
||||
|
@ -657,8 +657,8 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
|
||||
/* Report changing frame type event */
|
||||
pjmedia_jbuf_get_state(stream->jb, &jb_state);
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer is bufferring (prefetch=%d)%s",
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer is bufferring (prefetch=%d)%s",
|
||||
jb_state.prefetch, with_plc));
|
||||
|
||||
stream->jb_last_frm = frame_type;
|
||||
|
@ -683,19 +683,19 @@ static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
|
|||
frame_out.buf = p_out_samp + samples_count;
|
||||
frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE;
|
||||
status = pjmedia_codec_decode( stream->codec, &frame_in,
|
||||
(unsigned)frame_out.size,
|
||||
(unsigned)frame_out.size,
|
||||
&frame_out);
|
||||
if (status != 0) {
|
||||
LOGERR_((port->info.name.ptr, "codec decode() error",
|
||||
LOGERR_((port->info.name.ptr, "codec decode() error",
|
||||
status));
|
||||
|
||||
pjmedia_zero_samples(p_out_samp + samples_count,
|
||||
pjmedia_zero_samples(p_out_samp + samples_count,
|
||||
samples_per_frame);
|
||||
}
|
||||
|
||||
if (stream->jb_last_frm != frame_type) {
|
||||
/* Report changing frame type event */
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer starts returning normal frames "
|
||||
"(after %d empty/lost)",
|
||||
stream->jb_last_frm_cnt, stream->jb_last_frm));
|
||||
|
@ -752,7 +752,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
samples_required = PJMEDIA_PIA_SPF(&stream->port.info);
|
||||
samples_per_frame = stream->codec_param.info.frm_ptime *
|
||||
stream->codec_param.info.clock_rate *
|
||||
stream->codec_param.info.channel_cnt /
|
||||
stream->codec_param.info.channel_cnt /
|
||||
1000;
|
||||
|
||||
pj_bzero(f, sizeof(pjmedia_frame_ext));
|
||||
|
@ -773,7 +773,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
#if TRACE_JB
|
||||
trace_jb_get(stream, frame_type, frame_size);
|
||||
#endif
|
||||
|
||||
|
||||
/* Unlock jitter buffer mutex. */
|
||||
pj_mutex_unlock( stream->jb_mutex );
|
||||
|
||||
|
@ -790,7 +790,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
status = pjmedia_codec_decode( stream->codec, &frame_in,
|
||||
0, frame);
|
||||
if (status != PJ_SUCCESS) {
|
||||
LOGERR_((port->info.name.ptr, "codec decode() error",
|
||||
LOGERR_((port->info.name.ptr, "codec decode() error",
|
||||
status));
|
||||
pjmedia_frame_ext_append_subframe(f, NULL, 0,
|
||||
(pj_uint16_t)samples_per_frame);
|
||||
|
@ -798,7 +798,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
|
||||
if (stream->jb_last_frm != frame_type) {
|
||||
/* Report changing frame type event */
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer starts returning normal frames "
|
||||
"(after %d empty/lost)",
|
||||
stream->jb_last_frm_cnt, stream->jb_last_frm));
|
||||
|
@ -816,7 +816,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
if (stream->codec->op->recover) {
|
||||
status = pjmedia_codec_recover(stream->codec, 0, frame);
|
||||
}
|
||||
|
||||
|
||||
/* No PLC or PLC failed */
|
||||
if (!stream->codec->op->recover || status != PJ_SUCCESS) {
|
||||
pjmedia_frame_ext_append_subframe(f, NULL, 0,
|
||||
|
@ -839,8 +839,8 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
|
||||
/* Report changing frame type event */
|
||||
pjmedia_jbuf_get_state(stream->jb, &jb_state);
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer empty (prefetch=%d)",
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer empty (prefetch=%d)",
|
||||
jb_state.prefetch));
|
||||
|
||||
stream->jb_last_frm = frame_type;
|
||||
|
@ -858,7 +858,7 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
|
||||
/* Report changing frame type event */
|
||||
pjmedia_jbuf_get_state(stream->jb, &jb_state);
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Jitter buffer is bufferring (prefetch=%d)",
|
||||
jb_state.prefetch));
|
||||
|
||||
|
@ -878,23 +878,21 @@ static pj_status_t get_frame_ext( pjmedia_port *port, pjmedia_frame *frame)
|
|||
/*
|
||||
* Transmit DTMF
|
||||
*/
|
||||
static void create_dtmf_payload(pjmedia_stream *stream,
|
||||
static void create_dtmf_payload(pjmedia_stream *stream,
|
||||
struct pjmedia_frame *frame_out,
|
||||
int forced_last, int *first, int *last)
|
||||
{
|
||||
pjmedia_rtp_dtmf_event *event;
|
||||
struct dtmf *digit = &stream->tx_dtmf_buf[0];
|
||||
pj_uint32_t cur_ts;
|
||||
|
||||
pj_assert(sizeof(pjmedia_rtp_dtmf_event) == 4);
|
||||
|
||||
*first = *last = 0;
|
||||
|
||||
event = (pjmedia_rtp_dtmf_event*) frame_out->buf;
|
||||
cur_ts = pj_ntohl(stream->enc->rtp.out_hdr.ts);
|
||||
|
||||
if (digit->duration == 0) {
|
||||
PJ_LOG(5,(stream->port.info.name.ptr, "Sending DTMF digit id %c",
|
||||
PJ_LOG(5,(stream->port.info.name.ptr, "Sending DTMF digit id %c",
|
||||
digitmap[digit->event]));
|
||||
*first = 1;
|
||||
}
|
||||
|
@ -987,14 +985,14 @@ static pj_status_t send_rtcp(pjmedia_stream *stream,
|
|||
|
||||
/* Update RTCP XR with current JB states */
|
||||
pjmedia_jbuf_get_state(stream->jb, &jb_state);
|
||||
|
||||
|
||||
i = jb_state.avg_delay;
|
||||
status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
PJMEDIA_RTCP_XR_INFO_JB_NOM, i);
|
||||
pj_assert(status == PJ_SUCCESS);
|
||||
|
||||
i = jb_state.max_delay;
|
||||
status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
status = pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
PJMEDIA_RTCP_XR_INFO_JB_MAX, i);
|
||||
pj_assert(status == PJ_SUCCESS);
|
||||
|
||||
|
@ -1007,9 +1005,9 @@ static pj_status_t send_rtcp(pjmedia_stream *stream,
|
|||
|
||||
/* Send the RTCP XR to third-party destination if specified */
|
||||
if (stream->rtcp_xr_dest_len) {
|
||||
pjmedia_transport_send_rtcp2(stream->transport,
|
||||
pjmedia_transport_send_rtcp2(stream->transport,
|
||||
&stream->rtcp_xr_dest,
|
||||
stream->rtcp_xr_dest_len,
|
||||
stream->rtcp_xr_dest_len,
|
||||
xr_pkt, xr_len);
|
||||
}
|
||||
|
||||
|
@ -1049,13 +1047,13 @@ static pj_status_t send_rtcp(pjmedia_stream *stream,
|
|||
*/
|
||||
static void check_tx_rtcp(pjmedia_stream *stream, pj_uint32_t timestamp)
|
||||
{
|
||||
/* Note that timestamp may represent local or remote timestamp,
|
||||
/* Note that timestamp may represent local or remote timestamp,
|
||||
* depending on whether this function is called from put_frame()
|
||||
* or get_frame().
|
||||
*/
|
||||
|
||||
if (stream->rtcp_last_tx == 0) {
|
||||
|
||||
|
||||
stream->rtcp_last_tx = timestamp;
|
||||
|
||||
} else if (timestamp - stream->rtcp_last_tx >= stream->rtcp_interval) {
|
||||
|
@ -1066,7 +1064,7 @@ static void check_tx_rtcp(pjmedia_stream *stream, pj_uint32_t timestamp)
|
|||
if (stream->rtcp.xr_enabled) {
|
||||
if (stream->rtcp_xr_last_tx == 0) {
|
||||
stream->rtcp_xr_last_tx = timestamp;
|
||||
} else if (timestamp - stream->rtcp_xr_last_tx >=
|
||||
} else if (timestamp - stream->rtcp_xr_last_tx >=
|
||||
stream->rtcp_xr_interval)
|
||||
{
|
||||
with_xr = PJ_TRUE;
|
||||
|
@ -1130,7 +1128,7 @@ static void rebuffer(pjmedia_stream *stream,
|
|||
}
|
||||
|
||||
/* How many samples are needed */
|
||||
count = stream->codec_param.info.enc_ptime *
|
||||
count = stream->codec_param.info.enc_ptime *
|
||||
PJMEDIA_PIA_SRATE(&stream->port.info) / 1000;
|
||||
|
||||
/* See if we have enough samples */
|
||||
|
@ -1153,7 +1151,7 @@ static void rebuffer(pjmedia_stream *stream,
|
|||
/**
|
||||
* put_frame_imp()
|
||||
*/
|
||||
static pj_status_t put_frame_imp( pjmedia_port *port,
|
||||
static pj_status_t put_frame_imp( pjmedia_port *port,
|
||||
pjmedia_frame *frame )
|
||||
{
|
||||
pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
|
||||
|
@ -1174,7 +1172,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
{
|
||||
pj_uint32_t dtx_duration;
|
||||
|
||||
dtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent,
|
||||
dtx_duration = pj_timestamp_diff32(&stream->last_frm_ts_sent,
|
||||
&frame->timestamp);
|
||||
if (dtx_duration >
|
||||
PJMEDIA_STREAM_KA_INTERVAL * PJMEDIA_PIA_SRATE(&stream->port.info))
|
||||
|
@ -1193,7 +1191,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
|
||||
/* Number of samples in the frame */
|
||||
if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO)
|
||||
ts_len = ((unsigned)frame->size >> 1) /
|
||||
ts_len = ((unsigned)frame->size >> 1) /
|
||||
stream->codec_param.info.channel_cnt;
|
||||
else if (frame->type == PJMEDIA_FRAME_TYPE_EXTENDED)
|
||||
ts_len = PJMEDIA_PIA_SPF(&stream->port.info) /
|
||||
|
@ -1205,7 +1203,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
stream->tx_duration += ts_len;
|
||||
|
||||
#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
|
||||
/* Handle special case for audio codec with RTP timestamp inconsistence
|
||||
/* Handle special case for audio codec with RTP timestamp inconsistence
|
||||
* e.g: G722, MPEG audio.
|
||||
*/
|
||||
if (stream->has_g722_mpeg_bug)
|
||||
|
@ -1224,7 +1222,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
samples_per_frame = stream->enc_samples_per_pkt;
|
||||
|
||||
|
||||
/* If we have DTMF digits in the queue, transmit the digits.
|
||||
/* If we have DTMF digits in the queue, transmit the digits.
|
||||
* Otherwise encode the PCM buffer.
|
||||
*/
|
||||
if (stream->tx_dtmf_count) {
|
||||
|
@ -1234,17 +1232,17 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
|
||||
/* Encapsulate into RTP packet. Note that:
|
||||
* - RTP marker should be set on the beginning of a new event
|
||||
* - RTP timestamp is constant for the same packet.
|
||||
* - RTP timestamp is constant for the same packet.
|
||||
*/
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
stream->tx_event_pt, first,
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
stream->tx_event_pt, first,
|
||||
(int)frame_out.size,
|
||||
(first ? rtp_ts_len : 0),
|
||||
(const void**)&rtphdr,
|
||||
(first ? rtp_ts_len : 0),
|
||||
(const void**)&rtphdr,
|
||||
&rtphdrlen);
|
||||
|
||||
if (last) {
|
||||
/* This is the last packet for the event.
|
||||
/* This is the last packet for the event.
|
||||
* Increment the RTP timestamp of the RTP session, for next
|
||||
* RTP packets.
|
||||
*/
|
||||
|
@ -1271,7 +1269,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
stream->codec_param.info.frm_ptime *
|
||||
stream->codec_param.info.channel_cnt *
|
||||
stream->codec_param.info.clock_rate/1000 <
|
||||
PJ_ARRAY_SIZE(zero_frame))
|
||||
PJ_ARRAY_SIZE(zero_frame))
|
||||
{
|
||||
pjmedia_frame silence_frame;
|
||||
|
||||
|
@ -1282,23 +1280,23 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
stream->codec_param.info.clock_rate / 1000;
|
||||
silence_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
|
||||
silence_frame.timestamp.u32.lo = pj_ntohl(stream->enc->rtp.out_hdr.ts);
|
||||
|
||||
|
||||
/* Encode! */
|
||||
status = pjmedia_codec_encode( stream->codec, &silence_frame,
|
||||
channel->out_pkt_size -
|
||||
channel->out_pkt_size -
|
||||
sizeof(pjmedia_rtp_hdr),
|
||||
&frame_out);
|
||||
if (status != PJ_SUCCESS) {
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
"Codec encode() error", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Encapsulate. */
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
channel->pt, 0,
|
||||
(int)frame_out.size, rtp_ts_len,
|
||||
(const void**)&rtphdr,
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
channel->pt, 0,
|
||||
(int)frame_out.size, rtp_ts_len,
|
||||
(const void**)&rtphdr,
|
||||
&rtphdrlen);
|
||||
|
||||
|
||||
|
@ -1308,41 +1306,41 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
(frame->type == PJMEDIA_FRAME_TYPE_EXTENDED))
|
||||
{
|
||||
/* Encode! */
|
||||
status = pjmedia_codec_encode( stream->codec, frame,
|
||||
channel->out_pkt_size -
|
||||
status = pjmedia_codec_encode( stream->codec, frame,
|
||||
channel->out_pkt_size -
|
||||
sizeof(pjmedia_rtp_hdr),
|
||||
&frame_out);
|
||||
if (status != PJ_SUCCESS) {
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
"Codec encode() error", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Encapsulate. */
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
channel->pt, 0,
|
||||
(int)frame_out.size, rtp_ts_len,
|
||||
(const void**)&rtphdr,
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
channel->pt, 0,
|
||||
(int)frame_out.size, rtp_ts_len,
|
||||
(const void**)&rtphdr,
|
||||
&rtphdrlen);
|
||||
|
||||
} else {
|
||||
|
||||
/* Just update RTP session's timestamp. */
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
0, 0,
|
||||
0, rtp_ts_len,
|
||||
(const void**)&rtphdr,
|
||||
status = pjmedia_rtp_encode_rtp( &channel->rtp,
|
||||
0, 0,
|
||||
0, rtp_ts_len,
|
||||
(const void**)&rtphdr,
|
||||
&rtphdrlen);
|
||||
|
||||
}
|
||||
|
||||
if (status != PJ_SUCCESS) {
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
"RTP encode_rtp() error", status));
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Check if now is the time to transmit RTCP SR/RR report.
|
||||
/* Check if now is the time to transmit RTCP SR/RR report.
|
||||
* We only do this when stream direction is not "decoding only", because
|
||||
* when it is, check_tx_rtcp() will be handled by get_frame().
|
||||
*/
|
||||
|
@ -1413,7 +1411,7 @@ static pj_status_t put_frame_imp( pjmedia_port *port,
|
|||
* to transmit. This function encodes the PCM frame, pack it into
|
||||
* RTP packet, and transmit to peer.
|
||||
*/
|
||||
static pj_status_t put_frame( pjmedia_port *port,
|
||||
static pj_status_t put_frame( pjmedia_port *port,
|
||||
pjmedia_frame *frame )
|
||||
{
|
||||
pjmedia_stream *stream = (pjmedia_stream*) port->port_data.pdata;
|
||||
|
@ -1461,7 +1459,7 @@ static pj_status_t put_frame( pjmedia_port *port,
|
|||
* after transmitting for VAD_SUSPEND_SEC seconds.
|
||||
*/
|
||||
if (stream->vad_enabled != stream->codec_param.setting.vad &&
|
||||
(stream->tx_duration - stream->ts_vad_disabled) >
|
||||
(stream->tx_duration - stream->ts_vad_disabled) >
|
||||
PJMEDIA_PIA_SRATE(&stream->port.info) *
|
||||
PJMEDIA_STREAM_VAD_SUSPEND_MSEC / 1000)
|
||||
{
|
||||
|
@ -1478,7 +1476,7 @@ static pj_status_t put_frame( pjmedia_port *port,
|
|||
pjmedia_frame tmp_rebuffer_frame;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
|
||||
/* Copy original frame to temporary frame since we need
|
||||
/* Copy original frame to temporary frame since we need
|
||||
* to modify it.
|
||||
*/
|
||||
pj_memcpy(&tmp_rebuffer_frame, frame, sizeof(pjmedia_frame));
|
||||
|
@ -1545,7 +1543,7 @@ static void dump_bin(const char *buf, unsigned len)
|
|||
/*
|
||||
* Handle incoming DTMF digits.
|
||||
*/
|
||||
static void handle_incoming_dtmf( pjmedia_stream *stream,
|
||||
static void handle_incoming_dtmf( pjmedia_stream *stream,
|
||||
const void *payload, unsigned payloadlen)
|
||||
{
|
||||
pjmedia_rtp_dtmf_event *event = (pjmedia_rtp_dtmf_event*) payload;
|
||||
|
@ -1571,7 +1569,7 @@ static void handle_incoming_dtmf( pjmedia_stream *stream,
|
|||
|
||||
/* Ignore unknown event. */
|
||||
if (event->event > 15) {
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
PJ_LOG(5,(stream->port.info.name.ptr,
|
||||
"Ignored RTP pkt with bad DTMF event %d",
|
||||
event->event));
|
||||
return;
|
||||
|
@ -1590,7 +1588,7 @@ static void handle_incoming_dtmf( pjmedia_stream *stream,
|
|||
*/
|
||||
if (stream->dtmf_cb) {
|
||||
|
||||
stream->dtmf_cb(stream, stream->dtmf_cb_user_data,
|
||||
stream->dtmf_cb(stream, stream->dtmf_cb_user_data,
|
||||
digitmap[event->event]);
|
||||
|
||||
} else {
|
||||
|
@ -1600,7 +1598,7 @@ static void handle_incoming_dtmf( pjmedia_stream *stream,
|
|||
pj_mutex_lock(stream->jb_mutex);
|
||||
if (stream->rx_dtmf_count >= PJ_ARRAY_SIZE(stream->rx_dtmf_buf)) {
|
||||
/* DTMF digits overflow. Discard the oldest digit. */
|
||||
pj_array_erase(stream->rx_dtmf_buf,
|
||||
pj_array_erase(stream->rx_dtmf_buf,
|
||||
sizeof(stream->rx_dtmf_buf[0]),
|
||||
stream->rx_dtmf_count, 0);
|
||||
--stream->rx_dtmf_count;
|
||||
|
@ -1613,9 +1611,9 @@ static void handle_incoming_dtmf( pjmedia_stream *stream,
|
|||
|
||||
/*
|
||||
* This callback is called by stream transport on receipt of packets
|
||||
* in the RTP socket.
|
||||
* in the RTP socket.
|
||||
*/
|
||||
static void on_rx_rtp( void *data,
|
||||
static void on_rx_rtp( void *data,
|
||||
void *pkt,
|
||||
pj_ssize_t bytes_read)
|
||||
|
||||
|
@ -1631,7 +1629,7 @@ static void on_rx_rtp( void *data,
|
|||
|
||||
/* Check for errors */
|
||||
if (bytes_read < 0) {
|
||||
LOGERR_((stream->port.info.name.ptr, "RTP recv() error",
|
||||
LOGERR_((stream->port.info.name.ptr, "RTP recv() error",
|
||||
(pj_status_t)-bytes_read));
|
||||
return;
|
||||
}
|
||||
|
@ -1659,9 +1657,9 @@ static void on_rx_rtp( void *data,
|
|||
pjmedia_rtp_session_update2(&channel->rtp, hdr, &seq_st,
|
||||
hdr->pt != stream->rx_event_pt);
|
||||
if (seq_st.status.value) {
|
||||
TRC_ ((stream->port.info.name.ptr,
|
||||
TRC_ ((stream->port.info.name.ptr,
|
||||
"RTP status: badpt=%d, badssrc=%d, dup=%d, "
|
||||
"outorder=%d, probation=%d, restart=%d",
|
||||
"outorder=%d, probation=%d, restart=%d",
|
||||
seq_st.status.flag.badpt,
|
||||
seq_st.status.flag.badssrc,
|
||||
seq_st.status.flag.dup,
|
||||
|
@ -1736,8 +1734,8 @@ static void on_rx_rtp( void *data,
|
|||
status = pjmedia_codec_parse(stream->codec, (void*)payload,
|
||||
payloadlen, &ts, &count, frames);
|
||||
if (status != PJ_SUCCESS) {
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
"Codec parse() error",
|
||||
LOGERR_((stream->port.info.name.ptr,
|
||||
"Codec parse() error",
|
||||
status));
|
||||
count = 0;
|
||||
}
|
||||
|
@ -1745,17 +1743,17 @@ static void on_rx_rtp( void *data,
|
|||
#if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
|
||||
/* This code is used to learn the samples per frame value that is put
|
||||
* by remote endpoint, for codecs with inconsistent clock rate such
|
||||
* as G.722 or MPEG audio. We need to learn the samples per frame
|
||||
* as G.722 or MPEG audio. We need to learn the samples per frame
|
||||
* value as it is used as divider when inserting frames into the
|
||||
* jitter buffer.
|
||||
*/
|
||||
if (stream->has_g722_mpeg_bug) {
|
||||
if (stream->rtp_rx_check_cnt) {
|
||||
/* Make sure the detection performed only on two consecutive
|
||||
/* Make sure the detection performed only on two consecutive
|
||||
* packets with valid RTP sequence and no wrapped timestamp.
|
||||
*/
|
||||
if (seq_st.diff == 1 && stream->rtp_rx_last_ts &&
|
||||
ts.u64 > stream->rtp_rx_last_ts &&
|
||||
if (seq_st.diff == 1 && stream->rtp_rx_last_ts &&
|
||||
ts.u64 > stream->rtp_rx_last_ts &&
|
||||
stream->rtp_rx_last_cnt > 0)
|
||||
{
|
||||
unsigned peer_frm_ts_diff;
|
||||
|
@ -1767,8 +1765,8 @@ static void on_rx_rtp( void *data,
|
|||
PJMEDIA_PIA_CCNT(&stream->port.info);
|
||||
|
||||
/* Get remote frame timestamp span */
|
||||
peer_frm_ts_diff =
|
||||
((pj_uint32_t)ts.u64-stream->rtp_rx_last_ts) /
|
||||
peer_frm_ts_diff =
|
||||
((pj_uint32_t)ts.u64-stream->rtp_rx_last_ts) /
|
||||
stream->rtp_rx_last_cnt;
|
||||
|
||||
/* Possibilities remote's samples per frame for G.722
|
||||
|
@ -1777,7 +1775,7 @@ static void on_rx_rtp( void *data,
|
|||
* of silence frames.
|
||||
*/
|
||||
if (stream->codec_param.info.pt == PJMEDIA_RTP_PT_G722 &&
|
||||
(peer_frm_ts_diff == frm_ts_span ||
|
||||
(peer_frm_ts_diff == frm_ts_span ||
|
||||
peer_frm_ts_diff == (frm_ts_span>>1)))
|
||||
{
|
||||
if (peer_frm_ts_diff < stream->rtp_rx_ts_len_per_frame)
|
||||
|
@ -1789,9 +1787,9 @@ static void on_rx_rtp( void *data,
|
|||
|
||||
if (--stream->rtp_rx_check_cnt == 0) {
|
||||
PJ_LOG(4, (THIS_FILE, "G722 codec used, remote"
|
||||
" samples per frame detected = %d",
|
||||
" samples per frame detected = %d",
|
||||
stream->rtp_rx_ts_len_per_frame));
|
||||
|
||||
|
||||
/* Reset jitter buffer once detection done */
|
||||
pjmedia_jbuf_reset(stream->jb);
|
||||
}
|
||||
|
@ -1810,12 +1808,12 @@ static void on_rx_rtp( void *data,
|
|||
}
|
||||
|
||||
} else {
|
||||
ts_span = stream->codec_param.info.frm_ptime *
|
||||
ts_span = stream->codec_param.info.frm_ptime *
|
||||
stream->codec_param.info.clock_rate /
|
||||
1000;
|
||||
}
|
||||
#else
|
||||
ts_span = stream->codec_param.info.frm_ptime *
|
||||
ts_span = stream->codec_param.info.frm_ptime *
|
||||
stream->codec_param.info.clock_rate /
|
||||
1000;
|
||||
#endif
|
||||
|
@ -1841,7 +1839,7 @@ static void on_rx_rtp( void *data,
|
|||
|
||||
|
||||
/* Check if now is the time to transmit RTCP SR/RR report.
|
||||
* We only do this when stream direction is "decoding only",
|
||||
* We only do this when stream direction is "decoding only",
|
||||
* because otherwise check_tx_rtcp() will be handled by put_frame()
|
||||
*/
|
||||
if (stream->dir == PJMEDIA_DIR_DECODING) {
|
||||
|
@ -1849,7 +1847,7 @@ static void on_rx_rtp( void *data,
|
|||
}
|
||||
|
||||
if (status != 0) {
|
||||
LOGERR_((stream->port.info.name.ptr, "Jitter buffer put() error",
|
||||
LOGERR_((stream->port.info.name.ptr, "Jitter buffer put() error",
|
||||
status));
|
||||
pkt_discarded = PJ_TRUE;
|
||||
goto on_return;
|
||||
|
@ -1879,17 +1877,17 @@ on_return:
|
|||
|
||||
/*
|
||||
* This callback is called by stream transport on receipt of packets
|
||||
* in the RTCP socket.
|
||||
* in the RTCP socket.
|
||||
*/
|
||||
static void on_rx_rtcp( void *data,
|
||||
void *pkt,
|
||||
void *pkt,
|
||||
pj_ssize_t bytes_read)
|
||||
{
|
||||
pjmedia_stream *stream = (pjmedia_stream*) data;
|
||||
|
||||
/* Check for errors */
|
||||
if (bytes_read < 0) {
|
||||
LOGERR_((stream->port.info.name.ptr, "RTCP recv() error",
|
||||
LOGERR_((stream->port.info.name.ptr, "RTCP recv() error",
|
||||
(pj_status_t)-bytes_read));
|
||||
return;
|
||||
}
|
||||
|
@ -1910,7 +1908,7 @@ static pj_status_t create_channel( pj_pool_t *pool,
|
|||
{
|
||||
pjmedia_channel *channel;
|
||||
pj_status_t status;
|
||||
|
||||
|
||||
/* Allocate memory for channel descriptor */
|
||||
|
||||
channel = PJ_POOL_ZALLOC_T(pool, pjmedia_channel);
|
||||
|
@ -1923,13 +1921,13 @@ static pj_status_t create_channel( pj_pool_t *pool,
|
|||
channel->paused = 1;
|
||||
channel->pt = pt;
|
||||
|
||||
|
||||
|
||||
/* Allocate buffer for outgoing packet. */
|
||||
|
||||
if (param->type == PJMEDIA_TYPE_AUDIO) {
|
||||
channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) +
|
||||
stream->codec_param.info.max_bps *
|
||||
PJMEDIA_MAX_FRAME_DURATION_MS /
|
||||
channel->out_pkt_size = sizeof(pjmedia_rtp_hdr) +
|
||||
stream->codec_param.info.max_bps *
|
||||
PJMEDIA_MAX_FRAME_DURATION_MS /
|
||||
8 / 1000;
|
||||
if (channel->out_pkt_size > PJMEDIA_MAX_MTU -
|
||||
PJMEDIA_STREAM_RESV_PAYLOAD_LEN)
|
||||
|
@ -2077,8 +2075,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
if (info->param)
|
||||
stream->codec_param = *info->param;
|
||||
else {
|
||||
status = pjmedia_codec_mgr_get_default_param(stream->codec_mgr,
|
||||
&info->fmt,
|
||||
status = pjmedia_codec_mgr_get_default_param(stream->codec_mgr,
|
||||
&info->fmt,
|
||||
&stream->codec_param);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto err_cleanup;
|
||||
|
@ -2136,7 +2134,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
|
||||
/* If encoder and decoder's ptime are asymmetric, then we need to
|
||||
* create buffer on the encoder side. This could happen for example
|
||||
* with iLBC
|
||||
* with iLBC
|
||||
*/
|
||||
if (stream->codec_param.info.enc_ptime!=0 &&
|
||||
stream->codec_param.info.enc_ptime!=stream->codec_param.info.frm_ptime)
|
||||
|
@ -2184,7 +2182,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
if (stream->codec_param.info.max_rx_frame_size > 0) {
|
||||
stream->frame_size = stream->codec_param.info.max_rx_frame_size;
|
||||
} else {
|
||||
stream->frame_size = stream->codec_param.info.max_bps *
|
||||
stream->frame_size = stream->codec_param.info.max_bps *
|
||||
stream->codec_param.info.frm_ptime / 8 / 1000;
|
||||
if ((stream->codec_param.info.max_bps *
|
||||
stream->codec_param.info.frm_ptime) % 8000 != 0)
|
||||
|
@ -2217,7 +2215,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
|
||||
/* Init jitter buffer parameters: */
|
||||
if (info->jb_max >= stream->codec_param.info.frm_ptime)
|
||||
jb_max = (info->jb_max + stream->codec_param.info.frm_ptime - 1) /
|
||||
jb_max = (info->jb_max + stream->codec_param.info.frm_ptime - 1) /
|
||||
stream->codec_param.info.frm_ptime;
|
||||
else
|
||||
jb_max = 500 / stream->codec_param.info.frm_ptime;
|
||||
|
@ -2242,7 +2240,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
|
||||
/* Create jitter buffer */
|
||||
status = pjmedia_jbuf_create(pool, &stream->port.info.name,
|
||||
stream->frame_size,
|
||||
stream->frame_size,
|
||||
stream->codec_param.info.frm_ptime,
|
||||
jb_max, &stream->jb);
|
||||
if (status != PJ_SUCCESS)
|
||||
|
@ -2254,7 +2252,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
|
||||
/* Create decoder channel: */
|
||||
|
||||
status = create_channel( pool, stream, PJMEDIA_DIR_DECODING,
|
||||
status = create_channel( pool, stream, PJMEDIA_DIR_DECODING,
|
||||
info->rx_pt, info, &stream->dec);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto err_cleanup;
|
||||
|
@ -2262,7 +2260,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
|
||||
/* Create encoder channel: */
|
||||
|
||||
status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING,
|
||||
status = create_channel( pool, stream, PJMEDIA_DIR_ENCODING,
|
||||
info->tx_pt, info, &stream->enc);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto err_cleanup;
|
||||
|
@ -2315,9 +2313,9 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
stream->out_rtcp_pkt = pj_pool_alloc(pool, stream->out_rtcp_pkt_size);
|
||||
|
||||
/* Only attach transport when stream is ready. */
|
||||
status = pjmedia_transport_attach(tp, stream, &info->rem_addr,
|
||||
&info->rem_rtcp,
|
||||
pj_sockaddr_get_len(&info->rem_addr),
|
||||
status = pjmedia_transport_attach(tp, stream, &info->rem_addr,
|
||||
&info->rem_rtcp,
|
||||
pj_sockaddr_get_len(&info->rem_addr),
|
||||
&on_rx_rtp, &on_rx_rtcp);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto err_cleanup;
|
||||
|
@ -2335,8 +2333,8 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
if (info->rtcp_xr_interval != 0)
|
||||
stream->rtcp_xr_interval = info->rtcp_xr_interval;
|
||||
else
|
||||
stream->rtcp_xr_interval = (PJMEDIA_RTCP_INTERVAL +
|
||||
(pj_rand() % 8000)) *
|
||||
stream->rtcp_xr_interval = (PJMEDIA_RTCP_INTERVAL +
|
||||
(pj_rand() % 8000)) *
|
||||
info->fmt.clock_rate / 1000;
|
||||
|
||||
/* Additional third-party RTCP XR destination */
|
||||
|
@ -2348,19 +2346,19 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
|
||||
/* jitter buffer adaptive info */
|
||||
i = PJMEDIA_RTCP_XR_JB_ADAPTIVE;
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
PJMEDIA_RTCP_XR_INFO_CONF_JBA,
|
||||
i);
|
||||
|
||||
/* Jitter buffer aggressiveness info (estimated) */
|
||||
i = 7;
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
PJMEDIA_RTCP_XR_INFO_CONF_JBR,
|
||||
i);
|
||||
|
||||
/* Jitter buffer absolute maximum delay */
|
||||
i = jb_max * stream->codec_param.info.frm_ptime;
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
PJMEDIA_RTCP_XR_INFO_JB_ABS_MAX,
|
||||
i);
|
||||
|
||||
|
@ -2373,7 +2371,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
#else
|
||||
i = PJMEDIA_RTCP_XR_PLC_DIS;
|
||||
#endif
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
pjmedia_rtcp_xr_update_info(&stream->rtcp.xr_session,
|
||||
PJMEDIA_RTCP_XR_INFO_CONF_PLC,
|
||||
i);
|
||||
}
|
||||
|
@ -2395,13 +2393,13 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
char trace_name[PJ_MAXPATH];
|
||||
pj_ssize_t len;
|
||||
|
||||
pj_ansi_snprintf(trace_name, sizeof(trace_name),
|
||||
pj_ansi_snprintf(trace_name, sizeof(trace_name),
|
||||
TRACE_JB_PATH_PREFIX "%s.csv",
|
||||
stream->port.info.name.ptr);
|
||||
status = pj_file_open(pool, trace_name, PJ_O_WRONLY, &stream->trace_jb_fd);
|
||||
if (status != PJ_SUCCESS) {
|
||||
stream->trace_jb_fd = TRACE_JB_INVALID_FD;
|
||||
PJ_LOG(3,(THIS_FILE, "Failed creating RTP trace file '%s'",
|
||||
PJ_LOG(3,(THIS_FILE, "Failed creating RTP trace file '%s'",
|
||||
trace_name));
|
||||
} else {
|
||||
stream->trace_jb_buf = (char*)pj_pool_alloc(pool, PJ_LOG_MAX_SIZE);
|
||||
|
@ -2489,7 +2487,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
|
|||
}
|
||||
}
|
||||
|
||||
/* Detach from transport
|
||||
/* Detach from transport
|
||||
* MUST NOT hold stream mutex while detaching from transport, as
|
||||
* it may cause deadlock. See ticket #460 for the details.
|
||||
*/
|
||||
|
@ -2512,7 +2510,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
|
|||
}
|
||||
|
||||
/* Free mutex */
|
||||
|
||||
|
||||
if (stream->jb_mutex) {
|
||||
pj_mutex_destroy(stream->jb_mutex);
|
||||
stream->jb_mutex = NULL;
|
||||
|
@ -2723,9 +2721,9 @@ PJ_DEF(pj_status_t) pjmedia_stream_dial_dtmf( pjmedia_stream *stream,
|
|||
if (stream->tx_event_pt < 0) {
|
||||
return PJMEDIA_RTP_EREMNORFC2833;
|
||||
}
|
||||
|
||||
|
||||
pj_mutex_lock(stream->jb_mutex);
|
||||
|
||||
|
||||
if (stream->tx_dtmf_count+digit_char->slen >=
|
||||
(long)PJ_ARRAY_SIZE(stream->tx_dtmf_buf))
|
||||
{
|
||||
|
@ -2734,7 +2732,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_dial_dtmf( pjmedia_stream *stream,
|
|||
int i;
|
||||
|
||||
/* convert ASCII digits into payload type first, to make sure
|
||||
* that all digits are valid.
|
||||
* that all digits are valid.
|
||||
*/
|
||||
for (i=0; i<digit_char->slen; ++i) {
|
||||
unsigned pt;
|
||||
|
@ -2743,7 +2741,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_dial_dtmf( pjmedia_stream *stream,
|
|||
if (dig >= '0' && dig <= '9')
|
||||
{
|
||||
pt = dig - '0';
|
||||
}
|
||||
}
|
||||
else if (dig >= 'a' && dig <= 'd')
|
||||
{
|
||||
pt = dig - 'a' + 12;
|
||||
|
@ -2829,9 +2827,9 @@ PJ_DEF(pj_status_t) pjmedia_stream_get_dtmf( pjmedia_stream *stream,
|
|||
* Set callback to be called upon receiving DTMF digits.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pjmedia_stream_set_dtmf_callback(pjmedia_stream *stream,
|
||||
void (*cb)(pjmedia_stream*,
|
||||
void *user_data,
|
||||
int digit),
|
||||
void (*cb)(pjmedia_stream*,
|
||||
void *user_data,
|
||||
int digit),
|
||||
void *user_data)
|
||||
{
|
||||
PJ_ASSERT_RETURN(stream, PJ_EINVAL);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <pjmedia/transport_srtp.h>
|
||||
|
@ -45,7 +45,7 @@
|
|||
/* Maximum SRTP crypto key length */
|
||||
#define MAX_KEY_LEN 128
|
||||
|
||||
/* Initial value of probation counter. When probation counter > 0,
|
||||
/* Initial value of probation counter. When probation counter > 0,
|
||||
* it means SRTP is in probation state, and it may restart when
|
||||
* srtp_unprotect() returns err_status_replay_*
|
||||
*/
|
||||
|
@ -76,14 +76,14 @@ static crypto_suite crypto_suites[] = {
|
|||
{"NULL", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none},
|
||||
|
||||
/* cipher AES_CM, auth HMAC_SHA1, auth tag len = 10 octets */
|
||||
{"AES_CM_128_HMAC_SHA1_80", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10,
|
||||
{"AES_CM_128_HMAC_SHA1_80", AES_128_ICM, 30, HMAC_SHA1, 20, 10, 10,
|
||||
sec_serv_conf_and_auth},
|
||||
|
||||
/* cipher AES_CM, auth HMAC_SHA1, auth tag len = 4 octets */
|
||||
{"AES_CM_128_HMAC_SHA1_32", AES_128_ICM, 30, HMAC_SHA1, 20, 4, 10,
|
||||
sec_serv_conf_and_auth},
|
||||
|
||||
/*
|
||||
/*
|
||||
* F8_128_HMAC_SHA1_8 not supported by libsrtp?
|
||||
* {"F8_128_HMAC_SHA1_8", NULL_CIPHER, 0, NULL_AUTH, 0, 0, 0, sec_serv_none}
|
||||
*/
|
||||
|
@ -124,18 +124,18 @@ typedef struct transport_srtp
|
|||
void (*rtcp_cb)(void *user_data,
|
||||
void *pkt,
|
||||
pj_ssize_t size);
|
||||
|
||||
|
||||
/* Transport information */
|
||||
pjmedia_transport *member_tp; /**< Underlying transport. */
|
||||
|
||||
/* SRTP usage policy of peer. This field is updated when media is starting.
|
||||
* This is useful when SRTP is in optional mode and peer is using mandatory
|
||||
* mode, so when local is about to reinvite/update, it should offer
|
||||
* mode, so when local is about to reinvite/update, it should offer
|
||||
* RTP/SAVP instead of offering RTP/AVP.
|
||||
*/
|
||||
pjmedia_srtp_use peer_use;
|
||||
|
||||
/* When probation counter > 0, it means SRTP is in probation state,
|
||||
/* When probation counter > 0, it means SRTP is in probation state,
|
||||
* and it may restart when srtp_unprotect() returns err_status_replay_*
|
||||
*/
|
||||
unsigned probation_cnt;
|
||||
|
@ -205,7 +205,7 @@ static pj_status_t transport_destroy (pjmedia_transport *tp);
|
|||
|
||||
|
||||
|
||||
static pjmedia_transport_op transport_srtp_op =
|
||||
static pjmedia_transport_op transport_srtp_op =
|
||||
{
|
||||
&transport_get_info,
|
||||
&transport_attach,
|
||||
|
@ -238,17 +238,17 @@ const char* get_libsrtp_errstr(int err)
|
|||
"couldn't allocate memory", /* err_status_alloc_fail = 3 */
|
||||
"couldn't deallocate properly", /* err_status_dealloc_fail = 4 */
|
||||
"couldn't initialize", /* err_status_init_fail = 5 */
|
||||
"can't process as much data as requested",
|
||||
"can't process as much data as requested",
|
||||
/* err_status_terminus = 6 */
|
||||
"authentication failure", /* err_status_auth_fail = 7 */
|
||||
"cipher failure", /* err_status_cipher_fail = 8 */
|
||||
"replay check failed (bad index)", /* err_status_replay_fail = 9 */
|
||||
"replay check failed (index too old)",
|
||||
"replay check failed (index too old)",
|
||||
/* err_status_replay_old = 10 */
|
||||
"algorithm failed test routine", /* err_status_algo_fail = 11 */
|
||||
"unsupported operation", /* err_status_no_such_op = 12 */
|
||||
"no appropriate context found", /* err_status_no_ctx = 13 */
|
||||
"unable to perform desired validation",
|
||||
"unable to perform desired validation",
|
||||
/* err_status_cant_check = 14 */
|
||||
"can't use key any more", /* err_status_key_expired = 15 */
|
||||
"error in use of socket", /* err_status_socket_err = 16 */
|
||||
|
@ -285,17 +285,17 @@ PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt)
|
|||
err_status_t err;
|
||||
|
||||
err = srtp_init();
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s",
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s",
|
||||
get_libsrtp_errstr(err)));
|
||||
return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
|
||||
}
|
||||
|
||||
if (pjmedia_endpt_atexit(endpt, pjmedia_srtp_deinit_lib) != PJ_SUCCESS)
|
||||
{
|
||||
/* There will be memory leak when it fails to schedule libsrtp
|
||||
/* There will be memory leak when it fails to schedule libsrtp
|
||||
* deinitialization, however the memory leak could be harmless,
|
||||
* since in modern OS's memory used by an application is released
|
||||
* since in modern OS's memory used by an application is released
|
||||
* when the application terminates.
|
||||
*/
|
||||
PJ_LOG(4, (THIS_FILE, "Failed to register libsrtp deinit."));
|
||||
|
@ -306,7 +306,7 @@ PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt)
|
|||
#else
|
||||
PJ_UNUSED_ARG(endpt);
|
||||
#endif
|
||||
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ static void pjmedia_srtp_deinit_lib(pjmedia_endpt *endpt)
|
|||
err = srtp_deinit();
|
||||
#endif
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s",
|
||||
PJ_LOG(4, (THIS_FILE, "Failed to deinitialize libsrtp: %s",
|
||||
get_libsrtp_errstr(err)));
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ static int get_crypto_idx(const pj_str_t* crypto_name)
|
|||
{
|
||||
int i;
|
||||
int cs_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);
|
||||
|
||||
|
||||
/* treat unspecified crypto_name as crypto 'NULL' */
|
||||
if (crypto_name->slen == 0)
|
||||
return 0;
|
||||
|
@ -420,7 +420,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
|
|||
PJ_ASSERT_RETURN(endpt && tp && p_tp, PJ_EINVAL);
|
||||
|
||||
/* Check crypto availability */
|
||||
if (opt && opt->crypto_count == 0 &&
|
||||
if (opt && opt->crypto_count == 0 &&
|
||||
opt->use == PJMEDIA_SRTP_MANDATORY)
|
||||
return PJMEDIA_SRTP_ESDPREQCRYPTO;
|
||||
|
||||
|
@ -434,8 +434,8 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
|
|||
return PJMEDIA_SRTP_ENOTSUPCRYPTO;
|
||||
|
||||
/* check key length */
|
||||
if (opt->crypto[i].key.slen &&
|
||||
opt->crypto[i].key.slen <
|
||||
if (opt->crypto[i].key.slen &&
|
||||
opt->crypto[i].key.slen <
|
||||
(pj_ssize_t)crypto_suites[cs_idx].cipher_key_len)
|
||||
return PJMEDIA_SRTP_EINKEYLEN;
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
|
|||
* Initialize and start SRTP session with the given parameters.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pjmedia_transport_srtp_start(
|
||||
pjmedia_transport *tp,
|
||||
pjmedia_transport *tp,
|
||||
const pjmedia_srtp_crypto *tx,
|
||||
const pjmedia_srtp_crypto *rx)
|
||||
{
|
||||
|
@ -517,7 +517,6 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_start(
|
|||
int au_tx_idx = 0;
|
||||
int cr_rx_idx = 0;
|
||||
int au_rx_idx = 0;
|
||||
int crypto_suites_cnt;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
|
||||
PJ_ASSERT_RETURN(tp && tx && rx, PJ_EINVAL);
|
||||
|
@ -528,8 +527,6 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_start(
|
|||
pjmedia_transport_srtp_stop(tp);
|
||||
}
|
||||
|
||||
crypto_suites_cnt = sizeof(crypto_suites)/sizeof(crypto_suites[0]);
|
||||
|
||||
/* Get encryption and authentication method */
|
||||
cr_tx_idx = au_tx_idx = get_crypto_idx(&tx->name);
|
||||
if (tx->flags & PJMEDIA_SRTP_NO_ENCRYPTION)
|
||||
|
@ -544,7 +541,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_start(
|
|||
au_rx_idx = 0;
|
||||
|
||||
/* Check whether the crypto-suite requested is supported */
|
||||
if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 ||
|
||||
if (cr_tx_idx == -1 || cr_rx_idx == -1 || au_tx_idx == -1 ||
|
||||
au_rx_idx == -1)
|
||||
{
|
||||
status = PJMEDIA_SRTP_ENOTSUPCRYPTO;
|
||||
|
@ -647,7 +644,7 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_start(
|
|||
b64_len = pj_ansi_sprintf(b64, "--key too long--");
|
||||
else
|
||||
b64[b64_len] = '\0';
|
||||
|
||||
|
||||
PJ_LOG(5, (srtp->pool->obj_name, "TX: %s key=%s",
|
||||
srtp->tx_policy.name.ptr, b64));
|
||||
if (srtp->tx_policy.flags) {
|
||||
|
@ -699,13 +696,13 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_stop(pjmedia_transport *srtp)
|
|||
|
||||
err = srtp_dealloc(p_srtp->srtp_rx_ctx);
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(4, (p_srtp->pool->obj_name,
|
||||
PJ_LOG(4, (p_srtp->pool->obj_name,
|
||||
"Failed to dealloc RX SRTP context: %s",
|
||||
get_libsrtp_errstr(err)));
|
||||
}
|
||||
err = srtp_dealloc(p_srtp->srtp_tx_ctx);
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(4, (p_srtp->pool->obj_name,
|
||||
PJ_LOG(4, (p_srtp->pool->obj_name,
|
||||
"Failed to dealloc TX SRTP context: %s",
|
||||
get_libsrtp_errstr(err)));
|
||||
}
|
||||
|
@ -752,7 +749,7 @@ static pj_status_t transport_get_info(pjmedia_transport *tp,
|
|||
spc_info_idx = info->specific_info_cnt++;
|
||||
info->spc_info[spc_info_idx].type = PJMEDIA_TRANSPORT_TYPE_SRTP;
|
||||
info->spc_info[spc_info_idx].cbsize = sizeof(srtp_info);
|
||||
pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info,
|
||||
pj_memcpy(&info->spc_info[spc_info_idx].buffer, &srtp_info,
|
||||
sizeof(srtp_info));
|
||||
|
||||
return pjmedia_transport_get_info(srtp->member_tp, info);
|
||||
|
@ -781,7 +778,7 @@ static pj_status_t transport_attach(pjmedia_transport *tp,
|
|||
pj_lock_release(srtp->mutex);
|
||||
|
||||
/* Attach itself to transport */
|
||||
status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr,
|
||||
status = pjmedia_transport_attach(srtp->member_tp, srtp, rem_addr,
|
||||
rem_rtcp, addr_len, &srtp_rtp_cb,
|
||||
&srtp_rtcp_cb);
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -841,12 +838,12 @@ static pj_status_t transport_send_rtp( pjmedia_transport *tp,
|
|||
pj_lock_release(srtp->mutex);
|
||||
|
||||
if (err == err_status_ok) {
|
||||
status = pjmedia_transport_send_rtp(srtp->member_tp,
|
||||
status = pjmedia_transport_send_rtp(srtp->member_tp,
|
||||
srtp->rtp_tx_buffer, len);
|
||||
} else {
|
||||
status = PJMEDIA_ERRNO_FROM_LIBSRTP(err);
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -869,7 +866,7 @@ static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
|
|||
err_status_t err;
|
||||
|
||||
if (srtp->bypass_srtp) {
|
||||
return pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,
|
||||
return pjmedia_transport_send_rtcp2(srtp->member_tp, addr, addr_len,
|
||||
pkt, size);
|
||||
}
|
||||
|
||||
|
@ -902,7 +899,7 @@ static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
|
|||
unsigned pct_lost)
|
||||
{
|
||||
transport_srtp *srtp = (transport_srtp *) tp;
|
||||
|
||||
|
||||
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
|
||||
|
||||
return pjmedia_transport_simulate_lost(srtp->member_tp, dir, pct_lost);
|
||||
|
@ -964,13 +961,13 @@ static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size)
|
|||
return;
|
||||
}
|
||||
err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
|
||||
if (srtp->probation_cnt > 0 &&
|
||||
(err == err_status_replay_old || err == err_status_replay_fail))
|
||||
if (srtp->probation_cnt > 0 &&
|
||||
(err == err_status_replay_old || err == err_status_replay_fail))
|
||||
{
|
||||
/* Handle such condition that stream is updated (RTP seq is reinited
|
||||
* & SRTP is restarted), but some old packets are still coming
|
||||
* & SRTP is restarted), but some old packets are still coming
|
||||
* so SRTP is learning wrong RTP seq. While the newly inited RTP seq
|
||||
* comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect()
|
||||
* comes, SRTP thinks the RTP seq is replayed, so srtp_unprotect()
|
||||
* will return err_status_replay_*. Restarting SRTP can resolve this.
|
||||
*/
|
||||
pjmedia_srtp_crypto tx, rx;
|
||||
|
@ -981,7 +978,7 @@ static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size)
|
|||
status = pjmedia_transport_srtp_start((pjmedia_transport*)srtp,
|
||||
&tx, &rx);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s",
|
||||
PJ_LOG(5,(srtp->pool->obj_name, "Failed to restart SRTP, err=%s",
|
||||
get_libsrtp_errstr(err)));
|
||||
} else if (!srtp->bypass_srtp) {
|
||||
err = srtp_unprotect(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
|
||||
|
@ -989,8 +986,8 @@ static void srtp_rtp_cb( void *user_data, void *pkt, pj_ssize_t size)
|
|||
}
|
||||
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(5,(srtp->pool->obj_name,
|
||||
"Failed to unprotect SRTP, pkt size=%d, err=%s",
|
||||
PJ_LOG(5,(srtp->pool->obj_name,
|
||||
"Failed to unprotect SRTP, pkt size=%d, err=%s",
|
||||
size, get_libsrtp_errstr(err)));
|
||||
} else {
|
||||
cb = srtp->rtp_cb;
|
||||
|
@ -1035,7 +1032,7 @@ static void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size)
|
|||
}
|
||||
err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, (pj_uint8_t*)pkt, &len);
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(5,(srtp->pool->obj_name,
|
||||
PJ_LOG(5,(srtp->pool->obj_name,
|
||||
"Failed to unprotect SRTCP, pkt size=%d, err=%s",
|
||||
size, get_libsrtp_errstr(err)));
|
||||
} else {
|
||||
|
@ -1055,7 +1052,7 @@ static void srtp_rtcp_cb( void *user_data, void *pkt, pj_ssize_t size)
|
|||
* and set buffer_len = 0.
|
||||
*/
|
||||
static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,
|
||||
char *buffer, int *buffer_len,
|
||||
char *buffer, int *buffer_len,
|
||||
pjmedia_srtp_crypto *crypto,
|
||||
int tag)
|
||||
{
|
||||
|
@ -1087,7 +1084,7 @@ static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,
|
|||
do {
|
||||
key_ok = PJ_TRUE;
|
||||
|
||||
err = crypto_get_random((unsigned char*)key,
|
||||
err = crypto_get_random((unsigned char*)key,
|
||||
crypto_suites[cs_idx].cipher_key_len);
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(5,(THIS_FILE, "Failed generating random key: %s",
|
||||
|
@ -1099,7 +1096,7 @@ static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,
|
|||
|
||||
} while (!key_ok);
|
||||
crypto->key.ptr = (char*)
|
||||
pj_pool_zalloc(pool,
|
||||
pj_pool_zalloc(pool,
|
||||
crypto_suites[cs_idx].cipher_key_len);
|
||||
pj_memcpy(crypto->key.ptr, key, crypto_suites[cs_idx].cipher_key_len);
|
||||
crypto->key.slen = crypto_suites[cs_idx].cipher_key_len;
|
||||
|
@ -1117,13 +1114,13 @@ static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,
|
|||
}
|
||||
|
||||
b64_key[b64_key_len] = '\0';
|
||||
|
||||
|
||||
PJ_ASSERT_RETURN(*buffer_len >= (crypto->name.slen + \
|
||||
b64_key_len + 16), PJ_ETOOSMALL);
|
||||
|
||||
/* Print the crypto attribute value. */
|
||||
print_len = pj_ansi_snprintf(buffer, *buffer_len, "%d %s inline:%s",
|
||||
tag,
|
||||
tag,
|
||||
crypto_suites[cs_idx].name,
|
||||
b64_key);
|
||||
if (print_len < 1 || print_len >= *buffer_len)
|
||||
|
@ -1205,7 +1202,7 @@ static pj_status_t parse_attr_crypto(pj_pool_t *pool,
|
|||
/* Decode key */
|
||||
crypto->key.ptr = (char*) pj_pool_zalloc(pool, MAX_KEY_LEN);
|
||||
itmp = MAX_KEY_LEN;
|
||||
status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr,
|
||||
status = pj_base64_decode(&tmp, (pj_uint8_t*)crypto->key.ptr,
|
||||
&itmp);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_LOG(4,(THIS_FILE, "Failed decoding crypto key from base64"));
|
||||
|
@ -1226,7 +1223,7 @@ static pj_status_t transport_media_create(pjmedia_transport *tp,
|
|||
unsigned member_tp_option;
|
||||
|
||||
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
|
||||
|
||||
|
||||
pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));
|
||||
pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));
|
||||
|
||||
|
@ -1274,7 +1271,7 @@ BYPASS_SRTP:
|
|||
member_tp_option &= ~PJMEDIA_TPMED_NO_TRANSPORT_CHECKING;
|
||||
|
||||
PROPAGATE_MEDIA_CREATE:
|
||||
return pjmedia_transport_media_create(srtp->member_tp, sdp_pool,
|
||||
return pjmedia_transport_media_create(srtp->member_tp, sdp_pool,
|
||||
member_tp_option, sdp_remote,
|
||||
media_index);
|
||||
}
|
||||
|
@ -1296,7 +1293,7 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
unsigned i, j;
|
||||
|
||||
PJ_ASSERT_RETURN(tp && sdp_pool && sdp_local, PJ_EINVAL);
|
||||
|
||||
|
||||
pj_bzero(&srtp->rx_policy_neg, sizeof(srtp->rx_policy_neg));
|
||||
pj_bzero(&srtp->tx_policy_neg, sizeof(srtp->tx_policy_neg));
|
||||
|
||||
|
@ -1306,7 +1303,7 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
m_loc = sdp_local->media[media_index];
|
||||
|
||||
/* Bypass if media transport is not RTP/AVP or RTP/SAVP */
|
||||
if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) != 0 &&
|
||||
if (pj_stricmp(&m_loc->desc.transport, &ID_RTP_AVP) != 0 &&
|
||||
pj_stricmp(&m_loc->desc.transport, &ID_RTP_SAVP) != 0)
|
||||
goto BYPASS_SRTP;
|
||||
|
||||
|
@ -1317,12 +1314,12 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
* http://trac.pjsip.org/repos/ticket/1079
|
||||
*/
|
||||
/*
|
||||
if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) ||
|
||||
if (pjmedia_sdp_media_find_attr(m_loc, &ID_INACTIVE, NULL) ||
|
||||
(m_rem && pjmedia_sdp_media_find_attr(m_rem, &ID_INACTIVE, NULL)))
|
||||
goto BYPASS_SRTP;
|
||||
*/
|
||||
|
||||
/* Check remote media transport & set local media transport
|
||||
/* Check remote media transport & set local media transport
|
||||
* based on SRTP usage option.
|
||||
*/
|
||||
if (srtp->offerer_side) {
|
||||
|
@ -1332,7 +1329,7 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
case PJMEDIA_SRTP_DISABLED:
|
||||
goto BYPASS_SRTP;
|
||||
case PJMEDIA_SRTP_OPTIONAL:
|
||||
m_loc->desc.transport =
|
||||
m_loc->desc.transport =
|
||||
(srtp->peer_use == PJMEDIA_SRTP_MANDATORY)?
|
||||
ID_RTP_SAVP : ID_RTP_AVP;
|
||||
break;
|
||||
|
@ -1355,7 +1352,7 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
/* If buffer_len==0, just skip the crypto attribute. */
|
||||
if (buffer_len) {
|
||||
pj_strset(&attr_value, buffer, buffer_len);
|
||||
attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr,
|
||||
attr = pjmedia_sdp_attr_create(srtp->pool, ID_CRYPTO.ptr,
|
||||
&attr_value);
|
||||
m_loc->attr[m_loc->attr_count++] = attr;
|
||||
}
|
||||
|
@ -1400,11 +1397,11 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
|
||||
has_crypto_attr = PJ_TRUE;
|
||||
|
||||
status = parse_attr_crypto(srtp->pool, m_rem->attr[i],
|
||||
status = parse_attr_crypto(srtp->pool, m_rem->attr[i],
|
||||
&tmp_rx_crypto, &tags[cr_attr_count]);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
||||
/* Check duplicated tag */
|
||||
for (j=0; j<cr_attr_count; ++j) {
|
||||
if (tags[j] == tags[cr_attr_count]) {
|
||||
|
@ -1416,7 +1413,7 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
if (matched_idx == -1) {
|
||||
/* lets see if the crypto-suite offered is supported */
|
||||
for (j=0; j<srtp->setting.crypto_count; ++j)
|
||||
if (pj_stricmp(&tmp_rx_crypto.name,
|
||||
if (pj_stricmp(&tmp_rx_crypto.name,
|
||||
&srtp->setting.crypto[j].name) == 0)
|
||||
{
|
||||
int cs_idx = get_crypto_idx(&tmp_rx_crypto.name);
|
||||
|
@ -1433,11 +1430,11 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
// raw_test_key,
|
||||
// hex_test_key,
|
||||
// strlen(hex_test_key));
|
||||
//pj_strset(test_key, raw_test_key,
|
||||
//pj_strset(test_key, raw_test_key,
|
||||
// crypto_suites[cs_idx].cipher_key_len);
|
||||
/* EO Force to use test key */
|
||||
|
||||
if (tmp_rx_crypto.key.slen !=
|
||||
if (tmp_rx_crypto.key.slen !=
|
||||
(int)crypto_suites[cs_idx].cipher_key_len)
|
||||
return PJMEDIA_SRTP_EINKEYLEN;
|
||||
|
||||
|
@ -1458,11 +1455,11 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
|
||||
case PJMEDIA_SRTP_OPTIONAL:
|
||||
/* bypass SRTP when no crypto-attr and remote uses RTP/AVP */
|
||||
if (!has_crypto_attr &&
|
||||
if (!has_crypto_attr &&
|
||||
pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)
|
||||
goto BYPASS_SRTP;
|
||||
/* bypass SRTP when nothing match and remote uses RTP/AVP */
|
||||
else if (matched_idx == -1 &&
|
||||
else if (matched_idx == -1 &&
|
||||
pj_stricmp(&m_rem->desc.transport, &ID_RTP_AVP) == 0)
|
||||
goto BYPASS_SRTP;
|
||||
break;
|
||||
|
@ -1484,7 +1481,7 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
return PJMEDIA_SRTP_ENOTSUPCRYPTO;
|
||||
}
|
||||
|
||||
/* we have to generate crypto answer,
|
||||
/* we have to generate crypto answer,
|
||||
* with srtp->tx_policy_neg matched the offer
|
||||
* and rem_tag contains matched offer tag.
|
||||
*/
|
||||
|
@ -1496,18 +1493,18 @@ static pj_status_t transport_encode_sdp(pjmedia_transport *tp,
|
|||
return status;
|
||||
|
||||
srtp->tx_policy_neg = srtp->setting.crypto[matched_idx];
|
||||
|
||||
|
||||
/* If buffer_len==0, just skip the crypto attribute. */
|
||||
if (buffer_len) {
|
||||
pj_strset(&attr_value, buffer, buffer_len);
|
||||
attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr,
|
||||
attr = pjmedia_sdp_attr_create(sdp_pool, ID_CRYPTO.ptr,
|
||||
&attr_value);
|
||||
m_loc->attr[m_loc->attr_count++] = attr;
|
||||
}
|
||||
|
||||
/* At this point, we get valid rx_policy_neg & tx_policy_neg. */
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
goto PROPAGATE_MEDIA_CREATE;
|
||||
|
||||
|
@ -1518,7 +1515,7 @@ BYPASS_SRTP:
|
|||
//srtp->bypass_srtp = PJ_TRUE;
|
||||
|
||||
PROPAGATE_MEDIA_CREATE:
|
||||
return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool,
|
||||
return pjmedia_transport_encode_sdp(srtp->member_tp, sdp_pool,
|
||||
sdp_local, sdp_remote, media_index);
|
||||
}
|
||||
|
||||
|
@ -1547,7 +1544,7 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
|
|||
|
||||
/* For answerer side, this function will just have to start SRTP */
|
||||
|
||||
/* Check remote media transport & set local media transport
|
||||
/* Check remote media transport & set local media transport
|
||||
* based on SRTP usage option.
|
||||
*/
|
||||
if (srtp->offerer_side) {
|
||||
|
@ -1560,7 +1557,7 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
|
|||
} else if (srtp->setting.use == PJMEDIA_SRTP_OPTIONAL) {
|
||||
// Regardless the answer's transport type (RTP/AVP or RTP/SAVP),
|
||||
// the answer must be processed through in optional mode.
|
||||
// Please note that at this point transport type is ensured to be
|
||||
// Please note that at this point transport type is ensured to be
|
||||
// RTP/AVP or RTP/SAVP, see transport_media_create()
|
||||
//if (pj_stricmp(&m_rem->desc.transport, &m_loc->desc.transport)) {
|
||||
//DEACTIVATE_MEDIA(pool, m_loc);
|
||||
|
@ -1573,7 +1570,7 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (srtp->offerer_side) {
|
||||
/* find supported crypto-suite, get the tag, and assign policy_local */
|
||||
pjmedia_srtp_crypto tmp_tx_crypto;
|
||||
|
@ -1592,7 +1589,7 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
|
|||
|
||||
has_crypto_attr = PJ_TRUE;
|
||||
|
||||
status = parse_attr_crypto(srtp->pool, m_rem->attr[i],
|
||||
status = parse_attr_crypto(srtp->pool, m_rem->attr[i],
|
||||
&tmp_tx_crypto, &rem_tag);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
@ -1605,7 +1602,7 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
|
|||
}
|
||||
|
||||
/* match the crypto name */
|
||||
if (pj_stricmp(&tmp_tx_crypto.name,
|
||||
if (pj_stricmp(&tmp_tx_crypto.name,
|
||||
&srtp->setting.crypto[rem_tag-1].name) != 0)
|
||||
{
|
||||
DEACTIVATE_MEDIA(pool, m_loc);
|
||||
|
@ -1633,7 +1630,7 @@ static pj_status_t transport_media_start(pjmedia_transport *tp,
|
|||
}
|
||||
|
||||
/* Make sure we have the SRTP policies */
|
||||
if (srtp_crypto_empty(&srtp->tx_policy_neg) ||
|
||||
if (srtp_crypto_empty(&srtp->tx_policy_neg) ||
|
||||
srtp_crypto_empty(&srtp->rx_policy_neg))
|
||||
{
|
||||
goto BYPASS_SRTP;
|
||||
|
@ -1670,7 +1667,7 @@ BYPASS_SRTP:
|
|||
}
|
||||
|
||||
PROPAGATE_MEDIA_START:
|
||||
return pjmedia_transport_media_start(srtp->member_tp, pool,
|
||||
return pjmedia_transport_media_start(srtp->member_tp, pool,
|
||||
sdp_local, sdp_remote,
|
||||
media_index);
|
||||
}
|
||||
|
@ -1684,7 +1681,7 @@ static pj_status_t transport_media_stop(pjmedia_transport *tp)
|
|||
|
||||
status = pjmedia_transport_media_stop(srtp->member_tp);
|
||||
if (status != PJ_SUCCESS)
|
||||
PJ_LOG(4, (srtp->pool->obj_name,
|
||||
PJ_LOG(4, (srtp->pool->obj_name,
|
||||
"SRTP failed stop underlying media transport."));
|
||||
|
||||
return pjmedia_transport_srtp_stop(tp);
|
||||
|
@ -1719,10 +1716,10 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_decrypt_pkt(pjmedia_transport *tp,
|
|||
err = srtp_unprotect(srtp->srtp_rx_ctx, pkt, pkt_len);
|
||||
else
|
||||
err = srtp_unprotect_rtcp(srtp->srtp_rx_ctx, pkt, pkt_len);
|
||||
|
||||
|
||||
if (err != err_status_ok) {
|
||||
PJ_LOG(5,(srtp->pool->obj_name,
|
||||
"Failed to unprotect SRTP, pkt size=%d, err=%s",
|
||||
PJ_LOG(5,(srtp->pool->obj_name,
|
||||
"Failed to unprotect SRTP, pkt size=%d, err=%s",
|
||||
*pkt_len, get_libsrtp_errstr(err)));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
@ -47,7 +47,7 @@ typedef struct test_cond_t {
|
|||
int delay_min; /**< Minimum delay, in frames. */
|
||||
} test_cond_t;
|
||||
|
||||
static pj_bool_t parse_test_headers(char *line, test_param_t *param,
|
||||
static pj_bool_t parse_test_headers(char *line, test_param_t *param,
|
||||
test_cond_t *cond)
|
||||
{
|
||||
char *p = line;
|
||||
|
@ -56,7 +56,7 @@ static pj_bool_t parse_test_headers(char *line, test_param_t *param,
|
|||
/* Test params. */
|
||||
char mode_st[16];
|
||||
|
||||
sscanf(p+1, "%s %u %u %u", mode_st, ¶m->init_prefetch,
|
||||
sscanf(p+1, "%s %u %u %u", mode_st, ¶m->init_prefetch,
|
||||
¶m->min_prefetch, ¶m->max_prefetch);
|
||||
param->adaptive = (pj_ansi_stricmp(mode_st, "adaptive") == 0);
|
||||
|
||||
|
@ -102,7 +102,7 @@ static pj_bool_t parse_test_headers(char *line, test_param_t *param,
|
|||
return PJ_TRUE;
|
||||
}
|
||||
|
||||
static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb,
|
||||
static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb,
|
||||
pj_uint16_t *seq, pj_uint16_t *last_seq)
|
||||
{
|
||||
char frame[1];
|
||||
|
@ -155,9 +155,11 @@ static pj_bool_t process_test_data(char data, pjmedia_jbuf *jb,
|
|||
pjmedia_jb_state state;
|
||||
|
||||
pjmedia_jbuf_get_state(jb, &state);
|
||||
printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n",
|
||||
printf("seq=%d\t%c\tsize=%d\tprefetch=%d\n",
|
||||
*last_seq, toupper(data), state.size, state.prefetch);
|
||||
}
|
||||
#else
|
||||
PJ_UNUSED_ARG(print_state); /* Warning about variable set but unused */
|
||||
#endif
|
||||
|
||||
return PJ_TRUE;
|
||||
|
@ -170,7 +172,7 @@ int jbuf_main(void)
|
|||
int old_log_level;
|
||||
int rc = 0;
|
||||
const char* input_filename = "Jbtest.dat";
|
||||
const char* input_search_path[] = {
|
||||
const char* input_search_path[] = {
|
||||
"../build",
|
||||
"pjmedia/build",
|
||||
"build"
|
||||
|
@ -191,7 +193,7 @@ int jbuf_main(void)
|
|||
input = fopen(input_path, "rt");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Failed to open test data file. */
|
||||
if (input == NULL) {
|
||||
printf("Failed to open test data file, Jbtest.dat\n");
|
||||
|
@ -244,8 +246,8 @@ int jbuf_main(void)
|
|||
pjmedia_jbuf_reset(jb);
|
||||
|
||||
if (param.adaptive) {
|
||||
pjmedia_jbuf_set_adaptive(jb,
|
||||
param.init_prefetch,
|
||||
pjmedia_jbuf_set_adaptive(jb,
|
||||
param.init_prefetch,
|
||||
param.min_prefetch,
|
||||
param.max_prefetch);
|
||||
} else {
|
||||
|
@ -254,8 +256,8 @@ int jbuf_main(void)
|
|||
|
||||
#ifdef REPORT
|
||||
pjmedia_jbuf_get_state(jb, &state);
|
||||
printf("Initial\tsize=%d\tprefetch=%d\tmin.pftch=%d\tmax.pftch=%d\n",
|
||||
state.size, state.prefetch, state.min_prefetch,
|
||||
printf("Initial\tsize=%d\tprefetch=%d\tmin.pftch=%d\tmax.pftch=%d\n",
|
||||
state.size, state.prefetch, state.min_prefetch,
|
||||
state.max_prefetch);
|
||||
#endif
|
||||
|
||||
|
@ -263,7 +265,7 @@ int jbuf_main(void)
|
|||
/* Test session start */
|
||||
while (1) {
|
||||
char c;
|
||||
|
||||
|
||||
/* Get next line of test data */
|
||||
if (!p || *p == 0) {
|
||||
p = fgets(line, sizeof(line), input);
|
||||
|
@ -301,24 +303,24 @@ int jbuf_main(void)
|
|||
printf("Summary:\n");
|
||||
printf(" size=%d prefetch=%d\n", state.size, state.prefetch);
|
||||
printf(" delay (min/max/avg/dev)=%d/%d/%d/%d ms\n",
|
||||
state.min_delay, state.max_delay, state.avg_delay,
|
||||
state.min_delay, state.max_delay, state.avg_delay,
|
||||
state.dev_delay);
|
||||
printf(" lost=%d discard=%d empty=%d burst(avg)=%d\n",
|
||||
printf(" lost=%d discard=%d empty=%d burst(avg)=%d\n",
|
||||
state.lost, state.discard, state.empty, state.avg_burst);
|
||||
|
||||
/* Evaluate test session */
|
||||
if (cond.burst >= 0 && (int)state.avg_burst > cond.burst) {
|
||||
printf("! 'Burst' should be %d, it is %d\n",
|
||||
printf("! 'Burst' should be %d, it is %d\n",
|
||||
cond.burst, state.avg_burst);
|
||||
rc |= 1;
|
||||
}
|
||||
if (cond.delay >= 0 && (int)state.avg_delay/JB_PTIME > cond.delay) {
|
||||
printf("! 'Delay' should be %d, it is %d\n",
|
||||
printf("! 'Delay' should be %d, it is %d\n",
|
||||
cond.delay, state.avg_delay/JB_PTIME);
|
||||
rc |= 2;
|
||||
}
|
||||
if (cond.delay_min >= 0 && (int)state.min_delay/JB_PTIME > cond.delay_min) {
|
||||
printf("! 'Minimum delay' should be %d, it is %d\n",
|
||||
printf("! 'Minimum delay' should be %d, it is %d\n",
|
||||
cond.delay_min, state.min_delay/JB_PTIME);
|
||||
rc |= 32;
|
||||
}
|
||||
|
@ -328,12 +330,12 @@ int jbuf_main(void)
|
|||
rc |= 4;
|
||||
}
|
||||
if (cond.empty >= 0 && (int)state.empty > cond.empty) {
|
||||
printf("! 'Empty' should be %d, it is %d\n",
|
||||
printf("! 'Empty' should be %d, it is %d\n",
|
||||
cond.empty, state.empty);
|
||||
rc |= 8;
|
||||
}
|
||||
if (cond.lost >= 0 && (int)state.lost > cond.lost) {
|
||||
printf("! 'Lost' should be %d, it is %d\n",
|
||||
printf("! 'Lost' should be %d, it is %d\n",
|
||||
cond.lost, state.lost);
|
||||
rc |= 16;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "test.h"
|
||||
#include "server.h"
|
||||
|
@ -112,11 +112,11 @@ struct test_sess
|
|||
|
||||
|
||||
static void ice_on_rx_data(pj_ice_strans *ice_st,
|
||||
unsigned comp_id,
|
||||
unsigned comp_id,
|
||||
void *pkt, pj_size_t size,
|
||||
const pj_sockaddr_t *src_addr,
|
||||
unsigned src_addr_len);
|
||||
static void ice_on_ice_complete(pj_ice_strans *ice_st,
|
||||
static void ice_on_ice_complete(pj_ice_strans *ice_st,
|
||||
pj_ice_strans_op op,
|
||||
pj_status_t status);
|
||||
static void destroy_sess(struct test_sess *sess, unsigned wait_msec);
|
||||
|
@ -201,7 +201,7 @@ static int create_ice_strans(struct test_sess *test_sess,
|
|||
*p_ice = ice;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Create test session */
|
||||
static int create_sess(pj_stun_config *stun_cfg,
|
||||
unsigned server_flag,
|
||||
|
@ -238,7 +238,7 @@ static int create_sess(pj_stun_config *stun_cfg,
|
|||
destroy_sess(sess, 500);
|
||||
return -10;
|
||||
}
|
||||
sess->server->turn_respond_allocate =
|
||||
sess->server->turn_respond_allocate =
|
||||
sess->server->turn_respond_refresh = PJ_TRUE;
|
||||
|
||||
/* Create resolver */
|
||||
|
@ -318,7 +318,7 @@ static void destroy_sess(struct test_sess *sess, unsigned wait_msec)
|
|||
}
|
||||
|
||||
static void ice_on_rx_data(pj_ice_strans *ice_st,
|
||||
unsigned comp_id,
|
||||
unsigned comp_id,
|
||||
void *pkt, pj_size_t size,
|
||||
const pj_sockaddr_t *src_addr,
|
||||
unsigned src_addr_len)
|
||||
|
@ -335,7 +335,7 @@ static void ice_on_rx_data(pj_ice_strans *ice_st,
|
|||
}
|
||||
|
||||
|
||||
static void ice_on_ice_complete(pj_ice_strans *ice_st,
|
||||
static void ice_on_ice_complete(pj_ice_strans *ice_st,
|
||||
pj_ice_strans_op op,
|
||||
pj_status_t status)
|
||||
{
|
||||
|
@ -436,14 +436,14 @@ static int check_pair(const struct ice_ept *ept1, const struct ice_ept *ept2,
|
|||
/* Extra components must not have valid pair */
|
||||
for (; i<max_cnt; ++i) {
|
||||
if (ept1->cfg.comp_cnt>i &&
|
||||
pj_ice_strans_get_valid_pair(ept1->ice, i+1) != NULL)
|
||||
pj_ice_strans_get_valid_pair(ept1->ice, i+1) != NULL)
|
||||
{
|
||||
PJ_LOG(3,(THIS_FILE, INDENT "err: ice1 shouldn't have valid pair "
|
||||
"for component %d", i+1));
|
||||
return start_err - 8;
|
||||
}
|
||||
if (ept2->cfg.comp_cnt>i &&
|
||||
pj_ice_strans_get_valid_pair(ept2->ice, i+1) != NULL)
|
||||
pj_ice_strans_get_valid_pair(ept2->ice, i+1) != NULL)
|
||||
{
|
||||
PJ_LOG(3,(THIS_FILE, INDENT "err: ice2 shouldn't have valid pair "
|
||||
"for component %d", i+1));
|
||||
|
@ -463,7 +463,7 @@ static int check_pair(const struct ice_ept *ept1, const struct ice_ept *ept2,
|
|||
poll_events(stun_cfg, 10, PJ_FALSE); \
|
||||
pj_gettimeofday(&t); \
|
||||
if (expr) { \
|
||||
rc = PJ_SUCCESS; \
|
||||
RC = PJ_SUCCESS; \
|
||||
break; \
|
||||
} \
|
||||
PJ_TIME_VAL_SUB(t, t0); \
|
||||
|
@ -477,13 +477,13 @@ int worker_thread_proc(void *data)
|
|||
pj_status_t rc;
|
||||
struct test_sess *sess = (struct test_sess *) data;
|
||||
pj_stun_config *stun_cfg = sess->stun_cfg;
|
||||
|
||||
|
||||
/* Wait until negotiation is complete on both endpoints */
|
||||
#define ALL_DONE (sess->param->worker_quit || \
|
||||
(sess->caller.result.nego_status!=PJ_EPENDING && \
|
||||
sess->callee.result.nego_status!=PJ_EPENDING))
|
||||
WAIT_UNTIL(sess->param->worker_timeout, ALL_DONE, rc);
|
||||
|
||||
PJ_UNUSED_ARG(rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -538,7 +538,7 @@ static int perform_test2(const char *title,
|
|||
goto on_return;
|
||||
}
|
||||
/* Init ICE on caller */
|
||||
rc = pj_ice_strans_init_ice(sess->caller.ice, sess->caller.cfg.role,
|
||||
rc = pj_ice_strans_init_ice(sess->caller.ice, sess->caller.cfg.role,
|
||||
&sess->caller.ufrag, &sess->caller.pass);
|
||||
if (rc != PJ_SUCCESS) {
|
||||
app_perror(INDENT "err: caller pj_ice_strans_init_ice()", rc);
|
||||
|
@ -547,7 +547,7 @@ static int perform_test2(const char *title,
|
|||
}
|
||||
|
||||
/* Init ICE on callee */
|
||||
rc = pj_ice_strans_init_ice(sess->callee.ice, sess->callee.cfg.role,
|
||||
rc = pj_ice_strans_init_ice(sess->callee.ice, sess->callee.cfg.role,
|
||||
&sess->callee.ufrag, &sess->callee.pass);
|
||||
if (rc != PJ_SUCCESS) {
|
||||
app_perror(INDENT "err: callee pj_ice_strans_init_ice()", rc);
|
||||
|
@ -596,7 +596,7 @@ static int perform_test2(const char *title,
|
|||
}
|
||||
goto on_destroy;
|
||||
}
|
||||
|
||||
|
||||
WAIT_UNTIL(30000, ALL_DONE, rc);
|
||||
if (!ALL_DONE) {
|
||||
PJ_LOG(3,(THIS_FILE, INDENT "err: negotiation timed-out"));
|
||||
|
@ -690,7 +690,7 @@ int ice_test(void)
|
|||
unsigned server_flag;
|
||||
struct test_cfg ua1;
|
||||
struct test_cfg ua2;
|
||||
} sess_cfg[] =
|
||||
} sess_cfg[] =
|
||||
{
|
||||
/* Role comp# host? stun? turn? flag? ans_del snd_del des_del */
|
||||
{
|
||||
|
@ -740,7 +740,7 @@ int ice_test(void)
|
|||
|
||||
/* Simple test first with host candidate */
|
||||
if (1) {
|
||||
struct sess_cfg_t cfg =
|
||||
struct sess_cfg_t cfg =
|
||||
{
|
||||
"Basic with host candidates",
|
||||
0x0,
|
||||
|
@ -749,23 +749,23 @@ int ice_test(void)
|
|||
{ROLE2, 1, YES, NO, NO, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}
|
||||
};
|
||||
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
||||
cfg.ua1.comp_cnt = 2;
|
||||
cfg.ua2.comp_cnt = 2;
|
||||
rc = perform_test("Basic with host candidates, 2 components",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
rc = perform_test("Basic with host candidates, 2 components",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
|
||||
/* Simple test first with srflx candidate */
|
||||
if (1) {
|
||||
struct sess_cfg_t cfg =
|
||||
struct sess_cfg_t cfg =
|
||||
{
|
||||
"Basic with srflx candidates",
|
||||
0xFFFF,
|
||||
|
@ -774,7 +774,7 @@ int ice_test(void)
|
|||
{ROLE2, 1, YES, YES, NO, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}
|
||||
};
|
||||
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -782,8 +782,8 @@ int ice_test(void)
|
|||
cfg.ua1.comp_cnt = 2;
|
||||
cfg.ua2.comp_cnt = 2;
|
||||
|
||||
rc = perform_test("Basic with srflx candidates, 2 components",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
rc = perform_test("Basic with srflx candidates, 2 components",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -791,7 +791,7 @@ int ice_test(void)
|
|||
|
||||
/* Simple test with relay candidate */
|
||||
if (1) {
|
||||
struct sess_cfg_t cfg =
|
||||
struct sess_cfg_t cfg =
|
||||
{
|
||||
"Basic with relay candidates",
|
||||
0xFFFF,
|
||||
|
@ -800,7 +800,7 @@ int ice_test(void)
|
|||
{ROLE2, 1, NO, NO, YES, 0, 0, 0, 0, {PJ_SUCCESS, PJ_SUCCESS}}
|
||||
};
|
||||
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -808,8 +808,8 @@ int ice_test(void)
|
|||
cfg.ua1.comp_cnt = 2;
|
||||
cfg.ua2.comp_cnt = 2;
|
||||
|
||||
rc = perform_test("Basic with relay candidates, 2 components",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
rc = perform_test("Basic with relay candidates, 2 components",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -817,7 +817,7 @@ int ice_test(void)
|
|||
|
||||
/* Failure test with STUN resolution */
|
||||
if (1) {
|
||||
struct sess_cfg_t cfg =
|
||||
struct sess_cfg_t cfg =
|
||||
{
|
||||
"STUN resolution failure",
|
||||
0x0,
|
||||
|
@ -834,8 +834,8 @@ int ice_test(void)
|
|||
cfg.ua1.client_flag |= DEL_ON_ERR;
|
||||
cfg.ua2.client_flag |= DEL_ON_ERR;
|
||||
|
||||
rc = perform_test("STUN resolution failure with destroy on callback",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
rc = perform_test("STUN resolution failure with destroy on callback",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -843,7 +843,7 @@ int ice_test(void)
|
|||
|
||||
/* Failure test with TURN resolution */
|
||||
if (1) {
|
||||
struct sess_cfg_t cfg =
|
||||
struct sess_cfg_t cfg =
|
||||
{
|
||||
"TURN allocation failure",
|
||||
0xFFFF,
|
||||
|
@ -852,7 +852,7 @@ int ice_test(void)
|
|||
{ROLE2, 2, NO, NO, YES, WRONG_TURN, 0, 0, 0, {PJ_STATUS_FROM_STUN_CODE(401), -1}}
|
||||
};
|
||||
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
rc = perform_test(cfg.title, &stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -860,8 +860,8 @@ int ice_test(void)
|
|||
cfg.ua1.client_flag |= DEL_ON_ERR;
|
||||
cfg.ua2.client_flag |= DEL_ON_ERR;
|
||||
|
||||
rc = perform_test("TURN allocation failure with destroy on callback",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
rc = perform_test("TURN allocation failure with destroy on callback",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -870,7 +870,7 @@ int ice_test(void)
|
|||
|
||||
/* STUN failure, testing TURN deallocation */
|
||||
if (1) {
|
||||
struct sess_cfg_t cfg =
|
||||
struct sess_cfg_t cfg =
|
||||
{
|
||||
"STUN failure, testing TURN deallocation",
|
||||
0xFFFF & (~(CREATE_STUN_SERVER)),
|
||||
|
@ -887,8 +887,8 @@ int ice_test(void)
|
|||
cfg.ua1.client_flag |= DEL_ON_ERR;
|
||||
cfg.ua2.client_flag |= DEL_ON_ERR;
|
||||
|
||||
rc = perform_test("STUN failure, testing TURN deallocation (cb)",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
rc = perform_test("STUN failure, testing TURN deallocation (cb)",
|
||||
&stun_cfg, cfg.server_flag,
|
||||
&cfg.ua1, &cfg.ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -908,7 +908,7 @@ int ice_test(void)
|
|||
struct role_t {
|
||||
pj_ice_sess_role ua1;
|
||||
pj_ice_sess_role ua2;
|
||||
} role[] =
|
||||
} role[] =
|
||||
{
|
||||
{ ROLE1, ROLE2},
|
||||
{ ROLE2, ROLE1},
|
||||
|
@ -936,14 +936,14 @@ int ice_test(void)
|
|||
for (k2=1; k2<=2; ++k2) {
|
||||
char title[120];
|
||||
|
||||
sprintf(title,
|
||||
"%s/%s, %dms answer delay, %d vs %d components",
|
||||
sprintf(title,
|
||||
"%s/%s, %dms answer delay, %d vs %d components",
|
||||
pj_ice_sess_role_name(role[j].ua1),
|
||||
pj_ice_sess_role_name(role[j].ua2),
|
||||
delay[d], k1, k2);
|
||||
|
||||
cfg->ua2.comp_cnt = k2;
|
||||
rc = perform_test(title, &stun_cfg, cfg->server_flag,
|
||||
rc = perform_test(title, &stun_cfg, cfg->server_flag,
|
||||
&cfg->ua1, &cfg->ua2);
|
||||
if (rc != 0)
|
||||
goto on_return;
|
||||
|
@ -1021,14 +1021,14 @@ int ice_conc_test(void)
|
|||
pj_stun_config stun_cfg;
|
||||
unsigned i;
|
||||
int rc;
|
||||
|
||||
|
||||
pool = pj_pool_create(mem, NULL, 512, 512, NULL);
|
||||
rc = create_stun_config(pool, &stun_cfg);
|
||||
if (rc != PJ_SUCCESS) {
|
||||
pj_pool_release(pool);
|
||||
return -7;
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; i < LOOP; i++) {
|
||||
PJ_LOG(3,(THIS_FILE, INDENT "Test %d of %d", i+1, LOOP));
|
||||
rc = ice_one_conc_test(&stun_cfg, PJ_TRUE);
|
||||
|
@ -1038,7 +1038,7 @@ int ice_conc_test(void)
|
|||
|
||||
/* Avoid compiler warning */
|
||||
goto on_return;
|
||||
|
||||
|
||||
on_return:
|
||||
destroy_stun_config(&stun_cfg);
|
||||
pj_pool_release(pool);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "test.h"
|
||||
#include <pjlib.h>
|
||||
|
@ -108,12 +108,12 @@ void capture_pjlib_state(pj_stun_config *cfg, struct pjlib_state *st)
|
|||
pj_caching_pool *cp;
|
||||
|
||||
st->timer_cnt = (unsigned)pj_timer_heap_count(cfg->timer_heap);
|
||||
|
||||
|
||||
cp = (pj_caching_pool*)cfg->pf;
|
||||
st->pool_used_cnt = (unsigned)cp->used_count;
|
||||
}
|
||||
|
||||
int check_pjlib_state(pj_stun_config *cfg,
|
||||
int check_pjlib_state(pj_stun_config *cfg,
|
||||
const struct pjlib_state *initial_st)
|
||||
{
|
||||
struct pjlib_state current_state;
|
||||
|
@ -153,7 +153,7 @@ int check_pjlib_state(pj_stun_config *cfg,
|
|||
|
||||
pj_pool_factory *mem;
|
||||
|
||||
int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
|
||||
int param_log_decor = PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
|
||||
PJ_LOG_HAS_MICRO_SEC;
|
||||
|
||||
pj_log_func *orig_log_func;
|
||||
|
@ -178,6 +178,7 @@ static int test_inner(void)
|
|||
#if 1
|
||||
pj_log_set_level(3);
|
||||
pj_log_set_decor(param_log_decor);
|
||||
PJ_UNUSED_ARG(test_log_func);
|
||||
#elif 1
|
||||
log_file = fopen("pjnath-test.log", "wt");
|
||||
pj_log_set_level(5);
|
||||
|
@ -190,7 +191,7 @@ static int test_inner(void)
|
|||
app_perror("pj_init() error!!", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
pj_dump_config();
|
||||
pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 );
|
||||
|
||||
|
@ -233,7 +234,7 @@ int test_main(void)
|
|||
}
|
||||
PJ_CATCH_ANY {
|
||||
int id = PJ_GET_EXCEPTION();
|
||||
PJ_LOG(3,("test", "FATAL: unhandled exception id %d (%s)",
|
||||
PJ_LOG(3,("test", "FATAL: unhandled exception id %d (%s)",
|
||||
id, pj_exception_id_name(id)));
|
||||
}
|
||||
PJ_END;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <pjnath/ice_strans.h>
|
||||
#include <pjnath/errno.h>
|
||||
|
@ -65,7 +65,7 @@ enum tp_type
|
|||
|
||||
|
||||
/* The candidate type preference when STUN candidate is used */
|
||||
static pj_uint8_t srflx_pref_table[PJ_ICE_CAND_TYPE_MAX] =
|
||||
static pj_uint8_t srflx_pref_table[PJ_ICE_CAND_TYPE_MAX] =
|
||||
{
|
||||
#if PJNATH_ICE_PRIO_STD
|
||||
100, /**< PJ_ICE_HOST_PREF */
|
||||
|
@ -84,14 +84,14 @@ static pj_uint8_t srflx_pref_table[PJ_ICE_CAND_TYPE_MAX] =
|
|||
|
||||
/* ICE callbacks */
|
||||
static void on_ice_complete(pj_ice_sess *ice, pj_status_t status);
|
||||
static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
|
||||
static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
|
||||
unsigned comp_id,
|
||||
unsigned transport_id,
|
||||
const void *pkt, pj_size_t size,
|
||||
const pj_sockaddr_t *dst_addr,
|
||||
unsigned dst_addr_len);
|
||||
static void ice_rx_data(pj_ice_sess *ice,
|
||||
unsigned comp_id,
|
||||
static void ice_rx_data(pj_ice_sess *ice,
|
||||
unsigned comp_id,
|
||||
unsigned transport_id,
|
||||
void *pkt, pj_size_t size,
|
||||
const pj_sockaddr_t *src_addr,
|
||||
|
@ -110,7 +110,7 @@ static pj_bool_t stun_on_data_sent(pj_stun_sock *stun_sock,
|
|||
pj_ioqueue_op_key_t *send_key,
|
||||
pj_ssize_t sent);
|
||||
/* Notification when the status of the STUN transport has changed. */
|
||||
static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
|
||||
static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
|
||||
pj_stun_sock_op op,
|
||||
pj_status_t status);
|
||||
|
||||
|
@ -136,7 +136,7 @@ static void sess_init_update(pj_ice_strans *ice_st);
|
|||
* This structure describes an ICE stream transport component. A component
|
||||
* in ICE stream transport typically corresponds to a single socket created
|
||||
* for this component, and bound to a specific transport address. This
|
||||
* component may have multiple alias addresses, for example one alias
|
||||
* component may have multiple alias addresses, for example one alias
|
||||
* address for each interfaces in multi-homed host, another for server
|
||||
* reflexive alias, and another for relayed alias. For each transport
|
||||
* address alias, an ICE stream transport candidate (#pj_ice_sess_cand) will
|
||||
|
@ -298,11 +298,11 @@ static pj_status_t add_update_turn(pj_ice_strans *ice_st,
|
|||
|
||||
/* Override with component specific socket buffer size settings, if any */
|
||||
if (ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size > 0) {
|
||||
ice_st->cfg.turn.cfg.so_rcvbuf_size =
|
||||
ice_st->cfg.turn.cfg.so_rcvbuf_size =
|
||||
ice_st->cfg.comp[comp->comp_id-1].so_rcvbuf_size;
|
||||
}
|
||||
if (ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size > 0) {
|
||||
ice_st->cfg.turn.cfg.so_sndbuf_size =
|
||||
ice_st->cfg.turn.cfg.so_sndbuf_size =
|
||||
ice_st->cfg.comp[comp->comp_id-1].so_sndbuf_size;
|
||||
}
|
||||
|
||||
|
@ -381,10 +381,10 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
stun_sock_cb.on_rx_data = &stun_on_rx_data;
|
||||
stun_sock_cb.on_status = &stun_on_status;
|
||||
stun_sock_cb.on_data_sent = &stun_on_data_sent;
|
||||
|
||||
|
||||
/* Override component specific QoS settings, if any */
|
||||
if (ice_st->cfg.comp[comp_id-1].qos_type) {
|
||||
ice_st->cfg.stun.cfg.qos_type =
|
||||
ice_st->cfg.stun.cfg.qos_type =
|
||||
ice_st->cfg.comp[comp_id-1].qos_type;
|
||||
}
|
||||
if (ice_st->cfg.comp[comp_id-1].qos_params.flags) {
|
||||
|
@ -395,11 +395,11 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
|
||||
/* Override component specific socket buffer size settings, if any */
|
||||
if (ice_st->cfg.comp[comp_id-1].so_rcvbuf_size > 0) {
|
||||
ice_st->cfg.stun.cfg.so_rcvbuf_size =
|
||||
ice_st->cfg.stun.cfg.so_rcvbuf_size =
|
||||
ice_st->cfg.comp[comp_id-1].so_rcvbuf_size;
|
||||
}
|
||||
if (ice_st->cfg.comp[comp_id-1].so_sndbuf_size > 0) {
|
||||
ice_st->cfg.stun.cfg.so_sndbuf_size =
|
||||
ice_st->cfg.stun.cfg.so_sndbuf_size =
|
||||
ice_st->cfg.comp[comp_id-1].so_sndbuf_size;
|
||||
}
|
||||
|
||||
|
@ -411,8 +411,8 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Start STUN Binding resolution and add srflx candidate
|
||||
* only if server is set
|
||||
/* Start STUN Binding resolution and add srflx candidate
|
||||
* only if server is set
|
||||
*/
|
||||
if (ice_st->cfg.stun.server.slen) {
|
||||
pj_stun_sock_info stun_sock_info;
|
||||
|
@ -420,16 +420,16 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
/* Add pending job */
|
||||
///sess_add_ref(ice_st);
|
||||
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
"Comp %d: srflx candidate starts Binding discovery",
|
||||
comp_id));
|
||||
|
||||
pj_log_push_indent();
|
||||
|
||||
/* Start Binding resolution */
|
||||
status = pj_stun_sock_start(comp->stun_sock,
|
||||
status = pj_stun_sock_start(comp->stun_sock,
|
||||
&ice_st->cfg.stun.server,
|
||||
ice_st->cfg.stun.port,
|
||||
ice_st->cfg.stun.port,
|
||||
ice_st->cfg.resolver);
|
||||
if (status != PJ_SUCCESS) {
|
||||
///sess_dec_ref(ice_st);
|
||||
|
@ -475,8 +475,8 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
for (i=0; i<stun_sock_info.alias_cnt &&
|
||||
i<ice_st->cfg.stun.max_host_cands; ++i)
|
||||
for (i=0; i<stun_sock_info.alias_cnt &&
|
||||
i<ice_st->cfg.stun.max_host_cands; ++i)
|
||||
{
|
||||
char addrinfo[PJ_INET6_ADDRSTRLEN+10];
|
||||
const pj_sockaddr *addr = &stun_sock_info.aliases[i];
|
||||
|
@ -487,8 +487,8 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Ignore loopback addresses unless cfg->stun.loop_addr
|
||||
* is set
|
||||
/* Ignore loopback addresses unless cfg->stun.loop_addr
|
||||
* is set
|
||||
*/
|
||||
if ((pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127) {
|
||||
if (ice_st->cfg.stun.loop_addr==PJ_FALSE)
|
||||
|
@ -508,7 +508,7 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
pj_ice_calc_foundation(ice_st->pool, &cand->foundation,
|
||||
cand->type, &cand->base_addr);
|
||||
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
"Comp %d: host candidate %s added",
|
||||
comp_id, pj_sockaddr_print(&cand->addr, addrinfo,
|
||||
sizeof(addrinfo), 3)));
|
||||
|
@ -532,8 +532,8 @@ static pj_status_t create_comp(pj_ice_strans *ice_st, unsigned comp_id)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create ICE stream transport
|
||||
/*
|
||||
* Create ICE stream transport
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name,
|
||||
const pj_ice_strans_cfg *cfg,
|
||||
|
@ -564,7 +564,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name,
|
|||
ice_st->obj_name = pool->obj_name;
|
||||
ice_st->user_data = user_data;
|
||||
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
"Creating ICE stream transport with %d component(s)",
|
||||
comp_cnt));
|
||||
pj_log_push_indent();
|
||||
|
@ -586,13 +586,13 @@ PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name,
|
|||
pj_memcpy(&ice_st->cb, cb, sizeof(*cb));
|
||||
|
||||
ice_st->comp_cnt = comp_cnt;
|
||||
ice_st->comp = (pj_ice_strans_comp**)
|
||||
ice_st->comp = (pj_ice_strans_comp**)
|
||||
pj_pool_calloc(pool, comp_cnt, sizeof(pj_ice_strans_comp*));
|
||||
|
||||
/* Move state to candidate gathering */
|
||||
ice_st->state = PJ_ICE_STRANS_STATE_INIT;
|
||||
|
||||
/* Acquire initialization mutex to prevent callback to be
|
||||
/* Acquire initialization mutex to prevent callback to be
|
||||
* called before we finish initialization.
|
||||
*/
|
||||
pj_grp_lock_acquire(ice_st->grp_lock);
|
||||
|
@ -749,7 +749,7 @@ static void sess_init_update(pj_ice_strans *ice_st)
|
|||
ice_st->cb_called = PJ_TRUE;
|
||||
ice_st->state = PJ_ICE_STRANS_STATE_READY;
|
||||
if (ice_st->cb.on_ice_complete)
|
||||
(*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_INIT,
|
||||
(*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_INIT,
|
||||
PJ_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -785,7 +785,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_get_options( pj_ice_strans *ice_st,
|
|||
}
|
||||
|
||||
/*
|
||||
* Specify various options for this ICE stream transport.
|
||||
* Specify various options for this ICE stream transport.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_ice_strans_set_options(pj_ice_strans *ice_st,
|
||||
const pj_ice_sess_options *opt)
|
||||
|
@ -834,7 +834,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
|
|||
|
||||
/* Create! */
|
||||
status = pj_ice_sess_create(&ice_st->cfg.stun_cfg, ice_st->obj_name, role,
|
||||
ice_st->comp_cnt, &ice_cb,
|
||||
ice_st->comp_cnt, &ice_cb,
|
||||
local_ufrag, local_passwd,
|
||||
ice_st->grp_lock,
|
||||
&ice_st->ice);
|
||||
|
@ -852,7 +852,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
|
|||
* checked first.
|
||||
*/
|
||||
if (ice_st->comp[0]->default_cand >= 0 &&
|
||||
ice_st->comp[0]->cand_list[ice_st->comp[0]->default_cand].type
|
||||
ice_st->comp[0]->cand_list[ice_st->comp[0]->default_cand].type
|
||||
== PJ_ICE_CAND_TYPE_SRFLX)
|
||||
{
|
||||
pj_ice_sess_set_prefs(ice_st->ice, srflx_pref_table);
|
||||
|
@ -865,7 +865,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
|
|||
|
||||
/* Re-enable logging for Send/Data indications */
|
||||
if (comp->turn_sock) {
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
"Disabling STUN Indication logging for "
|
||||
"component %d", i+1));
|
||||
pj_turn_sock_set_log(comp->turn_sock, 0xFFFF);
|
||||
|
@ -878,7 +878,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
|
|||
|
||||
/* Skip if candidate is not ready */
|
||||
if (cand->status != PJ_SUCCESS) {
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
"Candidate %d of comp %d is not added (pending)",
|
||||
j, i));
|
||||
continue;
|
||||
|
@ -888,10 +888,10 @@ PJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
|
|||
pj_assert(pj_sockaddr_has_addr(&cand->addr));
|
||||
|
||||
/* Add the candidate */
|
||||
status = pj_ice_sess_add_cand(ice_st->ice, comp->comp_id,
|
||||
cand->transport_id, cand->type,
|
||||
cand->local_pref,
|
||||
&cand->foundation, &cand->addr,
|
||||
status = pj_ice_sess_add_cand(ice_st->ice, comp->comp_id,
|
||||
cand->transport_id, cand->type,
|
||||
cand->local_pref,
|
||||
&cand->foundation, &cand->addr,
|
||||
&cand->base_addr, &cand->rel_addr,
|
||||
pj_sockaddr_get_len(&cand->addr),
|
||||
(unsigned*)&ice_cand_id);
|
||||
|
@ -911,7 +911,7 @@ on_error:
|
|||
}
|
||||
|
||||
/*
|
||||
* Check if the ICE stream transport has the ICE session created.
|
||||
* Check if the ICE stream transport has the ICE session created.
|
||||
*/
|
||||
PJ_DEF(pj_bool_t) pj_ice_strans_has_sess(pj_ice_strans *ice_st)
|
||||
{
|
||||
|
@ -984,7 +984,7 @@ PJ_DEF(unsigned) pj_ice_strans_get_cands_count(pj_ice_strans *ice_st,
|
|||
{
|
||||
unsigned i, cnt;
|
||||
|
||||
PJ_ASSERT_RETURN(ice_st && ice_st->ice && comp_id &&
|
||||
PJ_ASSERT_RETURN(ice_st && ice_st->ice && comp_id &&
|
||||
comp_id <= ice_st->comp_cnt, 0);
|
||||
|
||||
cnt = 0;
|
||||
|
@ -1007,7 +1007,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_enum_cands(pj_ice_strans *ice_st,
|
|||
{
|
||||
unsigned i, cnt;
|
||||
|
||||
PJ_ASSERT_RETURN(ice_st && ice_st->ice && comp_id &&
|
||||
PJ_ASSERT_RETURN(ice_st && ice_st->ice && comp_id &&
|
||||
comp_id <= ice_st->comp_cnt && count && cand, PJ_EINVAL);
|
||||
|
||||
cnt = 0;
|
||||
|
@ -1041,7 +1041,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_get_def_cand( pj_ice_strans *ice_st,
|
|||
} else {
|
||||
pj_ice_strans_comp *comp = ice_st->comp[comp_id - 1];
|
||||
pj_assert(comp->default_cand>=0 && comp->default_cand<comp->cand_cnt);
|
||||
pj_memcpy(cand, &comp->cand_list[comp->default_cand],
|
||||
pj_memcpy(cand, &comp->cand_list[comp->default_cand],
|
||||
sizeof(pj_ice_sess_cand));
|
||||
}
|
||||
return PJ_SUCCESS;
|
||||
|
@ -1107,7 +1107,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_start_ice( pj_ice_strans *ice_st,
|
|||
}
|
||||
|
||||
if (count) {
|
||||
status = pj_turn_sock_set_perm(comp->turn_sock, count,
|
||||
status = pj_turn_sock_set_perm(comp->turn_sock, count,
|
||||
addrs, 0);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pj_ice_strans_stop_ice(ice_st);
|
||||
|
@ -1131,16 +1131,16 @@ PJ_DEF(pj_status_t) pj_ice_strans_start_ice( pj_ice_strans *ice_st,
|
|||
/*
|
||||
* Get valid pair.
|
||||
*/
|
||||
PJ_DEF(const pj_ice_sess_check*)
|
||||
PJ_DEF(const pj_ice_sess_check*)
|
||||
pj_ice_strans_get_valid_pair(const pj_ice_strans *ice_st,
|
||||
unsigned comp_id)
|
||||
{
|
||||
PJ_ASSERT_RETURN(ice_st && comp_id && comp_id <= ice_st->comp_cnt,
|
||||
NULL);
|
||||
|
||||
|
||||
if (ice_st->ice == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
return ice_st->ice->comp[comp_id-1].valid_check;
|
||||
}
|
||||
|
||||
|
@ -1170,7 +1170,6 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,
|
|||
const pj_sockaddr_t *dst_addr,
|
||||
int dst_addr_len)
|
||||
{
|
||||
pj_ssize_t pkt_size;
|
||||
pj_ice_strans_comp *comp;
|
||||
unsigned def_cand;
|
||||
pj_status_t status;
|
||||
|
@ -1219,25 +1218,24 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,
|
|||
|
||||
if (!comp->turn_log_off) {
|
||||
/* Disable logging for Send/Data indications */
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
"Disabling STUN Indication logging for "
|
||||
"component %d", comp->comp_id));
|
||||
pj_turn_sock_set_log(comp->turn_sock, msg_disable_ind);
|
||||
comp->turn_log_off = PJ_TRUE;
|
||||
}
|
||||
|
||||
status = pj_turn_sock_sendto(comp->turn_sock,
|
||||
(const pj_uint8_t*)data,
|
||||
status = pj_turn_sock_sendto(comp->turn_sock,
|
||||
(const pj_uint8_t*)data,
|
||||
(unsigned)data_len,
|
||||
dst_addr, dst_addr_len);
|
||||
return (status==PJ_SUCCESS||status==PJ_EPENDING) ?
|
||||
return (status==PJ_SUCCESS||status==PJ_EPENDING) ?
|
||||
PJ_SUCCESS : status;
|
||||
} else {
|
||||
pkt_size = data_len;
|
||||
status = pj_stun_sock_sendto(comp->stun_sock, NULL, data,
|
||||
(unsigned)data_len, 0, dst_addr,
|
||||
status = pj_stun_sock_sendto(comp->stun_sock, NULL, data,
|
||||
(unsigned)data_len, 0, dst_addr,
|
||||
dst_addr_len);
|
||||
return (status==PJ_SUCCESS||status==PJ_EPENDING) ?
|
||||
return (status==PJ_SUCCESS||status==PJ_EPENDING) ?
|
||||
PJ_SUCCESS : status;
|
||||
}
|
||||
|
||||
|
@ -1265,8 +1263,8 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
|
|||
if (status != PJ_SUCCESS) {
|
||||
char errmsg[PJ_ERR_MSG_SIZE];
|
||||
pj_strerror(status, errmsg, sizeof(errmsg));
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
"ICE negotiation failed after %ds:%03d: %s",
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
"ICE negotiation failed after %ds:%03d: %s",
|
||||
msec/1000, msec%1000, errmsg));
|
||||
} else {
|
||||
unsigned i;
|
||||
|
@ -1276,7 +1274,7 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
|
|||
PJ_STUN_SESS_LOG_RX_IND)
|
||||
};
|
||||
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
"ICE negotiation success after %ds:%03d",
|
||||
msec/1000, msec%1000));
|
||||
|
||||
|
@ -1288,9 +1286,9 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
|
|||
char lip[PJ_INET6_ADDRSTRLEN+10];
|
||||
char rip[PJ_INET6_ADDRSTRLEN+10];
|
||||
|
||||
pj_sockaddr_print(&check->lcand->addr, lip,
|
||||
pj_sockaddr_print(&check->lcand->addr, lip,
|
||||
sizeof(lip), 3);
|
||||
pj_sockaddr_print(&check->rcand->addr, rip,
|
||||
pj_sockaddr_print(&check->rcand->addr, rip,
|
||||
sizeof(rip), 3);
|
||||
|
||||
if (check->lcand->transport_id == TP_TURN) {
|
||||
|
@ -1303,7 +1301,7 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
|
|||
sizeof(check->rcand->addr));
|
||||
|
||||
/* Disable logging for Send/Data indications */
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
PJ_LOG(5,(ice_st->obj_name,
|
||||
"Disabling STUN Indication logging for "
|
||||
"component %d", i+1));
|
||||
pj_turn_sock_set_log(ice_st->comp[i]->turn_sock,
|
||||
|
@ -1314,14 +1312,14 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
|
|||
PJ_LOG(4,(ice_st->obj_name, " Comp %d: "
|
||||
"sending from %s candidate %s to "
|
||||
"%s candidate %s",
|
||||
i+1,
|
||||
i+1,
|
||||
pj_ice_get_cand_type_name(check->lcand->type),
|
||||
lip,
|
||||
pj_ice_get_cand_type_name(check->rcand->type),
|
||||
rip));
|
||||
|
||||
|
||||
} else {
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
PJ_LOG(4,(ice_st->obj_name,
|
||||
"Comp %d: disabled", i+1));
|
||||
}
|
||||
}
|
||||
|
@ -1331,10 +1329,10 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
|
|||
PJ_ICE_STRANS_STATE_FAILED;
|
||||
|
||||
pj_log_push_indent();
|
||||
(*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_NEGOTIATION,
|
||||
(*ice_st->cb.on_ice_complete)(ice_st, PJ_ICE_STRANS_OP_NEGOTIATION,
|
||||
status);
|
||||
pj_log_pop_indent();
|
||||
|
||||
|
||||
}
|
||||
|
||||
pj_grp_lock_dec_ref(ice_st->grp_lock);
|
||||
|
@ -1343,8 +1341,8 @@ static void on_ice_complete(pj_ice_sess *ice, pj_status_t status)
|
|||
/*
|
||||
* Callback called by ICE session when it wants to send outgoing packet.
|
||||
*/
|
||||
static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
|
||||
unsigned comp_id,
|
||||
static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
|
||||
unsigned comp_id,
|
||||
unsigned transport_id,
|
||||
const void *pkt, pj_size_t size,
|
||||
const pj_sockaddr_t *dst_addr,
|
||||
|
@ -1361,39 +1359,39 @@ static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
|
|||
|
||||
comp = ice_st->comp[comp_id-1];
|
||||
|
||||
TRACE_PKT((comp->ice_st->obj_name,
|
||||
TRACE_PKT((comp->ice_st->obj_name,
|
||||
"Component %d TX packet to %s:%d with transport %d",
|
||||
comp_id,
|
||||
comp_id,
|
||||
pj_sockaddr_print(dst_addr, daddr, sizeof(addr), 0),
|
||||
pj_sockaddr_get_port(dst_addr),
|
||||
transport_id));
|
||||
|
||||
if (transport_id == TP_TURN) {
|
||||
if (comp->turn_sock) {
|
||||
status = pj_turn_sock_sendto(comp->turn_sock,
|
||||
(const pj_uint8_t*)pkt,
|
||||
status = pj_turn_sock_sendto(comp->turn_sock,
|
||||
(const pj_uint8_t*)pkt,
|
||||
(unsigned)size,
|
||||
dst_addr, dst_addr_len);
|
||||
} else {
|
||||
status = PJ_EINVALIDOP;
|
||||
}
|
||||
} else if (transport_id == TP_STUN) {
|
||||
status = pj_stun_sock_sendto(comp->stun_sock, NULL,
|
||||
status = pj_stun_sock_sendto(comp->stun_sock, NULL,
|
||||
pkt, (unsigned)size, 0,
|
||||
dst_addr, dst_addr_len);
|
||||
} else {
|
||||
pj_assert(!"Invalid transport ID");
|
||||
status = PJ_EINVALIDOP;
|
||||
}
|
||||
|
||||
|
||||
return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback called by ICE session when it receives application data.
|
||||
*/
|
||||
static void ice_rx_data(pj_ice_sess *ice,
|
||||
unsigned comp_id,
|
||||
static void ice_rx_data(pj_ice_sess *ice,
|
||||
unsigned comp_id,
|
||||
unsigned transport_id,
|
||||
void *pkt, pj_size_t size,
|
||||
const pj_sockaddr_t *src_addr,
|
||||
|
@ -1404,13 +1402,13 @@ static void ice_rx_data(pj_ice_sess *ice,
|
|||
PJ_UNUSED_ARG(transport_id);
|
||||
|
||||
if (ice_st->cb.on_rx_data) {
|
||||
(*ice_st->cb.on_rx_data)(ice_st, comp_id, pkt, size,
|
||||
(*ice_st->cb.on_rx_data)(ice_st, comp_id, pkt, size,
|
||||
src_addr, src_addr_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Notification when incoming packet has been received from
|
||||
* the STUN socket.
|
||||
* the STUN socket.
|
||||
*/
|
||||
static pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock,
|
||||
void *pkt,
|
||||
|
@ -1438,19 +1436,19 @@ static pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock,
|
|||
* report this to application.
|
||||
*/
|
||||
if (ice_st->cb.on_rx_data) {
|
||||
(*ice_st->cb.on_rx_data)(ice_st, comp->comp_id, pkt, pkt_len,
|
||||
(*ice_st->cb.on_rx_data)(ice_st, comp->comp_id, pkt, pkt_len,
|
||||
src_addr, addr_len);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* Hand over the packet to ICE session */
|
||||
status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,
|
||||
status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,
|
||||
TP_STUN, pkt, pkt_len,
|
||||
src_addr, addr_len);
|
||||
|
||||
if (status != PJ_SUCCESS) {
|
||||
ice_st_perror(comp->ice_st, "Error processing packet",
|
||||
ice_st_perror(comp->ice_st, "Error processing packet",
|
||||
status);
|
||||
}
|
||||
}
|
||||
|
@ -1459,7 +1457,7 @@ static pj_bool_t stun_on_rx_data(pj_stun_sock *stun_sock,
|
|||
}
|
||||
|
||||
/* Notifification when asynchronous send operation to the STUN socket
|
||||
* has completed.
|
||||
* has completed.
|
||||
*/
|
||||
static pj_bool_t stun_on_data_sent(pj_stun_sock *stun_sock,
|
||||
pj_ioqueue_op_key_t *send_key,
|
||||
|
@ -1472,7 +1470,7 @@ static pj_bool_t stun_on_data_sent(pj_stun_sock *stun_sock,
|
|||
}
|
||||
|
||||
/* Notification when the status of the STUN transport has changed. */
|
||||
static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
|
||||
static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
|
||||
pj_stun_sock_op op,
|
||||
pj_status_t status)
|
||||
{
|
||||
|
@ -1572,11 +1570,11 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
|
|||
cand->status = PJ_SUCCESS;
|
||||
}
|
||||
|
||||
PJ_LOG(4,(comp->ice_st->obj_name,
|
||||
PJ_LOG(4,(comp->ice_st->obj_name,
|
||||
"Comp %d: %s, "
|
||||
"srflx address is %s",
|
||||
comp->comp_id, op_name,
|
||||
pj_sockaddr_print(&info.mapped_addr, ipaddr,
|
||||
comp->comp_id, op_name,
|
||||
pj_sockaddr_print(&info.mapped_addr, ipaddr,
|
||||
sizeof(ipaddr), 3)));
|
||||
|
||||
sess_init_update(ice_st);
|
||||
|
@ -1662,8 +1660,8 @@ static void turn_on_rx_data(pj_turn_sock *turn_sock,
|
|||
peer_addr, addr_len);
|
||||
|
||||
if (status != PJ_SUCCESS) {
|
||||
ice_st_perror(comp->ice_st,
|
||||
"Error processing packet from TURN relay",
|
||||
ice_st_perror(comp->ice_st,
|
||||
"Error processing packet from TURN relay",
|
||||
status);
|
||||
}
|
||||
}
|
||||
|
@ -1721,18 +1719,18 @@ static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state,
|
|||
pj_sockaddr_cp(&cand->addr, &rel_info.relay_addr);
|
||||
pj_sockaddr_cp(&cand->base_addr, &rel_info.relay_addr);
|
||||
pj_sockaddr_cp(&cand->rel_addr, &rel_info.mapped_addr);
|
||||
pj_ice_calc_foundation(comp->ice_st->pool, &cand->foundation,
|
||||
PJ_ICE_CAND_TYPE_RELAYED,
|
||||
pj_ice_calc_foundation(comp->ice_st->pool, &cand->foundation,
|
||||
PJ_ICE_CAND_TYPE_RELAYED,
|
||||
&rel_info.relay_addr);
|
||||
cand->status = PJ_SUCCESS;
|
||||
|
||||
/* Set default candidate to relay */
|
||||
comp->default_cand = (unsigned)(cand - comp->cand_list);
|
||||
|
||||
PJ_LOG(4,(comp->ice_st->obj_name,
|
||||
PJ_LOG(4,(comp->ice_st->obj_name,
|
||||
"Comp %d: TURN allocation complete, relay address is %s",
|
||||
comp->comp_id,
|
||||
pj_sockaddr_print(&rel_info.relay_addr, ipaddr,
|
||||
comp->comp_id,
|
||||
pj_sockaddr_print(&rel_info.relay_addr, ipaddr,
|
||||
sizeof(ipaddr), 3)));
|
||||
|
||||
sess_init_update(comp->ice_st);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "turn.h"
|
||||
#include "auth.h"
|
||||
|
@ -62,8 +62,8 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
const alloc_request *req,
|
||||
pj_turn_relay_res *relay);
|
||||
static void destroy_relay(pj_turn_relay_res *relay);
|
||||
static void on_rx_from_peer(pj_ioqueue_key_t *key,
|
||||
pj_ioqueue_op_key_t *op_key,
|
||||
static void on_rx_from_peer(pj_ioqueue_key_t *key,
|
||||
pj_ioqueue_op_key_t *op_key,
|
||||
pj_ssize_t bytes_read);
|
||||
static pj_status_t stun_on_send_msg(pj_stun_session *sess,
|
||||
void *token,
|
||||
|
@ -124,7 +124,7 @@ static pj_status_t parse_allocate_req(alloc_request *cfg,
|
|||
|
||||
/* Check if we can satisfy the bandwidth */
|
||||
if (cfg->bandwidth > MAX_CLIENT_BANDWIDTH) {
|
||||
pj_stun_session_respond(sess, rdata,
|
||||
pj_stun_session_respond(sess, rdata,
|
||||
PJ_STUN_SC_ALLOCATION_QUOTA_REACHED,
|
||||
"Invalid bandwidth", NULL, PJ_TRUE,
|
||||
src_addr, src_addr_len);
|
||||
|
@ -136,7 +136,7 @@ static pj_status_t parse_allocate_req(alloc_request *cfg,
|
|||
pj_stun_msg_find_attr(req, PJ_STUN_ATTR_REQ_TRANSPORT, 0);
|
||||
if (attr_req_tp == NULL) {
|
||||
pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,
|
||||
"Missing REQUESTED-TRANSPORT attribute",
|
||||
"Missing REQUESTED-TRANSPORT attribute",
|
||||
NULL, PJ_TRUE, src_addr, src_addr_len);
|
||||
return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);
|
||||
}
|
||||
|
@ -156,9 +156,9 @@ static pj_status_t parse_allocate_req(alloc_request *cfg,
|
|||
0);
|
||||
if (attr_res_token) {
|
||||
/* We don't support RESERVATION-TOKEN for now */
|
||||
pj_stun_session_respond(sess, rdata,
|
||||
pj_stun_session_respond(sess, rdata,
|
||||
PJ_STUN_SC_BAD_REQUEST,
|
||||
"RESERVATION-TOKEN is not supported", NULL,
|
||||
"RESERVATION-TOKEN is not supported", NULL,
|
||||
PJ_TRUE, src_addr, src_addr_len);
|
||||
return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ static pj_status_t parse_allocate_req(alloc_request *cfg,
|
|||
cfg->lifetime = attr_lifetime->value;
|
||||
if (cfg->lifetime < MIN_LIFETIME) {
|
||||
pj_stun_session_respond(sess, rdata, PJ_STUN_SC_BAD_REQUEST,
|
||||
"LIFETIME too short", NULL,
|
||||
"LIFETIME too short", NULL,
|
||||
PJ_TRUE, src_addr, src_addr_len);
|
||||
return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_BAD_REQUEST);
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ static pj_status_t send_allocate_response(pj_turn_allocation *alloc,
|
|||
|
||||
/* Add LIFETIME. */
|
||||
pj_stun_msg_add_uint_attr(tdata->pool, tdata->msg,
|
||||
PJ_STUN_ATTR_LIFETIME,
|
||||
PJ_STUN_ATTR_LIFETIME,
|
||||
(unsigned)alloc->relay.lifetime);
|
||||
|
||||
/* Add BANDWIDTH */
|
||||
|
@ -222,10 +222,10 @@ static pj_status_t send_allocate_response(pj_turn_allocation *alloc,
|
|||
PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE,
|
||||
&alloc->hkey.clt_addr,
|
||||
pj_sockaddr_get_len(&alloc->hkey.clt_addr));
|
||||
|
||||
|
||||
/* Send the response */
|
||||
return pj_stun_session_send_msg(srv_sess, transport, PJ_TRUE,
|
||||
PJ_FALSE, &alloc->hkey.clt_addr,
|
||||
PJ_FALSE, &alloc->hkey.clt_addr,
|
||||
pj_sockaddr_get_len(&alloc->hkey.clt_addr),
|
||||
tdata);
|
||||
}
|
||||
|
@ -255,9 +255,9 @@ static pj_status_t init_cred(pj_turn_allocation *alloc, const pj_stun_msg *req)
|
|||
PJ_ASSERT_RETURN(nonce != NULL, PJ_EBUG);
|
||||
|
||||
/* Lookup the password */
|
||||
status = pj_turn_get_password(NULL, NULL, &realm->value,
|
||||
&user->value, alloc->pool,
|
||||
&alloc->cred.data.static_cred.data_type,
|
||||
status = pj_turn_get_password(NULL, NULL, &realm->value,
|
||||
&user->value, alloc->pool,
|
||||
&alloc->cred.data.static_cred.data_type,
|
||||
&alloc->cred.data.static_cred.data);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
@ -314,7 +314,7 @@ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,
|
|||
alloc->hkey.tp_type = transport->listener->tp_type;
|
||||
pj_memcpy(&alloc->hkey.clt_addr, src_addr, src_addr_len);
|
||||
|
||||
status = pj_lock_create_recursive_mutex(pool, alloc->obj_name,
|
||||
status = pj_lock_create_recursive_mutex(pool, alloc->obj_name,
|
||||
&alloc->lock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_error;
|
||||
|
@ -327,7 +327,7 @@ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,
|
|||
alloc->ch_table = pj_hash_create(pool, PEER_TABLE_SIZE);
|
||||
|
||||
/* Print info */
|
||||
pj_ansi_strcpy(alloc->info,
|
||||
pj_ansi_strcpy(alloc->info,
|
||||
pj_turn_tp_type_name(transport->listener->tp_type));
|
||||
alloc->info[3] = ':';
|
||||
pj_sockaddr_print(src_addr, alloc->info+4, sizeof(alloc->info)-4, 3);
|
||||
|
@ -371,9 +371,9 @@ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,
|
|||
goto on_error;
|
||||
|
||||
/* Done */
|
||||
pj_sockaddr_print(&alloc->relay.hkey.addr, str_tmp,
|
||||
pj_sockaddr_print(&alloc->relay.hkey.addr, str_tmp,
|
||||
sizeof(str_tmp), 3);
|
||||
PJ_LOG(4,(alloc->obj_name, "Client %s created, relay addr=%s:%s",
|
||||
PJ_LOG(4,(alloc->obj_name, "Client %s created, relay addr=%s:%s",
|
||||
alloc->info, pj_turn_tp_type_name(req.tp_type), str_tmp));
|
||||
|
||||
/* Success */
|
||||
|
@ -383,7 +383,7 @@ PJ_DEF(pj_status_t) pj_turn_allocation_create(pj_turn_transport *transport,
|
|||
on_error:
|
||||
/* Send reply to the ALLOCATE request */
|
||||
pj_strerror(status, str_tmp, sizeof(str_tmp));
|
||||
pj_stun_session_respond(srv_sess, rdata, PJ_STUN_SC_BAD_REQUEST, str_tmp,
|
||||
pj_stun_session_respond(srv_sess, rdata, PJ_STUN_SC_BAD_REQUEST, str_tmp,
|
||||
transport, PJ_TRUE, src_addr, src_addr_len);
|
||||
|
||||
/* Cleanup */
|
||||
|
@ -396,7 +396,7 @@ on_error:
|
|||
static void destroy_relay(pj_turn_relay_res *relay)
|
||||
{
|
||||
if (relay->timer.id) {
|
||||
pj_timer_heap_cancel(relay->allocation->server->core.timer_heap,
|
||||
pj_timer_heap_cancel(relay->allocation->server->core.timer_heap,
|
||||
&relay->timer);
|
||||
relay->timer.id = PJ_FALSE;
|
||||
}
|
||||
|
@ -482,8 +482,8 @@ PJ_DEF(void) pj_turn_allocation_on_transport_closed( pj_turn_allocation *alloc,
|
|||
|
||||
|
||||
/* Initiate shutdown sequence for this allocation and start destroy timer.
|
||||
* Once allocation is marked as shutting down, any packets will be
|
||||
* rejected/discarded
|
||||
* Once allocation is marked as shutting down, any packets will be
|
||||
* rejected/discarded
|
||||
*/
|
||||
static void alloc_shutdown(pj_turn_allocation *alloc)
|
||||
{
|
||||
|
@ -501,7 +501,7 @@ static void alloc_shutdown(pj_turn_allocation *alloc)
|
|||
* shutdown request.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pj_assert(alloc->relay.timer.id == TIMER_ID_NONE);
|
||||
|
||||
|
@ -530,7 +530,7 @@ static pj_status_t resched_timeout(pj_turn_allocation *alloc)
|
|||
|
||||
pj_assert(alloc->relay.timer.id != TIMER_ID_DESTROY);
|
||||
if (alloc->relay.timer.id != 0) {
|
||||
pj_timer_heap_cancel(alloc->server->core.timer_heap,
|
||||
pj_timer_heap_cancel(alloc->server->core.timer_heap,
|
||||
&alloc->relay.timer);
|
||||
alloc->relay.timer.id = TIMER_ID_NONE;
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ static pj_status_t resched_timeout(pj_turn_allocation *alloc)
|
|||
delay.msec = 0;
|
||||
|
||||
alloc->relay.timer.id = TIMER_ID_TIMEOUT;
|
||||
status = pj_timer_heap_schedule(alloc->server->core.timer_heap,
|
||||
status = pj_timer_heap_schedule(alloc->server->core.timer_heap,
|
||||
&alloc->relay.timer, &delay);
|
||||
if (status != PJ_SUCCESS) {
|
||||
alloc->relay.timer.id = TIMER_ID_NONE;
|
||||
|
@ -565,8 +565,8 @@ static void relay_timeout_cb(pj_timer_heap_t *heap, pj_timer_entry *e)
|
|||
|
||||
e->id = TIMER_ID_NONE;
|
||||
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
"Client %s refresh timed-out, shutting down..",
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
"Client %s refresh timed-out, shutting down..",
|
||||
alloc->info));
|
||||
|
||||
alloc_shutdown(alloc);
|
||||
|
@ -574,7 +574,7 @@ static void relay_timeout_cb(pj_timer_heap_t *heap, pj_timer_entry *e)
|
|||
} else if (e->id == TIMER_ID_DESTROY) {
|
||||
e->id = TIMER_ID_NONE;
|
||||
|
||||
PJ_LOG(4,(alloc->obj_name, "Client %s destroying..",
|
||||
PJ_LOG(4,(alloc->obj_name, "Client %s destroying..",
|
||||
alloc->info));
|
||||
|
||||
destroy_allocation(alloc);
|
||||
|
@ -600,10 +600,10 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
pj_status_t status;
|
||||
|
||||
pj_bzero(relay, sizeof(*relay));
|
||||
|
||||
|
||||
relay->allocation = alloc;
|
||||
relay->tp.sock = PJ_INVALID_SOCKET;
|
||||
|
||||
|
||||
/* TODO: get the requested address family from somewhere */
|
||||
af = alloc->transport->listener->addr.addr.sa_family;
|
||||
|
||||
|
@ -621,10 +621,10 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
|
||||
/* Lifetime and timeout */
|
||||
relay->lifetime = req->lifetime;
|
||||
pj_timer_entry_init(&relay->timer, TIMER_ID_NONE, relay,
|
||||
pj_timer_entry_init(&relay->timer, TIMER_ID_NONE, relay,
|
||||
&relay_timeout_cb);
|
||||
resched_timeout(alloc);
|
||||
|
||||
|
||||
/* Transport type */
|
||||
relay->hkey.tp_type = req->tp_type;
|
||||
|
||||
|
@ -676,7 +676,7 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
|
||||
pj_sockaddr_init(af, &bound_addr, NULL, port);
|
||||
|
||||
status = pj_sock_bind(relay->tp.sock, &bound_addr,
|
||||
status = pj_sock_bind(relay->tp.sock, &bound_addr,
|
||||
pj_sockaddr_get_len(&bound_addr));
|
||||
if (status == PJ_SUCCESS)
|
||||
break;
|
||||
|
@ -684,7 +684,7 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
|
||||
if (status != PJ_SUCCESS) {
|
||||
/* Unable to allocate port */
|
||||
PJ_LOG(4,(THIS_FILE, "Unable to allocate relay, giving up: err %d",
|
||||
PJ_LOG(4,(THIS_FILE, "Unable to allocate relay, giving up: err %d",
|
||||
status));
|
||||
pj_sock_close(relay->tp.sock);
|
||||
relay->tp.sock = PJ_INVALID_SOCKET;
|
||||
|
@ -695,14 +695,14 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
namelen = sizeof(relay->hkey.addr);
|
||||
status = pj_sock_getsockname(relay->tp.sock, &relay->hkey.addr, &namelen);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_LOG(4,(THIS_FILE, "pj_sock_getsockname() failed: err %d",
|
||||
PJ_LOG(4,(THIS_FILE, "pj_sock_getsockname() failed: err %d",
|
||||
status));
|
||||
pj_sock_close(relay->tp.sock);
|
||||
relay->tp.sock = PJ_INVALID_SOCKET;
|
||||
return status;
|
||||
}
|
||||
if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {
|
||||
pj_sockaddr_copy_addr(&relay->hkey.addr,
|
||||
pj_sockaddr_copy_addr(&relay->hkey.addr,
|
||||
&alloc->transport->listener->addr);
|
||||
}
|
||||
if (!pj_sockaddr_has_addr(&relay->hkey.addr)) {
|
||||
|
@ -718,7 +718,7 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
status = pj_ioqueue_register_sock(pool, srv->core.ioqueue, relay->tp.sock,
|
||||
relay, &icb, &relay->tp.key);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_LOG(4,(THIS_FILE, "pj_ioqueue_register_sock() failed: err %d",
|
||||
PJ_LOG(4,(THIS_FILE, "pj_ioqueue_register_sock() failed: err %d",
|
||||
status));
|
||||
pj_sock_close(relay->tp.sock);
|
||||
relay->tp.sock = PJ_INVALID_SOCKET;
|
||||
|
@ -736,12 +736,12 @@ static pj_status_t create_relay(pj_turn_srv *srv,
|
|||
/* Create and send error response */
|
||||
static void send_reply_err(pj_turn_allocation *alloc,
|
||||
const pj_stun_rx_data *rdata,
|
||||
pj_bool_t cache,
|
||||
pj_bool_t cache,
|
||||
int code, const char *errmsg)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
||||
status = pj_stun_session_respond(alloc->sess, rdata, code, errmsg, NULL,
|
||||
status = pj_stun_session_respond(alloc->sess, rdata, code, errmsg, NULL,
|
||||
cache, &alloc->hkey.clt_addr,
|
||||
pj_sockaddr_get_len(&alloc->hkey.clt_addr.addr));
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -786,9 +786,9 @@ static void send_reply_ok(pj_turn_allocation *alloc,
|
|||
}
|
||||
}
|
||||
|
||||
status = pj_stun_session_send_msg(alloc->sess, NULL, PJ_TRUE,
|
||||
PJ_FALSE, &alloc->hkey.clt_addr,
|
||||
pj_sockaddr_get_len(&alloc->hkey.clt_addr),
|
||||
status = pj_stun_session_send_msg(alloc->sess, NULL, PJ_TRUE,
|
||||
PJ_FALSE, &alloc->hkey.clt_addr,
|
||||
pj_sockaddr_get_len(&alloc->hkey.clt_addr),
|
||||
tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
alloc_err(alloc, "Error sending STUN success response", status);
|
||||
|
@ -806,7 +806,7 @@ static pj_turn_permission *create_permission(pj_turn_allocation *alloc,
|
|||
|
||||
perm = PJ_POOL_ZALLOC_T(alloc->pool, pj_turn_permission);
|
||||
pj_memcpy(&perm->hkey.peer_addr, peer_addr, addr_len);
|
||||
|
||||
|
||||
perm->allocation = alloc;
|
||||
perm->channel = PJ_TURN_INVALID_CHANNEL;
|
||||
|
||||
|
@ -814,8 +814,8 @@ static pj_turn_permission *create_permission(pj_turn_allocation *alloc,
|
|||
perm->expiry.sec += PJ_TURN_PERM_TIMEOUT;
|
||||
|
||||
/* Register to hash table (only the address part!) */
|
||||
pj_hash_set(alloc->pool, alloc->peer_table,
|
||||
pj_sockaddr_get_addr(&perm->hkey.peer_addr),
|
||||
pj_hash_set(alloc->pool, alloc->peer_table,
|
||||
pj_sockaddr_get_addr(&perm->hkey.peer_addr),
|
||||
pj_sockaddr_get_addr_len(&perm->hkey.peer_addr), 0, perm);
|
||||
|
||||
return perm;
|
||||
|
@ -834,13 +834,13 @@ static pj_turn_permission *check_permission_expiry(pj_turn_permission *perm)
|
|||
}
|
||||
|
||||
/* Remove from permission hash table */
|
||||
pj_hash_set(NULL, alloc->peer_table,
|
||||
pj_sockaddr_get_addr(&perm->hkey.peer_addr),
|
||||
pj_hash_set(NULL, alloc->peer_table,
|
||||
pj_sockaddr_get_addr(&perm->hkey.peer_addr),
|
||||
pj_sockaddr_get_addr_len(&perm->hkey.peer_addr), 0, NULL);
|
||||
|
||||
/* Remove from channel hash table, if assigned a channel number */
|
||||
if (perm->channel != PJ_TURN_INVALID_CHANNEL) {
|
||||
pj_hash_set(NULL, alloc->ch_table, &perm->channel,
|
||||
pj_hash_set(NULL, alloc->ch_table, &perm->channel,
|
||||
sizeof(perm->channel), 0, NULL);
|
||||
}
|
||||
|
||||
|
@ -858,10 +858,10 @@ lookup_permission_by_addr(pj_turn_allocation *alloc,
|
|||
PJ_UNUSED_ARG(addr_len);
|
||||
|
||||
/* Lookup in peer hash table */
|
||||
perm = (pj_turn_permission*)
|
||||
pj_hash_get(alloc->peer_table,
|
||||
perm = (pj_turn_permission*)
|
||||
pj_hash_get(alloc->peer_table,
|
||||
pj_sockaddr_get_addr(peer_addr),
|
||||
pj_sockaddr_get_addr_len(peer_addr),
|
||||
pj_sockaddr_get_addr_len(peer_addr),
|
||||
NULL);
|
||||
return perm ? check_permission_expiry(perm) : NULL;
|
||||
}
|
||||
|
@ -880,7 +880,7 @@ lookup_permission_by_chnum(pj_turn_allocation *alloc,
|
|||
return perm ? check_permission_expiry(perm) : NULL;
|
||||
}
|
||||
|
||||
/* Update permission because of data from client to peer.
|
||||
/* Update permission because of data from client to peer.
|
||||
* Return PJ_TRUE is permission is found.
|
||||
*/
|
||||
static pj_bool_t refresh_permission(pj_turn_permission *perm)
|
||||
|
@ -916,7 +916,7 @@ PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
|
|||
* our stun_on_rx_request() or stun_on_rx_indication()
|
||||
* callbacks.
|
||||
*
|
||||
* Note: currently it is necessary to specify the
|
||||
* Note: currently it is necessary to specify the
|
||||
* PJ_STUN_NO_FINGERPRINT_CHECK otherwise the FINGERPRINT
|
||||
* attribute inside STUN Send Indication message will mess up
|
||||
* with fingerprint checking.
|
||||
|
@ -929,7 +929,7 @@ PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
|
|||
|
||||
status = pj_stun_session_on_rx_pkt(alloc->sess, pkt->pkt, pkt->len,
|
||||
options, NULL, &parsed_len,
|
||||
&pkt->src.clt_addr,
|
||||
&pkt->src.clt_addr,
|
||||
pkt->src_addr_len);
|
||||
|
||||
if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) {
|
||||
|
@ -962,7 +962,7 @@ PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
|
|||
/* For UDP check the packet length */
|
||||
if (alloc->transport->listener->tp_type == PJ_TURN_TP_UDP) {
|
||||
if (pkt->len < pj_ntohs(cd->length)+sizeof(*cd)) {
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
"ChannelData from %s discarded: UDP size error",
|
||||
alloc->info));
|
||||
goto on_return;
|
||||
|
@ -975,7 +975,7 @@ PJ_DEF(void) pj_turn_allocation_on_rx_client_pkt(pj_turn_allocation *alloc,
|
|||
perm = lookup_permission_by_chnum(alloc, pj_ntohs(cd->ch_number));
|
||||
if (!perm) {
|
||||
/* Discard */
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
"ChannelData from %s discarded: ch#0x%x not found",
|
||||
alloc->info, pj_ntohs(cd->ch_number)));
|
||||
goto on_return;
|
||||
|
@ -998,7 +998,7 @@ on_return:
|
|||
|
||||
|
||||
/*
|
||||
* Handle incoming packet from peer. This function is called by
|
||||
* Handle incoming packet from peer. This function is called by
|
||||
* on_rx_from_peer().
|
||||
*/
|
||||
static void handle_peer_pkt(pj_turn_allocation *alloc,
|
||||
|
@ -1009,7 +1009,7 @@ static void handle_peer_pkt(pj_turn_allocation *alloc,
|
|||
pj_turn_permission *perm;
|
||||
|
||||
/* Lookup permission */
|
||||
perm = lookup_permission_by_addr(alloc, src_addr,
|
||||
perm = lookup_permission_by_addr(alloc, src_addr,
|
||||
pj_sockaddr_get_len(src_addr));
|
||||
if (perm == NULL) {
|
||||
/* No permission, discard data */
|
||||
|
@ -1049,23 +1049,23 @@ static void handle_peer_pkt(pj_turn_allocation *alloc,
|
|||
pj_stun_tx_data *tdata;
|
||||
pj_status_t status;
|
||||
|
||||
status = pj_stun_session_create_ind(alloc->sess,
|
||||
status = pj_stun_session_create_ind(alloc->sess,
|
||||
PJ_STUN_DATA_INDICATION, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
alloc_err(alloc, "Error creating Data indication", status);
|
||||
return;
|
||||
}
|
||||
|
||||
pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
|
||||
pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
|
||||
PJ_STUN_ATTR_XOR_PEER_ADDR, PJ_TRUE,
|
||||
src_addr, pj_sockaddr_get_len(src_addr));
|
||||
pj_stun_msg_add_binary_attr(tdata->pool, tdata->msg,
|
||||
PJ_STUN_ATTR_DATA,
|
||||
PJ_STUN_ATTR_DATA,
|
||||
(const pj_uint8_t*)pkt, len);
|
||||
|
||||
pj_stun_session_send_msg(alloc->sess, NULL, PJ_FALSE,
|
||||
PJ_FALSE, &alloc->hkey.clt_addr,
|
||||
pj_sockaddr_get_len(&alloc->hkey.clt_addr),
|
||||
pj_stun_session_send_msg(alloc->sess, NULL, PJ_FALSE,
|
||||
PJ_FALSE, &alloc->hkey.clt_addr,
|
||||
pj_sockaddr_get_len(&alloc->hkey.clt_addr),
|
||||
tdata);
|
||||
}
|
||||
}
|
||||
|
@ -1073,8 +1073,8 @@ static void handle_peer_pkt(pj_turn_allocation *alloc,
|
|||
/*
|
||||
* ioqueue notification on RX packets from the relay socket.
|
||||
*/
|
||||
static void on_rx_from_peer(pj_ioqueue_key_t *key,
|
||||
pj_ioqueue_op_key_t *op_key,
|
||||
static void on_rx_from_peer(pj_ioqueue_key_t *key,
|
||||
pj_ioqueue_op_key_t *op_key,
|
||||
pj_ssize_t bytes_read)
|
||||
{
|
||||
pj_turn_relay_res *rel;
|
||||
|
@ -1096,7 +1096,7 @@ static void on_rx_from_peer(pj_ioqueue_key_t *key,
|
|||
rel->tp.src_addr_len = sizeof(rel->tp.src_addr);
|
||||
status = pj_ioqueue_recvfrom(key, op_key,
|
||||
rel->tp.rx_pkt, &bytes_read, 0,
|
||||
&rel->tp.src_addr,
|
||||
&rel->tp.src_addr,
|
||||
&rel->tp.src_addr_len);
|
||||
|
||||
if (status != PJ_EPENDING && status != PJ_SUCCESS)
|
||||
|
@ -1156,14 +1156,14 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
/* Refuse to serve any request if we've been shutdown */
|
||||
if (alloc->relay.lifetime == 0) {
|
||||
/* Reject with 437 if we're shutting down */
|
||||
send_reply_err(alloc, rdata, PJ_TRUE,
|
||||
send_reply_err(alloc, rdata, PJ_TRUE,
|
||||
PJ_STUN_SC_ALLOCATION_MISMATCH, NULL);
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
if (msg->hdr.type == PJ_STUN_REFRESH_REQUEST) {
|
||||
/*
|
||||
* Handle REFRESH request
|
||||
/*
|
||||
* Handle REFRESH request
|
||||
*/
|
||||
pj_stun_lifetime_attr *lifetime;
|
||||
pj_stun_bandwidth_attr *bandwidth;
|
||||
|
@ -1176,6 +1176,9 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
bandwidth = (pj_stun_bandwidth_attr*)
|
||||
pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_BANDWIDTH, 0);
|
||||
|
||||
/* TODO: process bandwidth */
|
||||
PJ_UNUSED_ARG(bandwidth);
|
||||
|
||||
if (lifetime && lifetime->value==0) {
|
||||
/*
|
||||
* This is deallocation request.
|
||||
|
@ -1186,7 +1189,7 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
send_reply_ok(alloc, rdata);
|
||||
|
||||
/* Shutdown allocation */
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
PJ_LOG(4,(alloc->obj_name,
|
||||
"Client %s request to dealloc, shutting down",
|
||||
alloc->info));
|
||||
|
||||
|
@ -1196,7 +1199,7 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
/*
|
||||
* This is a refresh request.
|
||||
*/
|
||||
|
||||
|
||||
/* Update lifetime */
|
||||
if (lifetime) {
|
||||
alloc->relay.lifetime = lifetime->value;
|
||||
|
@ -1226,7 +1229,7 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_PEER_ADDR, 0);
|
||||
|
||||
if (!ch_attr || !peer_attr) {
|
||||
send_reply_err(alloc, rdata, PJ_TRUE,
|
||||
send_reply_err(alloc, rdata, PJ_TRUE,
|
||||
PJ_STUN_SC_BAD_REQUEST, NULL);
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
@ -1234,14 +1237,14 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
/* Find permission with the channel number */
|
||||
p1 = lookup_permission_by_chnum(alloc, PJ_STUN_GET_CH_NB(ch_attr->value));
|
||||
|
||||
/* If permission is found, this is supposed to be a channel bind
|
||||
/* If permission is found, this is supposed to be a channel bind
|
||||
* refresh. Make sure it's for the same peer.
|
||||
*/
|
||||
if (p1) {
|
||||
if (pj_sockaddr_cmp(&p1->hkey.peer_addr, &peer_attr->sockaddr)) {
|
||||
/* Address mismatch. Send 400 */
|
||||
send_reply_err(alloc, rdata, PJ_TRUE,
|
||||
PJ_STUN_SC_BAD_REQUEST,
|
||||
send_reply_err(alloc, rdata, PJ_TRUE,
|
||||
PJ_STUN_SC_BAD_REQUEST,
|
||||
"Peer address mismatch");
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
@ -1262,7 +1265,7 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
p2 = lookup_permission_by_addr(alloc, &peer_attr->sockaddr,
|
||||
pj_sockaddr_get_len(&peer_attr->sockaddr));
|
||||
if (p2 && p2->channel != PJ_TURN_INVALID_CHANNEL) {
|
||||
send_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_BAD_REQUEST,
|
||||
send_reply_err(alloc, rdata, PJ_TRUE, PJ_STUN_SC_BAD_REQUEST,
|
||||
"Peer address already assigned a channel number");
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
@ -1280,7 +1283,7 @@ static pj_status_t stun_on_rx_request(pj_stun_session *sess,
|
|||
|
||||
/* Register to hash table */
|
||||
pj_assert(sizeof(p2->channel==2));
|
||||
pj_hash_set(alloc->pool, alloc->ch_table, &p2->channel,
|
||||
pj_hash_set(alloc->pool, alloc->ch_table, &p2->channel,
|
||||
sizeof(p2->channel), 0, p2);
|
||||
|
||||
/* Update */
|
||||
|
@ -1367,7 +1370,7 @@ static pj_status_t stun_on_rx_indication(pj_stun_session *sess,
|
|||
|
||||
/* Relay the data to peer */
|
||||
len = data_attr->length;
|
||||
pj_sock_sendto(alloc->relay.tp.sock, data_attr->data,
|
||||
pj_sock_sendto(alloc->relay.tp.sock, data_attr->data,
|
||||
&len, 0, &peer_attr->sockaddr,
|
||||
pj_sockaddr_get_len(&peer_attr->sockaddr));
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "turn.h"
|
||||
#include "auth.h"
|
||||
|
@ -76,7 +76,7 @@ PJ_DEF(const char*) pj_turn_tp_type_name(int tp_type)
|
|||
/*
|
||||
* Create server.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
|
||||
PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
|
||||
pj_turn_srv **p_srv)
|
||||
{
|
||||
pj_pool_t *pool;
|
||||
|
@ -94,14 +94,14 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
|
|||
srv->core.pf = pf;
|
||||
srv->core.pool = pool;
|
||||
srv->core.tls_key = srv->core.tls_data = -1;
|
||||
|
||||
|
||||
/* Create ioqueue */
|
||||
status = pj_ioqueue_create(pool, MAX_HANDLES, &srv->core.ioqueue);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
/* Server mutex */
|
||||
status = pj_lock_create_recursive_mutex(pool, srv->obj_name,
|
||||
status = pj_lock_create_recursive_mutex(pool, srv->obj_name,
|
||||
&srv->core.lock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
@ -114,7 +114,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
|
|||
status = pj_thread_local_alloc(&srv->core.tls_data);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
|
||||
/* Create timer heap */
|
||||
status = pj_timer_heap_create(pool, MAX_TIMER, &srv->core.timer_heap);
|
||||
if (status != PJ_SUCCESS)
|
||||
|
@ -125,7 +125,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
|
|||
|
||||
/* Array of listeners */
|
||||
srv->core.listener = (pj_turn_listener**)
|
||||
pj_pool_calloc(pool, MAX_LISTENERS,
|
||||
pj_pool_calloc(pool, MAX_LISTENERS,
|
||||
sizeof(srv->core.listener[0]));
|
||||
|
||||
/* Create hash tables */
|
||||
|
@ -169,19 +169,19 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
|
|||
/* Array of worker threads */
|
||||
srv->core.thread_cnt = MAX_THREADS;
|
||||
srv->core.thread = (pj_thread_t**)
|
||||
pj_pool_calloc(pool, srv->core.thread_cnt,
|
||||
pj_pool_calloc(pool, srv->core.thread_cnt,
|
||||
sizeof(pj_thread_t*));
|
||||
|
||||
/* Start the worker threads */
|
||||
for (i=0; i<srv->core.thread_cnt; ++i) {
|
||||
status = pj_thread_create(pool, srv->obj_name, &server_thread_proc,
|
||||
status = pj_thread_create(pool, srv->obj_name, &server_thread_proc,
|
||||
srv, 0, 0, &srv->core.thread[i]);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
/* We're done. Application should add listeners now */
|
||||
PJ_LOG(4,(srv->obj_name, "TURN server v%s is running",
|
||||
PJ_LOG(4,(srv->obj_name, "TURN server v%s is running",
|
||||
pj_get_version()));
|
||||
|
||||
*p_srv = srv;
|
||||
|
@ -193,8 +193,8 @@ on_error:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle timer and network events
|
||||
/*
|
||||
* Handle timer and network events
|
||||
*/
|
||||
static void srv_handle_events(pj_turn_srv *srv, const pj_time_val *max_timeout)
|
||||
{
|
||||
|
@ -203,8 +203,8 @@ static void srv_handle_events(pj_turn_srv *srv, const pj_time_val *max_timeout)
|
|||
unsigned net_event_count = 0;
|
||||
int c;
|
||||
|
||||
/* Poll the timer. The timer heap has its own mutex for better
|
||||
* granularity, so we don't need to lock the server.
|
||||
/* Poll the timer. The timer heap has its own mutex for better
|
||||
* granularity, so we don't need to lock the server.
|
||||
*/
|
||||
timeout.sec = timeout.msec = 0;
|
||||
c = pj_timer_heap_poll( srv->core.timer_heap, &timeout );
|
||||
|
@ -222,7 +222,7 @@ static void srv_handle_events(pj_turn_srv *srv, const pj_time_val *max_timeout)
|
|||
timeout = *max_timeout;
|
||||
}
|
||||
|
||||
/* Poll ioqueue.
|
||||
/* Poll ioqueue.
|
||||
* Repeat polling the ioqueue while we have immediate events, because
|
||||
* timer heap may process more than one events, so if we only process
|
||||
* one network events at a time (such as when IOCP backend is used),
|
||||
|
@ -292,7 +292,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv)
|
|||
it = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Destroy all listeners. */
|
||||
for (i=0; i<srv->core.lis_cnt; ++i) {
|
||||
if (srv->core.listener[i]) {
|
||||
|
@ -312,7 +312,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv)
|
|||
srv->tables.alloc = NULL;
|
||||
srv->tables.res = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Destroy timer heap */
|
||||
if (srv->core.timer_heap) {
|
||||
pj_timer_heap_destroy(srv->core.timer_heap);
|
||||
|
@ -460,7 +460,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_unregister_allocation(pj_turn_srv *srv,
|
|||
}
|
||||
|
||||
|
||||
/* Callback from our own STUN session whenever it needs to send
|
||||
/* Callback from our own STUN session whenever it needs to send
|
||||
* outgoing STUN packet.
|
||||
*/
|
||||
static pj_status_t on_tx_stun_msg( pj_stun_session *sess,
|
||||
|
@ -471,24 +471,24 @@ static pj_status_t on_tx_stun_msg( pj_stun_session *sess,
|
|||
unsigned addr_len)
|
||||
{
|
||||
pj_turn_transport *transport = (pj_turn_transport*) token;
|
||||
|
||||
|
||||
PJ_ASSERT_RETURN(transport!=NULL, PJ_EINVALIDOP);
|
||||
|
||||
PJ_UNUSED_ARG(sess);
|
||||
|
||||
return transport->sendto(transport, pdu, pdu_size, 0,
|
||||
return transport->sendto(transport, pdu, pdu_size, 0,
|
||||
dst_addr, addr_len);
|
||||
}
|
||||
|
||||
|
||||
/* Respond to STUN request */
|
||||
static pj_status_t stun_respond(pj_stun_session *sess,
|
||||
static pj_status_t stun_respond(pj_stun_session *sess,
|
||||
pj_turn_transport *transport,
|
||||
const pj_stun_rx_data *rdata,
|
||||
unsigned code,
|
||||
unsigned code,
|
||||
const char *errmsg,
|
||||
pj_bool_t cache,
|
||||
const pj_sockaddr_t *dst_addr,
|
||||
pj_bool_t cache,
|
||||
const pj_sockaddr_t *dst_addr,
|
||||
unsigned addr_len)
|
||||
{
|
||||
pj_status_t status;
|
||||
|
@ -496,14 +496,14 @@ static pj_status_t stun_respond(pj_stun_session *sess,
|
|||
pj_stun_tx_data *tdata;
|
||||
|
||||
/* Create response */
|
||||
status = pj_stun_session_create_res(sess, rdata, code,
|
||||
status = pj_stun_session_create_res(sess, rdata, code,
|
||||
(errmsg?pj_cstr(&reason,errmsg):NULL),
|
||||
&tdata);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Send the response */
|
||||
return pj_stun_session_send_msg(sess, transport, cache, PJ_FALSE,
|
||||
return pj_stun_session_send_msg(sess, transport, cache, PJ_FALSE,
|
||||
dst_addr, addr_len, tdata);
|
||||
}
|
||||
|
||||
|
@ -522,7 +522,6 @@ static pj_status_t on_rx_stun_request(pj_stun_session *sess,
|
|||
{
|
||||
pj_turn_transport *transport;
|
||||
const pj_stun_msg *msg = rdata->msg;
|
||||
pj_turn_srv *srv;
|
||||
pj_turn_allocation *alloc;
|
||||
pj_status_t status;
|
||||
|
||||
|
@ -530,7 +529,6 @@ static pj_status_t on_rx_stun_request(pj_stun_session *sess,
|
|||
PJ_UNUSED_ARG(pdu_len);
|
||||
|
||||
transport = (pj_turn_transport*) token;
|
||||
srv = transport->listener->server;
|
||||
|
||||
/* Respond any requests other than ALLOCATE with 437 response */
|
||||
if (msg->hdr.type != PJ_STUN_ALLOCATE_REQUEST) {
|
||||
|
@ -569,13 +567,13 @@ static void handle_binding_request(pj_turn_pkt *pkt,
|
|||
return;
|
||||
|
||||
/* Create response */
|
||||
status = pj_stun_msg_create_response(pkt->pool, request, 0, NULL,
|
||||
status = pj_stun_msg_create_response(pkt->pool, request, 0, NULL,
|
||||
&response);
|
||||
if (status != PJ_SUCCESS)
|
||||
return;
|
||||
|
||||
/* Add XOR-MAPPED-ADDRESS */
|
||||
pj_stun_msg_add_sockaddr_attr(pkt->pool, response,
|
||||
pj_stun_msg_add_sockaddr_attr(pkt->pool, response,
|
||||
PJ_STUN_ATTR_XOR_MAPPED_ADDR,
|
||||
PJ_TRUE,
|
||||
&pkt->src.clt_addr,
|
||||
|
@ -587,7 +585,7 @@ static void handle_binding_request(pj_turn_pkt *pkt,
|
|||
return;
|
||||
|
||||
/* Send response */
|
||||
pkt->transport->sendto(pkt->transport, pdu, len, 0,
|
||||
pkt->transport->sendto(pkt->transport, pdu, len, 0,
|
||||
&pkt->src.clt_addr, pkt->src_addr_len);
|
||||
}
|
||||
|
||||
|
@ -598,7 +596,7 @@ static void handle_binding_request(pj_turn_pkt *pkt,
|
|||
* is found for the client address, or handed over to owned STUN session
|
||||
* if an allocation is not found.
|
||||
*/
|
||||
PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
|
||||
PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
|
||||
pj_turn_pkt *pkt)
|
||||
{
|
||||
pj_turn_allocation *alloc;
|
||||
|
@ -638,7 +636,7 @@ PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
|
|||
*/
|
||||
if ((*pkt->pkt != 0x00 && *pkt->pkt != 0x01) ||
|
||||
pkt->len > 1600 ||
|
||||
(options & PJ_STUN_IS_DATAGRAM))
|
||||
(options & PJ_STUN_IS_DATAGRAM))
|
||||
{
|
||||
char errmsg[PJ_ERR_MSG_SIZE];
|
||||
char ip[PJ_INET6_ADDRSTRLEN+10];
|
||||
|
@ -646,7 +644,7 @@ PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
|
|||
pkt->len = 0;
|
||||
|
||||
pj_strerror(status, errmsg, sizeof(errmsg));
|
||||
PJ_LOG(5,(srv->obj_name,
|
||||
PJ_LOG(5,(srv->obj_name,
|
||||
"Non-STUN packet from %s is dropped: %s",
|
||||
pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3),
|
||||
errmsg));
|
||||
|
@ -654,7 +652,7 @@ PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Special handling for Binding Request. We won't give it to the
|
||||
/* Special handling for Binding Request. We won't give it to the
|
||||
* STUN session since this request is not authenticated.
|
||||
*/
|
||||
if (pkt->pkt[1] == 1) {
|
||||
|
@ -668,16 +666,16 @@ PJ_DEF(void) pj_turn_srv_on_rx_pkt(pj_turn_srv *srv,
|
|||
*/
|
||||
options &= ~PJ_STUN_CHECK_PACKET;
|
||||
parsed_len = 0;
|
||||
status = pj_stun_session_on_rx_pkt(srv->core.stun_sess, pkt->pkt,
|
||||
status = pj_stun_session_on_rx_pkt(srv->core.stun_sess, pkt->pkt,
|
||||
pkt->len, options, pkt->transport,
|
||||
&parsed_len, &pkt->src.clt_addr,
|
||||
&parsed_len, &pkt->src.clt_addr,
|
||||
pkt->src_addr_len);
|
||||
if (status != PJ_SUCCESS) {
|
||||
char errmsg[PJ_ERR_MSG_SIZE];
|
||||
char ip[PJ_INET6_ADDRSTRLEN+10];
|
||||
|
||||
pj_strerror(status, errmsg, sizeof(errmsg));
|
||||
PJ_LOG(5,(srv->obj_name,
|
||||
PJ_LOG(5,(srv->obj_name,
|
||||
"Error processing STUN packet from %s: %s",
|
||||
pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3),
|
||||
errmsg));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -14,7 +14,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "systest.h"
|
||||
#include "gui.h"
|
||||
|
@ -56,34 +56,34 @@ static gui_menu menu_sndaec = { "AEC/AES Test", &systest_aec_test };
|
|||
static gui_menu menu_listdev = { "View Devices", &systest_list_audio_devs };
|
||||
static gui_menu menu_getsets = { "View Settings", &systest_display_settings };
|
||||
|
||||
static gui_menu menu_tests = {
|
||||
"Tests", NULL,
|
||||
10,
|
||||
static gui_menu menu_tests = {
|
||||
"Tests", NULL,
|
||||
10,
|
||||
{
|
||||
&menu_wizard,
|
||||
&menu_audtest,
|
||||
&menu_audtest,
|
||||
&menu_playtn,
|
||||
&menu_playwv1,
|
||||
&menu_playwv2,
|
||||
&menu_recaud,
|
||||
&menu_calclat,
|
||||
&menu_sndaec,
|
||||
NULL,
|
||||
NULL,
|
||||
&menu_exit
|
||||
}
|
||||
};
|
||||
|
||||
static gui_menu menu_options = {
|
||||
"Options", NULL,
|
||||
2,
|
||||
static gui_menu menu_options = {
|
||||
"Options", NULL,
|
||||
2,
|
||||
{
|
||||
&menu_listdev,
|
||||
&menu_getsets,
|
||||
}
|
||||
};
|
||||
|
||||
static gui_menu root_menu = {
|
||||
"Root", NULL, 2, {&menu_tests, &menu_options}
|
||||
static gui_menu root_menu = {
|
||||
"Root", NULL, 2, {&menu_tests, &menu_options}
|
||||
};
|
||||
|
||||
/*****************************************************************/
|
||||
|
@ -133,7 +133,7 @@ static void systest_perror(const char *title, pj_status_t status)
|
|||
pj_strerror(status, errmsg, sizeof(errmsg));
|
||||
else
|
||||
errmsg[0] = '\0';
|
||||
|
||||
|
||||
strcpy(themsg, title);
|
||||
strncat(themsg, errmsg, sizeof(themsg)-1);
|
||||
themsg[sizeof(themsg)-1] = '\0';
|
||||
|
@ -158,7 +158,7 @@ test_item_t *systest_alloc_test_item(const char *title)
|
|||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* test: play simple ringback tone and hear it
|
||||
* test: play simple ringback tone and hear it
|
||||
*/
|
||||
static void systest_play_tone(void)
|
||||
{
|
||||
|
@ -201,17 +201,17 @@ static void systest_play_tone(void)
|
|||
PJ_LOG(3,(THIS_FILE, "Running %s", title));
|
||||
|
||||
pool = pjsua_pool_create("ringback", 512, 512);
|
||||
samples_per_frame = systest.media_cfg.audio_frame_ptime *
|
||||
samples_per_frame = systest.media_cfg.audio_frame_ptime *
|
||||
systest.media_cfg.clock_rate *
|
||||
systest.media_cfg.channel_count / 1000;
|
||||
|
||||
/* Ringback tone (call is ringing) */
|
||||
name = pj_str("ringback");
|
||||
status = pjmedia_tonegen_create2(pool, &name,
|
||||
status = pjmedia_tonegen_create2(pool, &name,
|
||||
systest.media_cfg.clock_rate,
|
||||
systest.media_cfg.channel_count,
|
||||
systest.media_cfg.channel_count,
|
||||
samples_per_frame,
|
||||
16, PJMEDIA_TONEGEN_LOOP,
|
||||
16, PJMEDIA_TONEGEN_LOOP,
|
||||
&ringback_port);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_return;
|
||||
|
@ -269,7 +269,7 @@ on_return:
|
|||
/* Util: create file player, each time trying different paths until we get
|
||||
* the file.
|
||||
*/
|
||||
static pj_status_t create_player(unsigned path_cnt, const char *paths[],
|
||||
static pj_status_t create_player(unsigned path_cnt, const char *paths[],
|
||||
pjsua_player_id *p_id)
|
||||
{
|
||||
pj_str_t name;
|
||||
|
@ -364,7 +364,7 @@ static void systest_play_wav2(void)
|
|||
|
||||
|
||||
/*****************************************************************************
|
||||
* test: record audio
|
||||
* test: record audio
|
||||
*/
|
||||
static void systest_rec_audio(void)
|
||||
{
|
||||
|
@ -387,7 +387,7 @@ static void systest_rec_audio(void)
|
|||
"This test will allow you to record audio "
|
||||
"from the microphone, and playback the "
|
||||
"audio to the speaker. Press OK to start recording, "
|
||||
"CANCEL to skip.",
|
||||
"CANCEL to skip.",
|
||||
WITH_OKCANCEL);
|
||||
if (key != KEY_OK) {
|
||||
ti->skipped = PJ_TRUE;
|
||||
|
@ -432,7 +432,7 @@ static void systest_rec_audio(void)
|
|||
"Recording has been stopped. "
|
||||
"The recorded audio is being played now to "
|
||||
"the speaker device, in a loop. Listen for "
|
||||
"any audio impairments. Press OK to stop.",
|
||||
"any audio impairments. Press OK to stop.",
|
||||
WITH_OK);
|
||||
|
||||
on_return:
|
||||
|
@ -525,11 +525,11 @@ static void systest_audio_test(void)
|
|||
param.play_id = systest.play_id;
|
||||
param.clock_rate = systest.media_cfg.snd_clock_rate;
|
||||
param.channel_count = systest.media_cfg.channel_count;
|
||||
param.samples_per_frame = param.clock_rate * param.channel_count *
|
||||
param.samples_per_frame = param.clock_rate * param.channel_count *
|
||||
systest.media_cfg.audio_frame_ptime / 1000;
|
||||
|
||||
/* Latency settings */
|
||||
param.flags |= (PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |
|
||||
param.flags |= (PJMEDIA_AUD_DEV_CAP_INPUT_LATENCY |
|
||||
PJMEDIA_AUD_DEV_CAP_OUTPUT_LATENCY);
|
||||
param.input_latency_ms = systest.media_cfg.snd_rec_latency;
|
||||
param.output_latency_ms = systest.media_cfg.snd_play_latency;
|
||||
|
@ -553,11 +553,11 @@ static void systest_audio_test(void)
|
|||
textbufpos = strlen(textbuf);
|
||||
|
||||
if (result.rec.frame_cnt==0) {
|
||||
problems[problem_count++] =
|
||||
problems[problem_count++] =
|
||||
"No audio frames were captured from the microphone. "
|
||||
"This means the audio device is not working properly.";
|
||||
} else {
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
sizeof(textbuf)-textbufpos,
|
||||
"Rec : interval (min/max/avg/dev)=\r\n"
|
||||
" %u/%u/%u/%u (ms)\r\n"
|
||||
|
@ -570,17 +570,17 @@ static void systest_audio_test(void)
|
|||
textbufpos = strlen(textbuf);
|
||||
|
||||
if (result.rec.max_burst > GOOD_MAX_INTERVAL) {
|
||||
problems[problem_count++] =
|
||||
problems[problem_count++] =
|
||||
"Recording max burst is quite high";
|
||||
}
|
||||
}
|
||||
|
||||
if (result.play.frame_cnt==0) {
|
||||
problems[problem_count++] =
|
||||
problems[problem_count++] =
|
||||
"No audio frames were played to the speaker. "
|
||||
"This means the audio device is not working properly.";
|
||||
} else {
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
sizeof(textbuf)-textbufpos,
|
||||
"Play: interval (min/max/avg/dev)=\r\n"
|
||||
" %u/%u/%u/%u (ms)\r\n"
|
||||
|
@ -593,14 +593,14 @@ static void systest_audio_test(void)
|
|||
textbufpos = strlen(textbuf);
|
||||
|
||||
if (result.play.max_burst > GOOD_MAX_INTERVAL) {
|
||||
problems[problem_count++] =
|
||||
problems[problem_count++] =
|
||||
"Playback max burst is quite high";
|
||||
}
|
||||
}
|
||||
|
||||
if (result.rec_drift_per_sec) {
|
||||
const char *which = result.rec_drift_per_sec>=0 ? "faster" : "slower";
|
||||
unsigned drift = result.rec_drift_per_sec>=0 ?
|
||||
unsigned drift = result.rec_drift_per_sec>=0 ?
|
||||
result.rec_drift_per_sec :
|
||||
-result.rec_drift_per_sec;
|
||||
|
||||
|
@ -613,7 +613,7 @@ static void systest_audio_test(void)
|
|||
}
|
||||
|
||||
if (problem_count == 0) {
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
sizeof(textbuf)-textbufpos,
|
||||
"\r\nThe sound device seems to be okay!");
|
||||
textbufpos = strlen(textbuf);
|
||||
|
@ -623,7 +623,7 @@ static void systest_audio_test(void)
|
|||
unsigned i;
|
||||
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
sizeof(textbuf)-textbufpos,
|
||||
sizeof(textbuf)-textbufpos,
|
||||
"There could be %d problem(s) with the "
|
||||
"sound device:\r\n",
|
||||
problem_count);
|
||||
|
@ -631,7 +631,7 @@ static void systest_audio_test(void)
|
|||
|
||||
for (i=0; i<problem_count; ++i) {
|
||||
pj_ansi_snprintf(textbuf+textbufpos,
|
||||
sizeof(textbuf)-textbufpos,
|
||||
sizeof(textbuf)-textbufpos,
|
||||
" %d: %s\r\n", i+1, problems[i]);
|
||||
textbufpos = strlen(textbuf);
|
||||
}
|
||||
|
@ -649,7 +649,7 @@ static void systest_audio_test(void)
|
|||
* sound latency test
|
||||
*/
|
||||
static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
|
||||
unsigned *lat_sum, unsigned *lat_cnt,
|
||||
unsigned *lat_sum, unsigned *lat_cnt,
|
||||
unsigned *lat_min, unsigned *lat_max)
|
||||
{
|
||||
pjmedia_frame frm;
|
||||
|
@ -688,7 +688,7 @@ static int calculate_latency(pj_pool_t *pool, pjmedia_port *wav,
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Zero the first 500ms to remove loud click noises
|
||||
/* Zero the first 500ms to remove loud click noises
|
||||
* (keypad press, etc.)
|
||||
*/
|
||||
pjmedia_zero_samples(buf, clock_rate / 2);
|
||||
|
@ -783,7 +783,7 @@ static void systest_latency_test(void)
|
|||
ti->skipped = PJ_TRUE;
|
||||
return;
|
||||
}
|
||||
key = gui_msgbox(title,
|
||||
key = gui_msgbox(title,
|
||||
"For this test to work, we must be able to capture "
|
||||
"the audio played in the speaker (the echo), and only"
|
||||
" that audio (i.e. you must be in relatively quiet "
|
||||
|
@ -797,7 +797,7 @@ static void systest_latency_test(void)
|
|||
|
||||
PJ_LOG(3,(THIS_FILE, "Running %s", title));
|
||||
|
||||
status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
|
||||
status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
|
||||
&play_id);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_return;
|
||||
|
@ -816,7 +816,7 @@ static void systest_latency_test(void)
|
|||
status = pjsua_conf_connect(play_slot, 0);
|
||||
status = pjsua_conf_connect(0, rec_slot);
|
||||
status = pjsua_conf_connect(play_slot, rec_slot);
|
||||
|
||||
|
||||
|
||||
/* We're running */
|
||||
PJ_LOG(3,(THIS_FILE, "Please wait while test is running (~10 sec)"));
|
||||
|
@ -869,7 +869,7 @@ static void systest_latency_test(void)
|
|||
if (status != PJ_SUCCESS)
|
||||
goto on_return;
|
||||
|
||||
status = calculate_latency(pool, wav_port, &lat_sum, &lat_cnt,
|
||||
status = calculate_latency(pool, wav_port, &lat_sum, &lat_cnt,
|
||||
&lat_min, &lat_max);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_return;
|
||||
|
@ -912,7 +912,7 @@ on_return:
|
|||
"The latency is quite high\r\n");
|
||||
msglen = strlen(msg);
|
||||
}
|
||||
|
||||
|
||||
key = gui_msgbox(title, msg, WITH_OK);
|
||||
|
||||
ti->success = PJ_TRUE;
|
||||
|
@ -964,7 +964,7 @@ static void systest_aec_test(void)
|
|||
/*
|
||||
* Create player and recorder
|
||||
*/
|
||||
status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
|
||||
status = create_player(PJ_ARRAY_SIZE(ref_wav_paths), ref_wav_paths,
|
||||
&player_id);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_PERROR(1,(THIS_FILE, status, "Error opening WAV file %s",
|
||||
|
@ -1017,7 +1017,7 @@ static void systest_aec_test(void)
|
|||
/* Wait user signal */
|
||||
gui_msgbox(title, "We are now playing the captured audio from the mic. "
|
||||
"Check if echo (of the audio played back previously) is "
|
||||
"present in the audio. The recording is stored in "
|
||||
"present in the audio. The recording is stored in "
|
||||
AEC_REC_PATH " for offline analysis. "
|
||||
"Press OK to stop.",
|
||||
WITH_OK);
|
||||
|
@ -1073,7 +1073,7 @@ static void systest_list_audio_devs()
|
|||
test_item_t *ti;
|
||||
enum gui_key key;
|
||||
const char *title = "Audio Device List";
|
||||
|
||||
|
||||
ti = systest_alloc_test_item(title);
|
||||
if (!ti)
|
||||
return;
|
||||
|
@ -1082,7 +1082,7 @@ static void systest_list_audio_devs()
|
|||
|
||||
dev_count = pjmedia_aud_dev_count();
|
||||
if (dev_count == 0) {
|
||||
key = gui_msgbox(title,
|
||||
key = gui_msgbox(title,
|
||||
"No audio devices are found", WITH_OK);
|
||||
ti->success = PJ_FALSE;
|
||||
pj_ansi_strcpy(ti->reason, "No device found");
|
||||
|
@ -1106,13 +1106,14 @@ static void systest_list_audio_devs()
|
|||
|
||||
pj_ansi_snprintf(ti->reason+len, sizeof(ti->reason)-len,
|
||||
" %2d: %s [%s] (%d/%d)\r\n",
|
||||
i, info.driver, info.name,
|
||||
i, info.driver, info.name,
|
||||
info.input_count, info.output_count);
|
||||
len = strlen(ti->reason);
|
||||
}
|
||||
|
||||
ti->reason[len] = '\0';
|
||||
key = gui_msgbox(title, ti->reason, WITH_OK);
|
||||
PJ_UNUSED_ARG(key);
|
||||
|
||||
ti->success = PJ_TRUE;
|
||||
}
|
||||
|
@ -1204,7 +1205,7 @@ static void systest_display_settings(void)
|
|||
pj_ansi_strncpy(ti->reason, textbuf, sizeof(ti->reason));
|
||||
ti->reason[sizeof(ti->reason)-1] = '\0';
|
||||
key = gui_msgbox(title, textbuf, WITH_OK);
|
||||
|
||||
PJ_UNUSED_ARG(key); /* Warning about unused var */
|
||||
}
|
||||
|
||||
/*****************************************************************/
|
||||
|
@ -1242,7 +1243,7 @@ int systest_init(void)
|
|||
#if defined(OVERRIDE_AUDDEV_REC_LAT) && OVERRIDE_AUDDEV_REC_LAT!=0
|
||||
systest.media_cfg.snd_rec_latency = OVERRIDE_AUDDEV_REC_LAT;
|
||||
#endif
|
||||
|
||||
|
||||
status = pjsua_init(&systest.ua_cfg, &log_cfg, &systest.media_cfg);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsua_destroy();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <pjsip/sip_auth.h>
|
||||
|
@ -137,7 +137,7 @@ static void digest2str(const unsigned char digest[], char *output)
|
|||
|
||||
/*
|
||||
* Create response digest based on the parameters and store the
|
||||
* digest ASCII in 'result'.
|
||||
* digest ASCII in 'result'.
|
||||
*/
|
||||
PJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result,
|
||||
const pj_str_t *nonce,
|
||||
|
@ -159,8 +159,8 @@ PJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result,
|
|||
AUTH_TRACE_((THIS_FILE, "Begin creating digest"));
|
||||
|
||||
if ((cred_info->data_type & PASSWD_MASK) == PJSIP_CRED_DATA_PLAIN_PASSWD) {
|
||||
/***
|
||||
*** ha1 = MD5(username ":" realm ":" password)
|
||||
/***
|
||||
*** ha1 = MD5(username ":" realm ":" password)
|
||||
***/
|
||||
pj_md5_init(&pms);
|
||||
MD5_APPEND( &pms, cred_info->username.ptr, cred_info->username.slen);
|
||||
|
@ -182,7 +182,7 @@ PJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result,
|
|||
AUTH_TRACE_((THIS_FILE, " ha1=%.32s", ha1));
|
||||
|
||||
/***
|
||||
*** ha2 = MD5(method ":" req_uri)
|
||||
*** ha2 = MD5(method ":" req_uri)
|
||||
***/
|
||||
pj_md5_init(&pms);
|
||||
MD5_APPEND( &pms, method->ptr, method->slen);
|
||||
|
@ -195,7 +195,7 @@ PJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result,
|
|||
|
||||
/***
|
||||
*** When qop is not used:
|
||||
*** response = MD5(ha1 ":" nonce ":" ha2)
|
||||
*** response = MD5(ha1 ":" nonce ":" ha2)
|
||||
***
|
||||
*** When qop=auth is used:
|
||||
*** response = MD5(ha1 ":" nonce ":" nc ":" cnonce ":" qop ":" ha2)
|
||||
|
@ -217,7 +217,7 @@ PJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result,
|
|||
|
||||
/* This is the final response digest. */
|
||||
pj_md5_final(&pms, digest);
|
||||
|
||||
|
||||
/* Convert digest to string and store in chal->response. */
|
||||
result->slen = PJSIP_MD5STRLEN;
|
||||
digest2str(digest, result->ptr);
|
||||
|
@ -258,7 +258,7 @@ static pj_bool_t has_auth_qop( pj_pool_t *pool, const pj_str_t *qop_offer)
|
|||
}
|
||||
|
||||
/*
|
||||
* Generate response digest.
|
||||
* Generate response digest.
|
||||
* Most of the parameters to generate the digest (i.e. username, realm, uri,
|
||||
* and nonce) are expected to be in the credential. Additional parameters (i.e.
|
||||
* password and method param) should be supplied in the argument.
|
||||
|
@ -307,18 +307,18 @@ static pj_status_t respond_digest( pj_pool_t *pool,
|
|||
|
||||
if ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {
|
||||
/* Call application callback to create the response digest */
|
||||
return (*cred_info->ext.aka.cb)(pool, chal, cred_info,
|
||||
return (*cred_info->ext.aka.cb)(pool, chal, cred_info,
|
||||
method, cred);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Convert digest to string and store in chal->response. */
|
||||
pjsip_auth_create_digest( &cred->response, &cred->nonce, NULL,
|
||||
NULL, NULL, uri, &chal->realm,
|
||||
pjsip_auth_create_digest( &cred->response, &cred->nonce, NULL,
|
||||
NULL, NULL, uri, &chal->realm,
|
||||
cred_info, method);
|
||||
}
|
||||
|
||||
} else if (has_auth_qop(pool, &chal->qop)) {
|
||||
/* Server requires quality of protection.
|
||||
/* Server requires quality of protection.
|
||||
* We respond with selecting "qop=auth" protection.
|
||||
*/
|
||||
cred->qop = pjsip_AUTH_STR;
|
||||
|
@ -334,18 +334,18 @@ static pj_status_t respond_digest( pj_pool_t *pool,
|
|||
|
||||
if ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {
|
||||
/* Call application callback to create the response digest */
|
||||
return (*cred_info->ext.aka.cb)(pool, chal, cred_info,
|
||||
return (*cred_info->ext.aka.cb)(pool, chal, cred_info,
|
||||
method, cred);
|
||||
}
|
||||
else {
|
||||
pjsip_auth_create_digest( &cred->response, &cred->nonce,
|
||||
&cred->nc, cnonce, &pjsip_AUTH_STR,
|
||||
pjsip_auth_create_digest( &cred->response, &cred->nonce,
|
||||
&cred->nc, cnonce, &pjsip_AUTH_STR,
|
||||
uri, &chal->realm, cred_info, method );
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Server requires quality protection that we don't support. */
|
||||
PJ_LOG(4,(THIS_FILE, "Unsupported qop offer %.*s",
|
||||
PJ_LOG(4,(THIS_FILE, "Unsupported qop offer %.*s",
|
||||
chal->qop.slen, chal->qop.ptr));
|
||||
return PJSIP_EINVALIDQOP;
|
||||
}
|
||||
|
@ -357,7 +357,7 @@ static pj_status_t respond_digest( pj_pool_t *pool,
|
|||
/*
|
||||
* Update authentication session with a challenge.
|
||||
*/
|
||||
static void update_digest_session( pj_pool_t *ses_pool,
|
||||
static void update_digest_session( pj_pool_t *ses_pool,
|
||||
pjsip_cached_auth *cached_auth,
|
||||
const pjsip_www_authenticate_hdr *hdr )
|
||||
{
|
||||
|
@ -370,7 +370,7 @@ static void update_digest_session( pj_pool_t *ses_pool,
|
|||
/* Only update if the new challenge is "significantly different"
|
||||
* than the one in the cache, to reduce memory usage.
|
||||
*/
|
||||
const pjsip_digest_challenge *d1 =
|
||||
const pjsip_digest_challenge *d1 =
|
||||
&cached_auth->last_chal->challenge.digest;
|
||||
const pjsip_digest_challenge *d2 = &hdr->challenge.digest;
|
||||
|
||||
|
@ -406,14 +406,14 @@ static void update_digest_session( pj_pool_t *ses_pool,
|
|||
pj_assert(cached_auth->realm.slen != 0);
|
||||
*/
|
||||
if (cached_auth->realm.slen == 0) {
|
||||
pj_strdup(ses_pool, &cached_auth->realm,
|
||||
pj_strdup(ses_pool, &cached_auth->realm,
|
||||
&hdr->challenge.digest.realm);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Update last_nonce and nonce-count */
|
||||
if (!pj_strcmp(&hdr->challenge.digest.nonce,
|
||||
&cached_auth->last_chal->challenge.digest.nonce))
|
||||
if (!pj_strcmp(&hdr->challenge.digest.nonce,
|
||||
&cached_auth->last_chal->challenge.digest.nonce))
|
||||
{
|
||||
/* Same nonce, increment nonce-count */
|
||||
++cached_auth->nc;
|
||||
|
@ -423,9 +423,9 @@ static void update_digest_session( pj_pool_t *ses_pool,
|
|||
&hdr->challenge.digest.nonce);
|
||||
/* Has the opaque changed? */
|
||||
if (pj_strcmp(&cached_auth->last_chal->challenge.digest.opaque,
|
||||
&hdr->challenge.digest.opaque))
|
||||
&hdr->challenge.digest.opaque))
|
||||
{
|
||||
pj_strdup(ses_pool,
|
||||
pj_strdup(ses_pool,
|
||||
&cached_auth->last_chal->challenge.digest.opaque,
|
||||
&hdr->challenge.digest.opaque);
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ static const pjsip_cred_info* auth_find_cred( const pjsip_auth_clt_sess *sess,
|
|||
/* Init client session. */
|
||||
PJ_DEF(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess,
|
||||
pjsip_endpoint *endpt,
|
||||
pj_pool_t *pool,
|
||||
pj_pool_t *pool,
|
||||
unsigned options)
|
||||
{
|
||||
PJ_ASSERT_RETURN(sess && endpt && pool && (options==0), PJ_EINVAL);
|
||||
|
@ -509,15 +509,15 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,
|
|||
PJ_ASSERT_RETURN(pool && sess && rhs, PJ_EINVAL);
|
||||
|
||||
pjsip_auth_clt_init(sess, (pjsip_endpoint*)rhs->endpt, pool, 0);
|
||||
|
||||
|
||||
sess->cred_cnt = rhs->cred_cnt;
|
||||
sess->cred_info = (pjsip_cred_info*)
|
||||
pj_pool_alloc(pool,
|
||||
pj_pool_alloc(pool,
|
||||
sess->cred_cnt*sizeof(pjsip_cred_info));
|
||||
for (i=0; i<rhs->cred_cnt; ++i) {
|
||||
pj_strdup(pool, &sess->cred_info[i].realm, &rhs->cred_info[i].realm);
|
||||
pj_strdup(pool, &sess->cred_info[i].scheme, &rhs->cred_info[i].scheme);
|
||||
pj_strdup(pool, &sess->cred_info[i].username,
|
||||
pj_strdup(pool, &sess->cred_info[i].username,
|
||||
&rhs->cred_info[i].username);
|
||||
sess->cred_info[i].data_type = rhs->cred_info[i].data_type;
|
||||
pj_strdup(pool, &sess->cred_info[i].data, &rhs->cred_info[i].data);
|
||||
|
@ -552,7 +552,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
|
|||
for (i=0; i<cred_cnt; ++i) {
|
||||
sess->cred_info[i].data_type = c[i].data_type;
|
||||
|
||||
/* When data_type is PJSIP_CRED_DATA_EXT_AKA,
|
||||
/* When data_type is PJSIP_CRED_DATA_EXT_AKA,
|
||||
* callback must be specified.
|
||||
*/
|
||||
if ((c[i].data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) {
|
||||
|
@ -568,11 +568,11 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
|
|||
PJ_ASSERT_RETURN(c[i].ext.aka.cb != NULL, PJ_EINVAL);
|
||||
|
||||
/* Verify K len */
|
||||
PJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN,
|
||||
PJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN,
|
||||
PJSIP_EAUTHINAKACRED);
|
||||
|
||||
/* Verify OP len */
|
||||
PJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN,
|
||||
PJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN,
|
||||
PJSIP_EAUTHINAKACRED);
|
||||
|
||||
/* Verify AMF len */
|
||||
|
@ -630,7 +630,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
/*
|
||||
* Create Authorization/Proxy-Authorization response header based on the challege
|
||||
* in WWW-Authenticate/Proxy-Authenticate header.
|
||||
*/
|
||||
|
@ -785,7 +785,7 @@ static pj_status_t new_auth_for_req( pjsip_tx_data *tdata,
|
|||
sess->pool, auth, &hauth);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
||||
pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)hauth);
|
||||
|
||||
if (p_h_auth)
|
||||
|
@ -831,6 +831,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
|
|||
|
||||
/* Get the method. */
|
||||
method = &tdata->msg->line.req.method;
|
||||
PJ_UNUSED_ARG(method); /* Warning about unused var caused by #if below */
|
||||
|
||||
auth = sess->cached_auth.next;
|
||||
while (auth != &sess->cached_auth) {
|
||||
|
@ -869,32 +870,32 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
|
|||
}
|
||||
# endif
|
||||
|
||||
}
|
||||
}
|
||||
# if defined(PJSIP_AUTH_QOP_SUPPORT) && \
|
||||
defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \
|
||||
(PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT)
|
||||
else if (auth->qop_value == PJSIP_AUTH_QOP_AUTH) {
|
||||
/* For qop="auth", we have to re-create the authorization header.
|
||||
/* For qop="auth", we have to re-create the authorization header.
|
||||
*/
|
||||
const pjsip_cred_info *cred;
|
||||
pjsip_authorization_hdr *hauth;
|
||||
pj_status_t status;
|
||||
|
||||
cred = auth_find_cred(sess, &auth->realm,
|
||||
cred = auth_find_cred(sess, &auth->realm,
|
||||
&auth->last_chal->scheme);
|
||||
if (!cred) {
|
||||
auth = auth->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
status = auth_respond( tdata->pool, auth->last_chal,
|
||||
tdata->msg->line.req.uri,
|
||||
status = auth_respond( tdata->pool, auth->last_chal,
|
||||
tdata->msg->line.req.uri,
|
||||
cred,
|
||||
&tdata->msg->line.req.method,
|
||||
sess->pool, auth, &hauth);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
|
||||
//pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
|
||||
pj_list_push_back(&added, hauth);
|
||||
}
|
||||
|
@ -983,7 +984,7 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
|
|||
hdr->type == PJSIP_H_PROXY_AUTHORIZATION))
|
||||
{
|
||||
sent_auth = (pjsip_authorization_hdr*) hdr;
|
||||
if (pj_stricmp(&hchal->challenge.common.realm,
|
||||
if (pj_stricmp(&hchal->challenge.common.realm,
|
||||
&sent_auth->credential.common.realm )==0)
|
||||
{
|
||||
/* If this authorization has empty response, remove it. */
|
||||
|
@ -1054,21 +1055,21 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
|
|||
}
|
||||
|
||||
/* Find credential to be used for the challenge. */
|
||||
cred = auth_find_cred( sess, &hchal->challenge.common.realm,
|
||||
cred = auth_find_cred( sess, &hchal->challenge.common.realm,
|
||||
&hchal->scheme);
|
||||
if (!cred) {
|
||||
const pj_str_t *realm = &hchal->challenge.common.realm;
|
||||
PJ_LOG(4,(THIS_FILE,
|
||||
PJ_LOG(4,(THIS_FILE,
|
||||
"Unable to set auth for %s: can not find credential for %.*s/%.*s",
|
||||
tdata->obj_name,
|
||||
tdata->obj_name,
|
||||
realm->slen, realm->ptr,
|
||||
hchal->scheme.slen, hchal->scheme.ptr));
|
||||
return PJSIP_ENOCREDENTIAL;
|
||||
}
|
||||
|
||||
/* Respond to authorization challenge. */
|
||||
status = auth_respond( req_pool, hchal, uri, cred,
|
||||
&tdata->msg->line.req.method,
|
||||
status = auth_respond( req_pool, hchal, uri, cred,
|
||||
&tdata->msg->line.req.method,
|
||||
sess->pool, cached_auth, h_auth);
|
||||
return status;
|
||||
}
|
||||
|
@ -1147,7 +1148,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_reinit_req( pjsip_auth_clt_sess *sess,
|
|||
/* Create authorization header for this challenge, and update
|
||||
* authorization session.
|
||||
*/
|
||||
status = process_auth( tdata->pool, hchal, tdata->msg->line.req.uri,
|
||||
status = process_auth( tdata->pool, hchal, tdata->msg->line.req.uri,
|
||||
tdata, sess, cached_auth, &hauth);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <pjsip/sip_dialog.h>
|
||||
#include <pjsip/sip_ua_layer.h>
|
||||
|
@ -73,8 +73,8 @@ static pj_status_t create_dialog( pjsip_user_agent *ua,
|
|||
if (!endpt)
|
||||
return PJ_EINVALIDOP;
|
||||
|
||||
pool = pjsip_endpt_create_pool(endpt, "dlg%p",
|
||||
PJSIP_POOL_LEN_DIALOG,
|
||||
pool = pjsip_endpt_create_pool(endpt, "dlg%p",
|
||||
PJSIP_POOL_LEN_DIALOG,
|
||||
PJSIP_POOL_INC_DIALOG);
|
||||
if (!pool)
|
||||
return PJ_ENOMEM;
|
||||
|
@ -194,8 +194,8 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
|
|||
/* Init local info. */
|
||||
dlg->local.info = pjsip_from_hdr_create(dlg->pool);
|
||||
pj_strdup_with_null(dlg->pool, &dlg->local.info_str, local_uri);
|
||||
dlg->local.info->uri = pjsip_parse_uri(dlg->pool,
|
||||
dlg->local.info_str.ptr,
|
||||
dlg->local.info->uri = pjsip_parse_uri(dlg->pool,
|
||||
dlg->local.info_str.ptr,
|
||||
dlg->local.info_str.slen, 0);
|
||||
if (!dlg->local.info->uri) {
|
||||
status = PJSIP_EINVALIDURI;
|
||||
|
@ -214,10 +214,10 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
|
|||
dlg->local.cseq = dlg->local.first_cseq;
|
||||
|
||||
/* Init local contact. */
|
||||
pj_strdup_with_null(dlg->pool, &tmp,
|
||||
pj_strdup_with_null(dlg->pool, &tmp,
|
||||
local_contact ? local_contact : local_uri);
|
||||
dlg->local.contact = (pjsip_contact_hdr*)
|
||||
pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr,
|
||||
pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr,
|
||||
tmp.slen, NULL);
|
||||
if (!dlg->local.contact) {
|
||||
status = PJSIP_EINVALIDURI;
|
||||
|
@ -227,8 +227,8 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
|
|||
/* Init remote info. */
|
||||
dlg->remote.info = pjsip_to_hdr_create(dlg->pool);
|
||||
pj_strdup_with_null(dlg->pool, &dlg->remote.info_str, remote_uri);
|
||||
dlg->remote.info->uri = pjsip_parse_uri(dlg->pool,
|
||||
dlg->remote.info_str.ptr,
|
||||
dlg->remote.info->uri = pjsip_parse_uri(dlg->pool,
|
||||
dlg->remote.info_str.ptr,
|
||||
dlg->remote.info_str.slen, 0);
|
||||
if (!dlg->remote.info->uri) {
|
||||
status = PJSIP_EINVALIDURI;
|
||||
|
@ -239,7 +239,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
|
|||
if (PJSIP_URI_SCHEME_IS_SIP(dlg->remote.info->uri) ||
|
||||
PJSIP_URI_SCHEME_IS_SIPS(dlg->remote.info->uri))
|
||||
{
|
||||
pjsip_sip_uri *sip_uri = (pjsip_sip_uri *)
|
||||
pjsip_sip_uri *sip_uri = (pjsip_sip_uri *)
|
||||
pjsip_uri_get_uri(dlg->remote.info->uri);
|
||||
if (!pj_list_empty(&sip_uri->header_param)) {
|
||||
pj_str_t tmp;
|
||||
|
@ -248,10 +248,10 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
|
|||
pj_list_init(&sip_uri->header_param);
|
||||
|
||||
/* Print URI */
|
||||
tmp.ptr = (char*) pj_pool_alloc(dlg->pool,
|
||||
tmp.ptr = (char*) pj_pool_alloc(dlg->pool,
|
||||
dlg->remote.info_str.slen);
|
||||
tmp.slen = pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR,
|
||||
sip_uri, tmp.ptr,
|
||||
sip_uri, tmp.ptr,
|
||||
dlg->remote.info_str.slen);
|
||||
|
||||
if (tmp.slen < 1) {
|
||||
|
@ -282,7 +282,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uac( pjsip_user_agent *ua,
|
|||
pj_list_init(&dlg->route_set);
|
||||
|
||||
/* Init client authentication session. */
|
||||
status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
|
||||
status = pjsip_auth_clt_init(&dlg->auth_sess, dlg->endpt,
|
||||
dlg->pool, 0);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
@ -332,11 +332,11 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
PJ_ASSERT_RETURN(rdata->msg_info.msg->type == PJSIP_REQUEST_MSG,
|
||||
PJSIP_ENOTREQUESTMSG);
|
||||
|
||||
/* Request must not have To tag.
|
||||
/* Request must not have To tag.
|
||||
* This should have been checked in the user agent (or application?).
|
||||
*/
|
||||
PJ_ASSERT_RETURN(rdata->msg_info.to->tag.slen == 0, PJ_EINVALIDOP);
|
||||
|
||||
|
||||
/* The request must be a dialog establishing request. */
|
||||
PJ_ASSERT_RETURN(
|
||||
pjsip_method_creates_dialog(&rdata->msg_info.msg->line.req.method),
|
||||
|
@ -384,9 +384,9 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
/* Init local contact. */
|
||||
/* TODO:
|
||||
* Section 12.1.1, paragraph about using SIPS URI in Contact.
|
||||
* If the request that initiated the dialog contained a SIPS URI
|
||||
* in the Request-URI or in the top Record-Route header field value,
|
||||
* if there was any, or the Contact header field if there was no
|
||||
* If the request that initiated the dialog contained a SIPS URI
|
||||
* in the Request-URI or in the top Record-Route header field value,
|
||||
* if there was any, or the Contact header field if there was no
|
||||
* Record-Route header field, the Contact header field in the response
|
||||
* MUST be a SIPS URI.
|
||||
*/
|
||||
|
@ -395,7 +395,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
|
||||
pj_strdup_with_null(dlg->pool, &tmp, contact);
|
||||
dlg->local.contact = (pjsip_contact_hdr*)
|
||||
pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr,
|
||||
pjsip_parse_hdr(dlg->pool, &HCONTACT, tmp.ptr,
|
||||
tmp.slen, NULL);
|
||||
if (!dlg->local.contact) {
|
||||
status = PJSIP_EINVALIDURI;
|
||||
|
@ -408,7 +408,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
}
|
||||
|
||||
/* Init remote info from the From header. */
|
||||
dlg->remote.info = (pjsip_fromto_hdr*)
|
||||
dlg->remote.info = (pjsip_fromto_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, rdata->msg_info.from);
|
||||
pjsip_fromto_hdr_set_to(dlg->remote.info);
|
||||
|
||||
|
@ -425,7 +425,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
pj_strdup(dlg->pool, &dlg->remote.info_str, &tmp);
|
||||
|
||||
|
||||
/* Init remote's contact from Contact header.
|
||||
/* Init remote's contact from Contact header.
|
||||
* Iterate the Contact URI until we find sip: or sips: scheme.
|
||||
*/
|
||||
do {
|
||||
|
@ -451,7 +451,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
goto on_error;
|
||||
}
|
||||
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, (pjsip_hdr*)contact_hdr);
|
||||
|
||||
/* Init remote's CSeq from CSeq header */
|
||||
|
@ -463,22 +463,22 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
/* Initial role is UAS */
|
||||
dlg->role = PJSIP_ROLE_UAS;
|
||||
|
||||
/* Secure?
|
||||
/* Secure?
|
||||
* RFC 3261 Section 12.1.1:
|
||||
* If the request arrived over TLS, and the Request-URI contained a
|
||||
* If the request arrived over TLS, and the Request-URI contained a
|
||||
* SIPS URI, the 'secure' flag is set to TRUE.
|
||||
*/
|
||||
dlg->secure = PJSIP_TRANSPORT_IS_SECURE(rdata->tp_info.transport) &&
|
||||
PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.msg->line.req.uri);
|
||||
|
||||
/* Call-ID */
|
||||
dlg->call_id = (pjsip_cid_hdr*)
|
||||
dlg->call_id = (pjsip_cid_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, rdata->msg_info.cid);
|
||||
|
||||
/* Route set.
|
||||
/* Route set.
|
||||
* RFC 3261 Section 12.1.1:
|
||||
* The route set MUST be set to the list of URIs in the Record-Route
|
||||
* header field from the request, taken in order and preserving all URI
|
||||
* The route set MUST be set to the list of URIs in the Record-Route
|
||||
* header field from the request, taken in order and preserving all URI
|
||||
* parameters. If no Record-Route header field is present in the request,
|
||||
* the route set MUST be set to the empty set.
|
||||
*/
|
||||
|
@ -498,7 +498,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_create_uas( pjsip_user_agent *ua,
|
|||
rr = rr->next;
|
||||
if (rr == (void*)&rdata->msg_info.msg->hdr)
|
||||
break;
|
||||
rr = (pjsip_route_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
|
||||
rr = (pjsip_route_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
|
||||
PJSIP_H_RECORD_ROUTE, rr);
|
||||
}
|
||||
dlg->route_set_frozen = PJ_TRUE;
|
||||
|
@ -620,7 +620,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
|
|||
|
||||
/* Check arguments. */
|
||||
PJ_ASSERT_RETURN(first_dlg && rdata && new_dlg, PJ_EINVAL);
|
||||
|
||||
|
||||
/* rdata must be response message. */
|
||||
PJ_ASSERT_RETURN(msg->type == PJSIP_RESPONSE_MSG,
|
||||
PJSIP_ENOTRESPONSEMSG);
|
||||
|
@ -648,7 +648,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
|
|||
dlg->target = (pjsip_uri*) pjsip_uri_clone(dlg->pool, contact->uri);
|
||||
|
||||
/* Clone local info. */
|
||||
dlg->local.info = (pjsip_fromto_hdr*)
|
||||
dlg->local.info = (pjsip_fromto_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, first_dlg->local.info);
|
||||
|
||||
/* Clone local tag. */
|
||||
|
@ -660,11 +660,11 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
|
|||
dlg->local.cseq = first_dlg->local.cseq;
|
||||
|
||||
/* Clone local Contact. */
|
||||
dlg->local.contact = (pjsip_contact_hdr*)
|
||||
dlg->local.contact = (pjsip_contact_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, first_dlg->local.contact);
|
||||
|
||||
/* Clone remote info. */
|
||||
dlg->remote.info = (pjsip_fromto_hdr*)
|
||||
dlg->remote.info = (pjsip_fromto_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, first_dlg->remote.info);
|
||||
|
||||
/* Set remote tag from the response. */
|
||||
|
@ -689,7 +689,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
|
|||
dlg->secure = PJSIP_URI_SCHEME_IS_SIPS(dlg->target);
|
||||
|
||||
/* Clone Call-ID header. */
|
||||
dlg->call_id = (pjsip_cid_hdr*)
|
||||
dlg->call_id = (pjsip_cid_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, first_dlg->call_id);
|
||||
|
||||
/* Get route-set from the response. */
|
||||
|
@ -707,7 +707,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_fork( const pjsip_dialog *first_dlg,
|
|||
//dlg->route_set_frozen = PJ_TRUE;
|
||||
|
||||
/* Clone client authentication session. */
|
||||
status = pjsip_auth_clt_clone(dlg->pool, &dlg->auth_sess,
|
||||
status = pjsip_auth_clt_clone(dlg->pool, &dlg->auth_sess,
|
||||
&first_dlg->auth_sess);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
@ -841,13 +841,13 @@ PJ_DEF(pj_status_t) pjsip_dlg_inc_session( pjsip_dialog *dlg,
|
|||
*/
|
||||
PJ_DEF(void) pjsip_dlg_inc_lock(pjsip_dialog *dlg)
|
||||
{
|
||||
PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_inc_lock(), sess_count=%d",
|
||||
PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_inc_lock(), sess_count=%d",
|
||||
dlg->sess_count));
|
||||
|
||||
pj_mutex_lock(dlg->mutex_);
|
||||
dlg->sess_count++;
|
||||
|
||||
PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_inc_lock(), sess_count=%d",
|
||||
PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_inc_lock(), sess_count=%d",
|
||||
dlg->sess_count));
|
||||
}
|
||||
|
||||
|
@ -858,7 +858,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)
|
|||
{
|
||||
pj_status_t status;
|
||||
|
||||
PJ_LOG(6,(dlg->obj_name,"Entering pjsip_dlg_try_inc_lock(), sess_count=%d",
|
||||
PJ_LOG(6,(dlg->obj_name,"Entering pjsip_dlg_try_inc_lock(), sess_count=%d",
|
||||
dlg->sess_count));
|
||||
|
||||
status = pj_mutex_trylock(dlg->mutex_);
|
||||
|
@ -869,7 +869,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_try_inc_lock(pjsip_dialog *dlg)
|
|||
|
||||
dlg->sess_count++;
|
||||
|
||||
PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_try_inc_lock(), sess_count=%d",
|
||||
PJ_LOG(6,(dlg->obj_name, "Leaving pjsip_dlg_try_inc_lock(), sess_count=%d",
|
||||
dlg->sess_count));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
@ -884,7 +884,7 @@ PJ_DEF(void) pjsip_dlg_dec_lock(pjsip_dialog *dlg)
|
|||
{
|
||||
PJ_ASSERT_ON_FAIL(dlg!=NULL, return);
|
||||
|
||||
PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_dec_lock(), sess_count=%d",
|
||||
PJ_LOG(6,(dlg->obj_name, "Entering pjsip_dlg_dec_lock(), sess_count=%d",
|
||||
dlg->sess_count));
|
||||
|
||||
pj_assert(dlg->sess_count > 0);
|
||||
|
@ -959,7 +959,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
|
|||
PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(dlg->usage_cnt < PJSIP_MAX_MODULE, PJ_EBUG);
|
||||
|
||||
PJ_LOG(5,(dlg->obj_name,
|
||||
PJ_LOG(5,(dlg->obj_name,
|
||||
"Module %.*s added as dialog usage, data=%p",
|
||||
(int)mod->name.slen, mod->name.ptr, mod_data));
|
||||
|
||||
|
@ -976,7 +976,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
|
|||
* call transfer on the same dialog.
|
||||
* So return PJ_SUCCESS here.
|
||||
*/
|
||||
PJ_LOG(4,(dlg->obj_name,
|
||||
PJ_LOG(4,(dlg->obj_name,
|
||||
"Module %.*s already registered as dialog usage, "
|
||||
"updating the data %p",
|
||||
(int)mod->name.slen, mod->name.ptr, mod_data));
|
||||
|
@ -999,7 +999,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
|
|||
*/
|
||||
pj_array_insert(dlg->usage, sizeof(dlg->usage[0]), dlg->usage_cnt,
|
||||
index, &mod);
|
||||
|
||||
|
||||
/* Set module data. */
|
||||
dlg->mod_data[mod->id] = mod_data;
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_add_usage( pjsip_dialog *dlg,
|
|||
|
||||
|
||||
/*
|
||||
* Attach module specific data to the dialog. Application can also set
|
||||
* Attach module specific data to the dialog. Application can also set
|
||||
* the value directly by accessing dlg->mod_data[module_id].
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pjsip_dlg_set_mod_data( pjsip_dialog *dlg,
|
||||
|
@ -1043,7 +1043,7 @@ PJ_DEF(void*) pjsip_dlg_get_mod_data( pjsip_dialog *dlg,
|
|||
|
||||
/*
|
||||
* Create a new request within dialog (i.e. after the dialog session has been
|
||||
* established). The construction of such requests follows the rule in
|
||||
* established). The construction of such requests follows the rule in
|
||||
* RFC3261 section 12.2.1.
|
||||
*/
|
||||
static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
|
||||
|
@ -1057,7 +1057,7 @@ static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
|
|||
pj_status_t status;
|
||||
|
||||
/* Contact Header field.
|
||||
* Contact can only be present in requests that establish dialog (in the
|
||||
* Contact can only be present in requests that establish dialog (in the
|
||||
* core SIP spec, only INVITE).
|
||||
*/
|
||||
if (pjsip_method_creates_dialog(method))
|
||||
|
@ -1082,7 +1082,7 @@ static pj_status_t dlg_create_request_throw( pjsip_dialog *dlg,
|
|||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Just copy dialog route-set to Route header.
|
||||
/* Just copy dialog route-set to Route header.
|
||||
* The transaction will do the processing as specified in Section 12.2.1
|
||||
* of RFC 3261 in function tsx_process_route() in sip_transaction.c.
|
||||
*/
|
||||
|
@ -1192,10 +1192,10 @@ PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
|
|||
* ACK nor CANCEL.
|
||||
*/
|
||||
if (msg->line.req.method.id != PJSIP_CANCEL_METHOD &&
|
||||
msg->line.req.method.id != PJSIP_ACK_METHOD)
|
||||
msg->line.req.method.id != PJSIP_ACK_METHOD)
|
||||
{
|
||||
pjsip_cseq_hdr *ch;
|
||||
|
||||
|
||||
ch = PJSIP_MSG_CSEQ_HDR(msg);
|
||||
PJ_ASSERT_RETURN(ch!=NULL, PJ_EBUG);
|
||||
|
||||
|
@ -1244,7 +1244,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
|
|||
pjsip_tx_data_set_transport(tdata, &dlg->tp_sel);
|
||||
|
||||
/* Send request */
|
||||
status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata,
|
||||
status = pjsip_endpt_send_request_stateless(dlg->endpt, tdata,
|
||||
NULL, NULL);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
@ -1259,7 +1259,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_send_request( pjsip_dialog *dlg,
|
|||
on_error:
|
||||
/* Unlock dialog, may destroy dialog. */
|
||||
pjsip_dlg_dec_lock(dlg);
|
||||
|
||||
|
||||
/* Whatever happen delete the message. */
|
||||
pjsip_tx_data_dec_ref( tdata );
|
||||
pj_log_pop_indent();
|
||||
|
@ -1286,13 +1286,13 @@ static void dlg_beautify_response(pjsip_dialog *dlg,
|
|||
if (add_headers && pjsip_method_creates_dialog(&cseq->method)) {
|
||||
/* Add Contact header for 1xx, 2xx, 3xx and 485 response. */
|
||||
if (st_class==2 || st_class==3 || (st_class==1 && st_code != 100) ||
|
||||
st_code==485)
|
||||
st_code==485)
|
||||
{
|
||||
/* Add contact header only if one is not present. */
|
||||
if (pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL) == 0 &&
|
||||
pjsip_msg_find_hdr_by_name(tdata->msg, &HCONTACT, NULL) == 0)
|
||||
pjsip_msg_find_hdr_by_name(tdata->msg, &HCONTACT, NULL) == 0)
|
||||
{
|
||||
hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool,
|
||||
hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool,
|
||||
dlg->local.contact);
|
||||
pjsip_msg_add_hdr(tdata->msg, hdr);
|
||||
}
|
||||
|
@ -1301,7 +1301,7 @@ static void dlg_beautify_response(pjsip_dialog *dlg,
|
|||
/* Add Allow header in 18x, 2xx and 405 response. */
|
||||
if ((((st_code/10==18 || st_class==2) && dlg->add_allow)
|
||||
|| st_code==405) &&
|
||||
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ALLOW, NULL)==NULL)
|
||||
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_ALLOW, NULL)==NULL)
|
||||
{
|
||||
c_hdr = pjsip_endpt_get_capability(dlg->endpt,
|
||||
PJSIP_H_ALLOW, NULL);
|
||||
|
@ -1312,8 +1312,8 @@ static void dlg_beautify_response(pjsip_dialog *dlg,
|
|||
}
|
||||
|
||||
/* Add Supported header in 2xx response. */
|
||||
if (st_class==2 &&
|
||||
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL)==NULL)
|
||||
if (st_class==2 &&
|
||||
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL)==NULL)
|
||||
{
|
||||
c_hdr = pjsip_endpt_get_capability(dlg->endpt,
|
||||
PJSIP_H_SUPPORTED, NULL);
|
||||
|
@ -1400,7 +1400,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_modify_response( pjsip_dialog *dlg,
|
|||
tdata->msg->line.status.reason = *pjsip_get_status_text(st_code);
|
||||
}
|
||||
|
||||
/* Remove existing Contact header (without this, when dialog sent
|
||||
/* Remove existing Contact header (without this, when dialog sent
|
||||
* 180 and then 302, the Contact in 302 will not get updated).
|
||||
*/
|
||||
hdr = (pjsip_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CONTACT, NULL);
|
||||
|
@ -1445,13 +1445,13 @@ PJ_DEF(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
|
|||
PJ_LOG(5,(dlg->obj_name, "Sending %s",
|
||||
pjsip_tx_data_get_info(tdata)));
|
||||
|
||||
/* Check that transaction method and cseq match the response.
|
||||
/* Check that transaction method and cseq match the response.
|
||||
* This operation is sloooww (search CSeq header twice), that's why
|
||||
* we only do it in debug mode.
|
||||
*/
|
||||
#if defined(PJ_DEBUG) && PJ_DEBUG!=0
|
||||
PJ_ASSERT_RETURN( PJSIP_MSG_CSEQ_HDR(tdata->msg)->cseq == tsx->cseq &&
|
||||
pjsip_method_cmp(&PJSIP_MSG_CSEQ_HDR(tdata->msg)->method,
|
||||
pjsip_method_cmp(&PJSIP_MSG_CSEQ_HDR(tdata->msg)->method,
|
||||
&tsx->method)==0,
|
||||
PJ_EINVALIDOP);
|
||||
#endif
|
||||
|
@ -1477,7 +1477,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_send_response( pjsip_dialog *dlg,
|
|||
/* Ask transaction to send the response */
|
||||
status = pjsip_tsx_send_msg(tsx, tdata);
|
||||
|
||||
/* This function must decrement transmit data request counter
|
||||
/* This function must decrement transmit data request counter
|
||||
* regardless of the operation status. The transaction only
|
||||
* decrements the counter if the operation is successful.
|
||||
*/
|
||||
|
@ -1562,7 +1562,7 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
/* Check CSeq */
|
||||
if (rdata->msg_info.cseq->cseq <= dlg->remote.cseq &&
|
||||
rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD &&
|
||||
rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD)
|
||||
rdata->msg_info.msg->line.req.method.id != PJSIP_CANCEL_METHOD)
|
||||
{
|
||||
/* Invalid CSeq.
|
||||
* Respond statelessly with 500 (Internal Server Error)
|
||||
|
@ -1594,8 +1594,8 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
}
|
||||
|
||||
/* Create UAS transaction for this request. */
|
||||
if (pjsip_rdata_get_tsx(rdata) == NULL &&
|
||||
rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD)
|
||||
if (pjsip_rdata_get_tsx(rdata) == NULL &&
|
||||
rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD)
|
||||
{
|
||||
status = pjsip_tsx_create_uas(dlg->ua, rdata, &tsx);
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -1629,7 +1629,7 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
pjsip_contact_hdr *contact;
|
||||
|
||||
contact = (pjsip_contact_hdr*)
|
||||
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
|
||||
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
|
||||
NULL);
|
||||
if (contact && contact->uri &&
|
||||
(dlg->remote.contact==NULL ||
|
||||
|
@ -1637,7 +1637,7 @@ void pjsip_dlg_on_rx_request( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
dlg->remote.contact->uri,
|
||||
contact->uri)))
|
||||
{
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, contact);
|
||||
dlg->target = dlg->remote.contact->uri;
|
||||
}
|
||||
|
@ -1687,11 +1687,11 @@ on_return:
|
|||
static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
|
||||
{
|
||||
const pjsip_hdr *hdr, *end_hdr;
|
||||
pj_int32_t msg_cseq;
|
||||
//pj_int32_t msg_cseq;
|
||||
const pjsip_msg *msg;
|
||||
|
||||
msg = rdata->msg_info.msg;
|
||||
msg_cseq = rdata->msg_info.cseq->cseq;
|
||||
//msg_cseq = rdata->msg_info.cseq->cseq;
|
||||
|
||||
/* Ignore if route set has been frozen */
|
||||
if (dlg->route_set_frozen)
|
||||
|
@ -1707,7 +1707,7 @@ static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
|
|||
return;
|
||||
|
||||
/* Ignore subsequent responses with higher CSeq than initial CSeq.
|
||||
* Unfortunately this would be broken when the first request is
|
||||
* Unfortunately this would be broken when the first request is
|
||||
* challenged!
|
||||
*/
|
||||
//if (msg_cseq != dlg->local.first_cseq)
|
||||
|
@ -1746,8 +1746,8 @@ static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
|
|||
|
||||
PJ_LOG(5,(dlg->obj_name, "Route-set updated"));
|
||||
|
||||
/* Freeze the route set only when the route set comes in 2xx response.
|
||||
* If it is in 1xx response, prepare to recompute the route set when
|
||||
/* Freeze the route set only when the route set comes in 2xx response.
|
||||
* If it is in 1xx response, prepare to recompute the route set when
|
||||
* the 2xx response comes in.
|
||||
*
|
||||
* There is a debate whether route set should be frozen when the dialog
|
||||
|
@ -1755,11 +1755,11 @@ static void dlg_update_routeset(pjsip_dialog *dlg, const pjsip_rx_data *rdata)
|
|||
* it is safer to not freeze the route set (thus recompute the route set
|
||||
* upon receiving 2xx response). Also RFC 3261 says so in 13.2.2.4.
|
||||
*
|
||||
* The pjsip_method_creates_dialog() check protects from wrongly
|
||||
* The pjsip_method_creates_dialog() check protects from wrongly
|
||||
* freezing the route set upon receiving 200/OK response for PRACK.
|
||||
*/
|
||||
if (pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
|
||||
PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200))
|
||||
PJSIP_IS_STATUS_IN_CLASS(msg->line.status.code, 200))
|
||||
{
|
||||
dlg->route_set_frozen = PJ_TRUE;
|
||||
PJ_LOG(5,(dlg->obj_name, "Route-set frozen"));
|
||||
|
@ -1788,7 +1788,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
/* Keep the response's status code */
|
||||
res_code = rdata->msg_info.msg->line.status.code;
|
||||
|
||||
/* When we receive response that establishes dialog, update To tag,
|
||||
/* When we receive response that establishes dialog, update To tag,
|
||||
* route set and dialog target.
|
||||
*
|
||||
* The second condition of the "if" is a workaround for forking.
|
||||
|
@ -1802,13 +1802,13 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
*
|
||||
* New update:
|
||||
* We also need to update the dialog for 1xx responses, to handle the
|
||||
* case when 100rel is used, otherwise PRACK will be sent to the
|
||||
* case when 100rel is used, otherwise PRACK will be sent to the
|
||||
* wrong target.
|
||||
*/
|
||||
if ((dlg->state == PJSIP_DIALOG_STATE_NULL &&
|
||||
if ((dlg->state == PJSIP_DIALOG_STATE_NULL &&
|
||||
pjsip_method_creates_dialog(&rdata->msg_info.cseq->method) &&
|
||||
(res_code > 100 && res_code < 300) &&
|
||||
rdata->msg_info.to->tag.slen)
|
||||
rdata->msg_info.to->tag.slen)
|
||||
||
|
||||
(dlg->role==PJSIP_ROLE_UAC &&
|
||||
!dlg->uac_has_2xx &&
|
||||
|
@ -1819,7 +1819,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
{
|
||||
pjsip_contact_hdr *contact;
|
||||
|
||||
/* Update remote capability info, when To tags in the dialog remote
|
||||
/* Update remote capability info, when To tags in the dialog remote
|
||||
* info and the incoming response are different, e.g: first response
|
||||
* with To-tag or forking, apply strict update.
|
||||
*/
|
||||
|
@ -1833,19 +1833,19 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
|
||||
/* RFC 3271 Section 12.1.2:
|
||||
* The route set MUST be set to the list of URIs in the Record-Route
|
||||
* header field from the response, taken in reverse order and
|
||||
* preserving all URI parameters. If no Record-Route header field
|
||||
* is present in the response, the route set MUST be set to the
|
||||
* header field from the response, taken in reverse order and
|
||||
* preserving all URI parameters. If no Record-Route header field
|
||||
* is present in the response, the route set MUST be set to the
|
||||
* empty set. This route set, even if empty, overrides any pre-existing
|
||||
* route set for future requests in this dialog.
|
||||
*/
|
||||
dlg_update_routeset(dlg, rdata);
|
||||
|
||||
/* The remote target MUST be set to the URI from the Contact header
|
||||
/* The remote target MUST be set to the URI from the Contact header
|
||||
* field of the response.
|
||||
*/
|
||||
contact = (pjsip_contact_hdr*)
|
||||
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
|
||||
pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT,
|
||||
NULL);
|
||||
if (contact && contact->uri &&
|
||||
(dlg->remote.contact==NULL ||
|
||||
|
@ -1853,7 +1853,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
dlg->remote.contact->uri,
|
||||
contact->uri)))
|
||||
{
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, contact);
|
||||
dlg->target = dlg->remote.contact->uri;
|
||||
}
|
||||
|
@ -1863,15 +1863,15 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
/* Prevent dialog from being updated just in case more 2xx
|
||||
* gets through this dialog (it shouldn't happen).
|
||||
*/
|
||||
if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx &&
|
||||
res_code/100==2)
|
||||
if (dlg->role==PJSIP_ROLE_UAC && !dlg->uac_has_2xx &&
|
||||
res_code/100==2)
|
||||
{
|
||||
dlg->uac_has_2xx = PJ_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update remote target (again) when receiving 2xx response messages
|
||||
* that's defined as target refresh.
|
||||
* that's defined as target refresh.
|
||||
*
|
||||
* Also upon receiving 2xx response, recheck again the route set.
|
||||
* This is for compatibility with RFC 2543, as described in Section
|
||||
|
@ -1881,7 +1881,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
identifier of an existing dialog, the dialog MUST be transitioned to
|
||||
the "confirmed" state, and the route set for the dialog MUST be
|
||||
recomputed based on the 2xx response using the procedures of Section
|
||||
12.2.1.2.
|
||||
12.2.1.2.
|
||||
|
||||
Note that the only piece of state that is recomputed is the route
|
||||
set. Other pieces of state such as the highest sequence numbers
|
||||
|
@ -1896,7 +1896,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
pjsip_contact_hdr *contact;
|
||||
|
||||
contact = (pjsip_contact_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
|
||||
PJSIP_H_CONTACT,
|
||||
PJSIP_H_CONTACT,
|
||||
NULL);
|
||||
if (contact && contact->uri &&
|
||||
(dlg->remote.contact==NULL ||
|
||||
|
@ -1904,7 +1904,7 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
dlg->remote.contact->uri,
|
||||
contact->uri)))
|
||||
{
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
dlg->remote.contact = (pjsip_contact_hdr*)
|
||||
pjsip_hdr_clone(dlg->pool, contact);
|
||||
dlg->target = dlg->remote.contact->uri;
|
||||
}
|
||||
|
@ -1942,8 +1942,8 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
if (dlg->usage_cnt==0) {
|
||||
pj_status_t status;
|
||||
|
||||
if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD &&
|
||||
rdata->msg_info.msg->line.status.code/100 == 2)
|
||||
if (rdata->msg_info.cseq->method.id==PJSIP_INVITE_METHOD &&
|
||||
rdata->msg_info.msg->line.status.code/100 == 2)
|
||||
{
|
||||
pjsip_tx_data *ack;
|
||||
|
||||
|
@ -1957,11 +1957,11 @@ void pjsip_dlg_on_rx_response( pjsip_dialog *dlg, pjsip_rx_data *rdata )
|
|||
{
|
||||
pjsip_transaction *tsx = pjsip_rdata_get_tsx(rdata);
|
||||
pjsip_tx_data *tdata;
|
||||
|
||||
status = pjsip_auth_clt_reinit_req( &dlg->auth_sess,
|
||||
|
||||
status = pjsip_auth_clt_reinit_req( &dlg->auth_sess,
|
||||
rdata, tsx->last_tx,
|
||||
&tdata);
|
||||
|
||||
|
||||
if (status == PJ_SUCCESS) {
|
||||
/* Re-send request. */
|
||||
status = pjsip_dlg_send_request(dlg, tdata, -1, NULL);
|
||||
|
@ -2014,7 +2014,7 @@ void pjsip_dlg_on_tsx_state( pjsip_dialog *dlg,
|
|||
* the tsx_count if we're still attached to the transaction.
|
||||
*/
|
||||
if (tsx->state == PJSIP_TSX_STATE_TERMINATED &&
|
||||
tsx->mod_data[dlg->ua->id] == dlg)
|
||||
tsx->mod_data[dlg->ua->id] == dlg)
|
||||
{
|
||||
pj_assert(dlg->tsx_count>0);
|
||||
--dlg->tsx_count;
|
||||
|
@ -2044,7 +2044,7 @@ PJ_DEF(pjsip_dialog_cap_status) pjsip_dlg_remote_has_cap(
|
|||
|
||||
pjsip_dlg_inc_lock(dlg);
|
||||
|
||||
hdr = (const pjsip_generic_array_hdr*)
|
||||
hdr = (const pjsip_generic_array_hdr*)
|
||||
pjsip_dlg_get_remote_cap_hdr(dlg, htype, hname);
|
||||
if (!hdr) {
|
||||
cap_status = PJSIP_DIALOG_CAP_UNKNOWN;
|
||||
|
@ -2071,7 +2071,7 @@ PJ_DEF(pj_status_t) pjsip_dlg_update_remote_cap(pjsip_dialog *dlg,
|
|||
const pjsip_msg *msg,
|
||||
pj_bool_t strict)
|
||||
{
|
||||
pjsip_hdr_e htypes[] =
|
||||
pjsip_hdr_e htypes[] =
|
||||
{ PJSIP_H_ACCEPT, PJSIP_H_ALLOW, PJSIP_H_SUPPORTED };
|
||||
unsigned i;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
@ -30,7 +30,7 @@
|
|||
** UAS tests.
|
||||
**
|
||||
** This file performs various tests for UAC transactions. Each test will have
|
||||
** a different Via branch param so that message receiver module and
|
||||
** a different Via branch param so that message receiver module and
|
||||
** transaction user module can identify which test is being carried out.
|
||||
**
|
||||
** TEST1_BRANCH_ID
|
||||
|
@ -47,7 +47,7 @@
|
|||
** response is sent.
|
||||
**
|
||||
** TEST4_BRANCH_ID
|
||||
** Transaction retransmits last response (if any) without notifying
|
||||
** Transaction retransmits last response (if any) without notifying
|
||||
** transaction user upon receiving request retransmissions on TRYING
|
||||
** state
|
||||
**
|
||||
|
@ -66,7 +66,7 @@
|
|||
**
|
||||
** TEST9_BRANCH_ID
|
||||
** INVITE transaction MUST cease retransmission of final response when
|
||||
** ACK is received. (Note: PJSIP also retransmit 2xx final response
|
||||
** ACK is received. (Note: PJSIP also retransmit 2xx final response
|
||||
** until it's terminated by user).
|
||||
** Transaction also MUST terminate in T4 seconds.
|
||||
** (Only applicable for non-reliable transports).
|
||||
|
@ -116,7 +116,7 @@
|
|||
#define TEST4_STATUS_CODE 200
|
||||
#define TEST4_REQUEST_COUNT 2
|
||||
#define TEST5_PROVISIONAL_CODE 100
|
||||
#define TEST5_STATUS_CODE 200
|
||||
#define TEST5_STATUS_CODE 200
|
||||
#define TEST5_REQUEST_COUNT 2
|
||||
#define TEST5_RESPONSE_COUNT 2
|
||||
#define TEST6_PROVISIONAL_CODE 100
|
||||
|
@ -146,7 +146,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e);
|
|||
static pj_bool_t on_rx_message(pjsip_rx_data *rdata);
|
||||
|
||||
/* UAC transaction user module. */
|
||||
static pjsip_module tsx_user =
|
||||
static pjsip_module tsx_user =
|
||||
{
|
||||
NULL, NULL, /* prev and next */
|
||||
{ "Tsx-UAS-User", 12}, /* Name. */
|
||||
|
@ -164,7 +164,7 @@ static pjsip_module tsx_user =
|
|||
};
|
||||
|
||||
/* Module to send request. */
|
||||
static pjsip_module msg_sender =
|
||||
static pjsip_module msg_sender =
|
||||
{
|
||||
NULL, NULL, /* prev and next */
|
||||
{ "Msg-Sender", 10}, /* Name. */
|
||||
|
@ -241,7 +241,7 @@ static void send_response( pjsip_rx_data *rdata,
|
|||
pj_status_t status;
|
||||
pjsip_tx_data *tdata;
|
||||
|
||||
status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
|
||||
status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
|
||||
&tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
app_perror(" error: unable to create response", status);
|
||||
|
@ -271,7 +271,7 @@ static void schedule_send_response( pjsip_rx_data *rdata,
|
|||
struct response *r;
|
||||
pj_time_val delay;
|
||||
|
||||
status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
|
||||
status = pjsip_endpt_create_response( endpt, rdata, status_code, NULL,
|
||||
&tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
app_perror(" error: unable to create response", status);
|
||||
|
@ -353,7 +353,7 @@ static void schedule_terminate_tsx( pjsip_transaction *tsx,
|
|||
static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
||||
{
|
||||
if (pj_stricmp2(&tsx->branch, TEST1_BRANCH_ID)==0 ||
|
||||
pj_stricmp2(&tsx->branch, TEST2_BRANCH_ID)==0)
|
||||
pj_stricmp2(&tsx->branch, TEST2_BRANCH_ID)==0)
|
||||
{
|
||||
/*
|
||||
* TEST1_BRANCH_ID tests that non-INVITE transaction transmits final
|
||||
|
@ -374,7 +374,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -100;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state must be completed. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -405,7 +405,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -110;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state must be completed. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -465,20 +465,20 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
|
||||
/* Check that status code is status_code. */
|
||||
if (tsx->status_code != TEST4_STATUS_CODE) {
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" error: incorrect status code %d "
|
||||
"(expecting %d)", tsx->status_code,
|
||||
TEST4_STATUS_CODE));
|
||||
test_complete = -120;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
test_complete = -121;
|
||||
}
|
||||
|
||||
} else if (tsx->state != PJSIP_TSX_STATE_DESTROYED)
|
||||
} else if (tsx->state != PJSIP_TSX_STATE_DESTROYED)
|
||||
{
|
||||
PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (122)",
|
||||
pjsip_tsx_state_str(tsx->state)));
|
||||
|
@ -502,7 +502,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -130;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_PROCEEDING) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -537,11 +537,11 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
/* Check that status code is status_code. */
|
||||
if (tsx->status_code != TEST6_STATUS_CODE) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code %d "
|
||||
"(expecting %d)", tsx->status_code,
|
||||
"(expecting %d)", tsx->status_code,
|
||||
TEST6_STATUS_CODE));
|
||||
test_complete = -140;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -550,7 +550,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
|
||||
} else if (tsx->state != PJSIP_TSX_STATE_PROCEEDING &&
|
||||
tsx->state != PJSIP_TSX_STATE_COMPLETED &&
|
||||
tsx->state != PJSIP_TSX_STATE_DESTROYED)
|
||||
tsx->state != PJSIP_TSX_STATE_DESTROYED)
|
||||
{
|
||||
PJ_LOG(3,(THIS_FILE, " error: unexpected state %s (142)",
|
||||
pjsip_tsx_state_str(tsx->state)));
|
||||
|
@ -561,7 +561,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
|
||||
} else
|
||||
if (pj_stricmp2(&tsx->branch, TEST7_BRANCH_ID)==0 ||
|
||||
pj_stricmp2(&tsx->branch, TEST8_BRANCH_ID)==0)
|
||||
pj_stricmp2(&tsx->branch, TEST8_BRANCH_ID)==0)
|
||||
{
|
||||
/*
|
||||
* TEST7_BRANCH_ID and TEST8_BRANCH_ID test retransmission of
|
||||
|
@ -587,7 +587,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -150;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -605,7 +605,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
} else {
|
||||
|
||||
if (tsx->retransmit_count != 10) {
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" error: incorrect retransmit count %d "
|
||||
"(expecting 10)",
|
||||
tsx->retransmit_count));
|
||||
|
@ -621,7 +621,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -152;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -656,7 +656,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -160;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_CONFIRMED) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -670,7 +670,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -162;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_TRYING) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -685,7 +685,7 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code"));
|
||||
test_complete = -164;
|
||||
}
|
||||
|
||||
|
||||
/* Previous state. */
|
||||
if (e->body.tsx_state.prev_state != PJSIP_TSX_STATE_COMPLETED) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: incorrect prev_state"));
|
||||
|
@ -703,10 +703,10 @@ static void tsx_user_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
|
|||
} else
|
||||
if (pj_stricmp2(&tsx->branch, TEST10_BRANCH_ID)==0 ||
|
||||
pj_stricmp2(&tsx->branch, TEST11_BRANCH_ID)==0 ||
|
||||
pj_stricmp2(&tsx->branch, TEST12_BRANCH_ID)==0)
|
||||
pj_stricmp2(&tsx->branch, TEST12_BRANCH_ID)==0)
|
||||
{
|
||||
if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
|
||||
|
||||
|
||||
if (!test_complete)
|
||||
test_complete = 1;
|
||||
|
||||
|
@ -740,11 +740,11 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
pj_status_t status;
|
||||
|
||||
if (pj_stricmp2(&branch_param, TEST1_BRANCH_ID) == 0 ||
|
||||
pj_stricmp2(&branch_param, TEST2_BRANCH_ID) == 0)
|
||||
pj_stricmp2(&branch_param, TEST2_BRANCH_ID) == 0)
|
||||
{
|
||||
/*
|
||||
* TEST1_BRANCH_ID tests that non-INVITE transaction transmits 2xx
|
||||
* final response using correct transport and terminates transaction
|
||||
* TEST1_BRANCH_ID tests that non-INVITE transaction transmits 2xx
|
||||
* final response using correct transport and terminates transaction
|
||||
* after 32 seconds.
|
||||
*
|
||||
* TEST2_BRANCH_ID performs similar test for non-2xx final response.
|
||||
|
@ -753,8 +753,8 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
TEST1_STATUS_CODE : TEST2_STATUS_CODE;
|
||||
|
||||
if (msg->type == PJSIP_REQUEST_MSG) {
|
||||
/* On received request, create UAS and respond with final
|
||||
* response.
|
||||
/* On received request, create UAS and respond with final
|
||||
* response.
|
||||
*/
|
||||
pjsip_transaction *tsx;
|
||||
|
||||
|
@ -810,7 +810,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
save_key(tsx);
|
||||
|
||||
send_response(rdata, tsx, TEST3_PROVISIONAL_CODE);
|
||||
schedule_send_response(rdata, &tsx->transaction_key,
|
||||
schedule_send_response(rdata, &tsx->transaction_key,
|
||||
TEST3_STATUS_CODE, 2000);
|
||||
|
||||
} else {
|
||||
|
@ -840,7 +840,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
|
||||
} else if (pj_stricmp2(&branch_param, TEST4_BRANCH_ID) == 0 ||
|
||||
pj_stricmp2(&branch_param, TEST5_BRANCH_ID) == 0 ||
|
||||
pj_stricmp2(&branch_param, TEST6_BRANCH_ID) == 0)
|
||||
pj_stricmp2(&branch_param, TEST6_BRANCH_ID) == 0)
|
||||
{
|
||||
|
||||
/* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state. */
|
||||
|
@ -877,7 +877,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
|
||||
} else {
|
||||
/* Verify the response received. */
|
||||
|
||||
|
||||
PJ_LOG(4,(THIS_FILE, " received response number %d", recv_count));
|
||||
|
||||
++recv_count;
|
||||
|
@ -892,7 +892,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
PJ_LOG(3,(THIS_FILE, " error: incorrect status code!"));
|
||||
test_complete = -133;
|
||||
|
||||
}
|
||||
}
|
||||
if (recv_count > TEST5_RESPONSE_COUNT) {
|
||||
PJ_LOG(3,(THIS_FILE, " error: not expecting response!"));
|
||||
test_complete = -134;
|
||||
|
@ -928,7 +928,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
|
||||
|
||||
} else if (pj_stricmp2(&branch_param, TEST7_BRANCH_ID) == 0 ||
|
||||
pj_stricmp2(&branch_param, TEST8_BRANCH_ID) == 0)
|
||||
pj_stricmp2(&branch_param, TEST8_BRANCH_ID) == 0)
|
||||
{
|
||||
|
||||
/*
|
||||
|
@ -971,7 +971,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
code = TEST8_STATUS_CODE;
|
||||
|
||||
if (recv_count==1) {
|
||||
|
||||
|
||||
if (rdata->msg_info.msg->line.status.code != code) {
|
||||
PJ_LOG(3,(THIS_FILE," error: invalid status code"));
|
||||
test_complete = -141;
|
||||
|
@ -987,7 +987,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
now = rdata->pkt_info.timestamp;
|
||||
|
||||
PJ_TIME_VAL_SUB(now, recv_last);
|
||||
|
||||
|
||||
msec = now.sec*1000 + now.msec;
|
||||
msec_expected = (1 << (recv_count-2)) * pjsip_cfg()->tsx.t1;
|
||||
if (msec_expected > pjsip_cfg()->tsx.t2)
|
||||
|
@ -1016,7 +1016,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
} else if (pj_stricmp2(&branch_param, TEST9_BRANCH_ID) == 0) {
|
||||
|
||||
/*
|
||||
* TEST9_BRANCH_ID tests that the retransmission of INVITE final
|
||||
* TEST9_BRANCH_ID tests that the retransmission of INVITE final
|
||||
* response should cease when ACK is received. Transaction also MUST
|
||||
* terminate in T4 seconds.
|
||||
*/
|
||||
|
@ -1059,7 +1059,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
now = rdata->pkt_info.timestamp;
|
||||
|
||||
PJ_TIME_VAL_SUB(now, recv_last);
|
||||
|
||||
|
||||
msec = now.sec*1000 + now.msec;
|
||||
msec_expected = (1 << (recv_count-2)) * pjsip_cfg()->tsx.t1;
|
||||
if (msec_expected > pjsip_cfg()->tsx.t2)
|
||||
|
@ -1081,11 +1081,11 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
pjsip_via_hdr *via;
|
||||
|
||||
status = pjsip_endpt_create_request_from_hdr(
|
||||
endpt, &pjsip_ack_method,
|
||||
endpt, &pjsip_ack_method,
|
||||
rdata->msg_info.to->uri,
|
||||
rdata->msg_info.from,
|
||||
rdata->msg_info.to,
|
||||
NULL,
|
||||
NULL,
|
||||
rdata->msg_info.cid,
|
||||
rdata->msg_info.cseq->cseq,
|
||||
NULL,
|
||||
|
@ -1120,7 +1120,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
|
||||
} else if (pj_stricmp2(&branch_param, TEST10_BRANCH_ID) == 0 ||
|
||||
pj_stricmp2(&branch_param, TEST11_BRANCH_ID) == 0 ||
|
||||
pj_stricmp2(&branch_param, TEST12_BRANCH_ID) == 0)
|
||||
pj_stricmp2(&branch_param, TEST12_BRANCH_ID) == 0)
|
||||
{
|
||||
int test_num, code1, code2;
|
||||
|
||||
|
@ -1131,6 +1131,8 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
else
|
||||
test_num=12, code1 = 200, code2 = 0;
|
||||
|
||||
PJ_UNUSED_ARG(test_num);
|
||||
|
||||
if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
|
||||
|
||||
/* On received response, create UAS. */
|
||||
|
@ -1145,7 +1147,7 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
|
||||
pjsip_tsx_recv_msg(tsx, rdata);
|
||||
save_key(tsx);
|
||||
|
||||
|
||||
schedule_send_response(rdata, &tsx_key, code1, 1000);
|
||||
|
||||
if (code2)
|
||||
|
@ -1161,11 +1163,11 @@ static pj_bool_t on_rx_message(pjsip_rx_data *rdata)
|
|||
return PJ_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* The generic test framework, used by most of the tests.
|
||||
/*
|
||||
* The generic test framework, used by most of the tests.
|
||||
*/
|
||||
static int perform_test( char *target_uri, char *from_uri,
|
||||
char *branch_param, int test_time,
|
||||
static int perform_test( char *target_uri, char *from_uri,
|
||||
char *branch_param, int test_time,
|
||||
const pjsip_method *method,
|
||||
int request_cnt, int request_interval_msec,
|
||||
int expecting_timeout)
|
||||
|
@ -1177,7 +1179,7 @@ static int perform_test( char *target_uri, char *from_uri,
|
|||
int sent_cnt;
|
||||
pj_status_t status;
|
||||
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" please standby, this will take at most %d seconds..",
|
||||
test_time));
|
||||
|
||||
|
@ -1192,7 +1194,7 @@ static int perform_test( char *target_uri, char *from_uri,
|
|||
|
||||
/* Create request. */
|
||||
status = pjsip_endpt_create_request( endpt, method, &target,
|
||||
&from, &target, NULL, NULL, -1,
|
||||
&from, &target, NULL, NULL, -1,
|
||||
NULL, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
app_perror(" Error: unable to create request", status);
|
||||
|
@ -1368,7 +1370,7 @@ static int tsx_retransmit_last_response_test(const char *title,
|
|||
PJ_LOG(3,(THIS_FILE," %s", title));
|
||||
|
||||
status = perform_test(TARGET_URI, FROM_URI, branch_id, 5,
|
||||
&pjsip_options_method,
|
||||
&pjsip_options_method,
|
||||
request_cnt, 1000, 1);
|
||||
if (status && status != TEST_TIMEOUT_ERROR)
|
||||
return status;
|
||||
|
@ -1422,7 +1424,7 @@ static int tsx_final_response_retransmission_test(void)
|
|||
|
||||
/*****************************************************************************
|
||||
**
|
||||
** TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
|
||||
** TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
|
||||
** cease when ACK is received
|
||||
**
|
||||
*****************************************************************************
|
||||
|
@ -1463,7 +1465,7 @@ static int tsx_transport_failure_test(void)
|
|||
int fail_delay;
|
||||
char *branch_id;
|
||||
char *title;
|
||||
} tests[] =
|
||||
} tests[] =
|
||||
{
|
||||
{ 0, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (no delay)" },
|
||||
{ 50, 10, TEST10_BRANCH_ID, "test10: failed transport in TRYING state (50 ms delay)" },
|
||||
|
@ -1537,13 +1539,13 @@ int tsx_uas_test(struct tsx_test_param *param)
|
|||
test_param = param;
|
||||
tp_flag = pjsip_transport_get_flag_from_type((pjsip_transport_type_e)param->type);
|
||||
|
||||
pj_ansi_sprintf(TARGET_URI, "sip:bob@127.0.0.1:%d;transport=%s",
|
||||
pj_ansi_sprintf(TARGET_URI, "sip:bob@127.0.0.1:%d;transport=%s",
|
||||
param->port, param->tp_type);
|
||||
pj_ansi_sprintf(FROM_URI, "sip:alice@127.0.0.1:%d;transport=%s",
|
||||
pj_ansi_sprintf(FROM_URI, "sip:alice@127.0.0.1:%d;transport=%s",
|
||||
param->port, param->tp_type);
|
||||
|
||||
/* Check if loop transport is configured. */
|
||||
status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
|
||||
status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
|
||||
&addr, sizeof(addr), NULL, &loop);
|
||||
if (status != PJ_SUCCESS) {
|
||||
PJ_LOG(3,(THIS_FILE, " Error: loop transport is not configured!"));
|
||||
|
@ -1561,8 +1563,8 @@ int tsx_uas_test(struct tsx_test_param *param)
|
|||
return -4;
|
||||
}
|
||||
|
||||
/* TEST1_BRANCH_ID: Basic 2xx final response.
|
||||
* TEST2_BRANCH_ID: Basic non-2xx final response.
|
||||
/* TEST1_BRANCH_ID: Basic 2xx final response.
|
||||
* TEST2_BRANCH_ID: Basic non-2xx final response.
|
||||
*/
|
||||
status = tsx_basic_final_response_test();
|
||||
if (status != 0)
|
||||
|
@ -1577,7 +1579,7 @@ int tsx_uas_test(struct tsx_test_param *param)
|
|||
/* TEST4_BRANCH_ID: absorbs retransmissions in TRYING state
|
||||
*/
|
||||
status = tsx_retransmit_last_response_test(TEST4_TITLE,
|
||||
TEST4_BRANCH_ID,
|
||||
TEST4_BRANCH_ID,
|
||||
TEST4_REQUEST_COUNT,
|
||||
TEST4_STATUS_CODE);
|
||||
if (status != 0)
|
||||
|
@ -1586,7 +1588,7 @@ int tsx_uas_test(struct tsx_test_param *param)
|
|||
/* TEST5_BRANCH_ID: retransmit last response in PROCEEDING state
|
||||
*/
|
||||
status = tsx_retransmit_last_response_test(TEST5_TITLE,
|
||||
TEST5_BRANCH_ID,
|
||||
TEST5_BRANCH_ID,
|
||||
TEST5_REQUEST_COUNT,
|
||||
TEST5_STATUS_CODE);
|
||||
if (status != 0)
|
||||
|
@ -1599,7 +1601,7 @@ int tsx_uas_test(struct tsx_test_param *param)
|
|||
*/
|
||||
if ((tp_flag & PJSIP_TRANSPORT_RELIABLE) == 0) {
|
||||
status = tsx_retransmit_last_response_test(TEST6_TITLE,
|
||||
TEST6_BRANCH_ID,
|
||||
TEST6_BRANCH_ID,
|
||||
TEST6_REQUEST_COUNT,
|
||||
TEST6_STATUS_CODE);
|
||||
if (status != 0)
|
||||
|
@ -1613,7 +1615,7 @@ int tsx_uas_test(struct tsx_test_param *param)
|
|||
if (status != 0)
|
||||
return status;
|
||||
|
||||
/* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
|
||||
/* TEST9_BRANCH_ID: retransmission of non-2xx INVITE final response must
|
||||
* cease when ACK is received
|
||||
* Only applicable for non-reliable transports.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* $Id$ */
|
||||
/*
|
||||
/*
|
||||
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
|
||||
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
|
||||
*
|
||||
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "test.h"
|
||||
#include <pjsip.h>
|
||||
|
@ -67,7 +67,6 @@ static pjsip_uri *create_uri14( pj_pool_t *pool );
|
|||
static pjsip_uri *create_uri15( pj_pool_t *pool );
|
||||
static pjsip_uri *create_uri16( pj_pool_t *pool );
|
||||
static pjsip_uri *create_uri17( pj_pool_t *pool );
|
||||
static pjsip_uri *create_uri18( pj_pool_t *pool );
|
||||
static pjsip_uri *create_uri25( pj_pool_t *pool );
|
||||
static pjsip_uri *create_uri26( pj_pool_t *pool );
|
||||
static pjsip_uri *create_uri27( pj_pool_t *pool );
|
||||
|
@ -96,7 +95,7 @@ struct uri_test
|
|||
pjsip_uri *(*creator)(pj_pool_t *pool);
|
||||
const char *printed;
|
||||
pj_size_t len;
|
||||
} uri_test_array[] =
|
||||
} uri_test_array[] =
|
||||
{
|
||||
{
|
||||
PJ_SUCCESS,
|
||||
|
@ -183,7 +182,7 @@ struct uri_test
|
|||
},
|
||||
{
|
||||
/* Excercise strange character sets allowed in display, user, password,
|
||||
* host, and port.
|
||||
* host, and port.
|
||||
*/
|
||||
PJ_SUCCESS,
|
||||
"This is -. !% *_+`'~ me <sip:a19A&=+$,;?/%2c:%40a&Zz=+$,@"
|
||||
|
@ -197,7 +196,7 @@ struct uri_test
|
|||
&create_uri15,
|
||||
},
|
||||
{
|
||||
/* Another excercise to the allowed character sets to the username
|
||||
/* Another excercise to the allowed character sets to the username
|
||||
* and password.
|
||||
*/
|
||||
PJ_SUCCESS,
|
||||
|
@ -438,7 +437,7 @@ static pjsip_uri *create_uri4(pj_pool_t *pool)
|
|||
static pjsip_uri *create_uri5(pj_pool_t *pool)
|
||||
{
|
||||
/* "sip:localhost;pickup=hurry;user=phone;message=I%20am%20sorry"
|
||||
"?Subject=Hello%20There&Server=SIP%20Server"
|
||||
"?Subject=Hello%20There&Server=SIP%20Server"
|
||||
*/
|
||||
pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 0);
|
||||
|
||||
|
@ -658,7 +657,7 @@ static pjsip_uri *create_uri29(pj_pool_t *pool)
|
|||
pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
|
||||
|
||||
uri->number = pj_str("(44).1234-*#+Deaf");
|
||||
return (pjsip_uri*)uri;
|
||||
return (pjsip_uri*)uri;
|
||||
}
|
||||
|
||||
/* "tel:+1;isub=/:@&$,-_.!~*'()[]/:&$aA1%21+=" */
|
||||
|
@ -668,7 +667,7 @@ static pjsip_uri *create_uri30(pj_pool_t *pool)
|
|||
|
||||
uri->number = pj_str("+1");
|
||||
uri->isub_param = pj_str("/:@&$,-_.!~*'()[]/:&$aA1!+=");
|
||||
return (pjsip_uri*)uri;
|
||||
return (pjsip_uri*)uri;
|
||||
}
|
||||
|
||||
/* "tel:+1;ext=+123" */
|
||||
|
@ -678,7 +677,7 @@ static pjsip_uri *create_uri31(pj_pool_t *pool)
|
|||
|
||||
uri->number = pj_str("+1");
|
||||
uri->ext_param = pj_str("+123");
|
||||
return (pjsip_uri*)uri;
|
||||
return (pjsip_uri*)uri;
|
||||
}
|
||||
|
||||
/* "tel:911;phone-context=+1-911" */
|
||||
|
@ -688,7 +687,7 @@ static pjsip_uri *create_uri32(pj_pool_t *pool)
|
|||
|
||||
uri->number = pj_str("911");
|
||||
uri->context = pj_str("+1-911");
|
||||
return (pjsip_uri*)uri;
|
||||
return (pjsip_uri*)uri;
|
||||
}
|
||||
|
||||
/* "tel:911;phone-context=emergency.example.com" */
|
||||
|
@ -698,7 +697,7 @@ static pjsip_uri *create_uri33(pj_pool_t *pool)
|
|||
|
||||
uri->number = pj_str("911");
|
||||
uri->context = pj_str("EMERGENCY.EXAMPLE.COM");
|
||||
return (pjsip_uri*)uri;
|
||||
return (pjsip_uri*)uri;
|
||||
}
|
||||
|
||||
/* "tel:911;p1=p1;p2=p2" */
|
||||
|
@ -708,12 +707,12 @@ static pjsip_uri *create_uri34(pj_pool_t *pool)
|
|||
pjsip_param *p;
|
||||
|
||||
uri->number = pj_str("911");
|
||||
|
||||
|
||||
p = PJ_POOL_ALLOC_T(pool, pjsip_param);
|
||||
p->name = p->value = pj_str("p1");
|
||||
pj_list_insert_before(&uri->other_param, p);
|
||||
|
||||
return (pjsip_uri*)uri;
|
||||
return (pjsip_uri*)uri;
|
||||
}
|
||||
|
||||
/* "sip:user@[::1];maddr=[::01]" */
|
||||
|
@ -749,7 +748,7 @@ static pjsip_uri *create_uri37( pj_pool_t *pool )
|
|||
|
||||
url = pjsip_sip_uri_create(pool, 0);
|
||||
url->host = pj_str("localhost");
|
||||
|
||||
|
||||
name->uri = (pjsip_uri*)url;
|
||||
|
||||
return (pjsip_uri*)name;
|
||||
|
@ -767,7 +766,7 @@ static pjsip_uri *create_uri38( pj_pool_t *pool )
|
|||
|
||||
url = pjsip_sip_uri_create(pool, 0);
|
||||
url->host = pj_str("localhost");
|
||||
|
||||
|
||||
name->uri = (pjsip_uri*)url;
|
||||
|
||||
return (pjsip_uri*)name;
|
||||
|
@ -999,8 +998,8 @@ static int uri_benchmark(unsigned *p_parse, unsigned *p_print, unsigned *p_cmp)
|
|||
avg_parse = 1;
|
||||
avg_parse = 1000000 / avg_parse;
|
||||
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" %u.%u MB of urls parsed in %d.%03ds (avg=%d urls/sec)",
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" %u.%u MB of urls parsed in %d.%03ds (avg=%d urls/sec)",
|
||||
(unsigned)(var.parse_len/1000000), (unsigned)kbytes,
|
||||
elapsed.sec, elapsed.msec,
|
||||
(unsigned)avg_parse));
|
||||
|
@ -1018,8 +1017,8 @@ static int uri_benchmark(unsigned *p_parse, unsigned *p_print, unsigned *p_cmp)
|
|||
avg_print = 1;
|
||||
avg_print = 1000000 / avg_print;
|
||||
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" %u.%u MB of urls printed in %d.%03ds (avg=%d urls/sec)",
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" %u.%u MB of urls printed in %d.%03ds (avg=%d urls/sec)",
|
||||
(unsigned)(var.print_len/1000000), (unsigned)kbytes,
|
||||
elapsed.sec, elapsed.msec,
|
||||
(unsigned)avg_print));
|
||||
|
@ -1037,8 +1036,8 @@ static int uri_benchmark(unsigned *p_parse, unsigned *p_print, unsigned *p_cmp)
|
|||
avg_cmp = 1;
|
||||
avg_cmp = 1000000 / avg_cmp;
|
||||
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" %u.%u MB of urls compared in %d.%03ds (avg=%d urls/sec)",
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
" %u.%u MB of urls compared in %d.%03ds (avg=%d urls/sec)",
|
||||
(unsigned)(var.cmp_len/1000000), (unsigned)kbytes,
|
||||
elapsed.sec, elapsed.msec,
|
||||
(unsigned)avg_cmp));
|
||||
|
@ -1084,8 +1083,8 @@ int uri_test(void)
|
|||
avg_len /= PJ_ARRAY_SIZE(uri_test_array);
|
||||
|
||||
|
||||
/*
|
||||
* Print maximum parse/sec
|
||||
/*
|
||||
* Print maximum parse/sec
|
||||
*/
|
||||
for (i=0, max=0; i<COUNT; ++i)
|
||||
if (run[i].parse > max) max = run[i].parse;
|
||||
|
|
|
@ -224,7 +224,6 @@
|
|||
){
|
||||
float lsf[LPC_FILTERORDER * LPC_N_MAX];
|
||||
float lsfdeq[LPC_FILTERORDER * LPC_N_MAX];
|
||||
int change=0;
|
||||
|
||||
SimpleAnalysis(lsf, data, iLBCenc_inst);
|
||||
SimplelsfQ(lsfdeq, lsf_index, lsf, iLBCenc_inst->lpc_n);
|
||||
|
@ -233,7 +232,7 @@
|
|||
|
||||
|
||||
|
||||
change=LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n);
|
||||
LSF_check(lsfdeq, LPC_FILTERORDER, iLBCenc_inst->lpc_n);
|
||||
SimpleInterpolateLSF(syntdenum, weightdenum,
|
||||
lsf, lsfdeq, iLBCenc_inst->lsfold,
|
||||
iLBCenc_inst->lsfdeqold, LPC_FILTERORDER, iLBCenc_inst);
|
||||
|
|
|
@ -277,7 +277,7 @@
|
|||
table */
|
||||
){
|
||||
int k,n,m, Nit=2, change=0,pos;
|
||||
float tmp;
|
||||
//float tmp;
|
||||
static float eps=(float)0.039; /* 50 Hz */
|
||||
static float eps2=(float)0.0195;
|
||||
static float maxlsf=(float)3.14; /* 4000 Hz */
|
||||
|
@ -293,7 +293,7 @@
|
|||
if ((lsf[pos+1]-lsf[pos])<eps) {
|
||||
|
||||
if (lsf[pos+1]<lsf[pos]) {
|
||||
tmp=lsf[pos+1];
|
||||
//tmp=lsf[pos+1];
|
||||
lsf[pos+1]= lsf[pos]+eps2;
|
||||
lsf[pos]= lsf[pos+1]-eps2;
|
||||
} else {
|
||||
|
|
|
@ -339,7 +339,6 @@
|
|||
int lag, ilag;
|
||||
float cc, maxcc;
|
||||
int idxVec[STATE_LEN];
|
||||
int check;
|
||||
int gain_index[NASUB_MAX*CB_NSTAGES],
|
||||
extra_gain_index[CB_NSTAGES];
|
||||
int cb_index[CB_NSTAGES*NASUB_MAX], extra_cb_index[CB_NSTAGES];
|
||||
|
@ -500,7 +499,7 @@
|
|||
/* decode the lsf */
|
||||
|
||||
SimplelsfDEQ(lsfdeq, lsf_i, iLBCdec_inst->lpc_n);
|
||||
check=LSF_check(lsfdeq, LPC_FILTERORDER,
|
||||
LSF_check(lsfdeq, LPC_FILTERORDER,
|
||||
iLBCdec_inst->lpc_n);
|
||||
DecoderInterpolateLSF(syntdenum, weightdenum,
|
||||
lsfdeq, LPC_FILTERORDER, iLBCdec_inst);
|
||||
|
|
|
@ -6,28 +6,28 @@
|
|||
* SOFTWARE FOR SAMPLING-RATE CONVERSION AND FIR DIGITAL FILTER DESIGN
|
||||
*
|
||||
* Snippet from the resample.1 man page:
|
||||
*
|
||||
*
|
||||
* HISTORY
|
||||
*
|
||||
* The first version of this software was written by Julius O. Smith III
|
||||
* <jos@ccrma.stanford.edu> at CCRMA <http://www-ccrma.stanford.edu> in
|
||||
* 1981. It was called SRCONV and was written in SAIL for PDP-10
|
||||
* compatible machines. The algorithm was first published in
|
||||
*
|
||||
*
|
||||
* Smith, Julius O. and Phil Gossett. ``A Flexible Sampling-Rate
|
||||
* Conversion Method,'' Proceedings (2): 19.4.1-19.4.4, IEEE Conference
|
||||
* on Acoustics, Speech, and Signal Processing, San Diego, March 1984.
|
||||
*
|
||||
*
|
||||
* An expanded tutorial based on this paper is available at the Digital
|
||||
* Audio Resampling Home Page given above.
|
||||
*
|
||||
*
|
||||
* Circa 1988, the SRCONV program was translated from SAIL to C by
|
||||
* Christopher Lee Fraley working with Roger Dannenberg at CMU.
|
||||
*
|
||||
*
|
||||
* Since then, the C version has been maintained by jos.
|
||||
*
|
||||
*
|
||||
* Sndlib support was added 6/99 by John Gibson <jgg9c@virginia.edu>.
|
||||
*
|
||||
*
|
||||
* The resample program is free software distributed in accordance
|
||||
* with the Lesser GNU Public License (LGPL). There is NO warranty; not
|
||||
* even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
@ -77,7 +77,7 @@
|
|||
|
||||
#undef INLINE
|
||||
#define INLINE
|
||||
#define HAVE_FILTER 0
|
||||
#define HAVE_FILTER 0
|
||||
|
||||
#ifndef NULL
|
||||
# define NULL 0
|
||||
|
@ -94,14 +94,14 @@ static INLINE RES_HWORD WordToHword(RES_WORD v, int scl)
|
|||
v = MAX_HWORD;
|
||||
} else if (v < MIN_HWORD) {
|
||||
v = MIN_HWORD;
|
||||
}
|
||||
}
|
||||
out = (RES_HWORD) v;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Sampling rate conversion using linear interpolation for maximum speed.
|
||||
*/
|
||||
static int
|
||||
static int
|
||||
SrcLinear(const RES_HWORD X[], RES_HWORD Y[], double pFactor, RES_UHWORD nx)
|
||||
{
|
||||
RES_HWORD iconst;
|
||||
|
@ -109,19 +109,19 @@ static int
|
|||
const RES_HWORD *xp;
|
||||
RES_HWORD *Ystart, *Yend;
|
||||
RES_WORD v,x1,x2;
|
||||
|
||||
double dt; /* Step through input signal */
|
||||
|
||||
double dt; /* Step through input signal */
|
||||
RES_UWORD dtb; /* Fixed-point version of Dt */
|
||||
RES_UWORD endTime; /* When time reaches EndTime, return to user */
|
||||
|
||||
//RES_UWORD endTime; /* When time reaches EndTime, return to user */
|
||||
|
||||
dt = 1.0/pFactor; /* Output sampling period */
|
||||
dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */
|
||||
|
||||
|
||||
Ystart = Y;
|
||||
Yend = Ystart + (unsigned)(nx * pFactor + 0.5);
|
||||
endTime = time + (1<<Np)*(RES_WORD)nx;
|
||||
|
||||
// Integer round down in dtb calculation may cause (endTime % dtb > 0),
|
||||
//endTime = time + (1<<Np)*(RES_WORD)nx;
|
||||
|
||||
// Integer round down in dtb calculation may cause (endTime % dtb > 0),
|
||||
// so it may cause resample write pass the output buffer (Y >= Yend).
|
||||
// while (time < endTime)
|
||||
while (Y < Yend)
|
||||
|
@ -139,7 +139,7 @@ static int
|
|||
return (Y - Ystart); /* Return number of output samples */
|
||||
}
|
||||
|
||||
static RES_WORD FilterUp(const RES_HWORD Imp[], const RES_HWORD ImpD[],
|
||||
static RES_WORD FilterUp(const RES_HWORD Imp[], const RES_HWORD ImpD[],
|
||||
RES_UHWORD Nwing, RES_BOOL Interp,
|
||||
const RES_HWORD *Xp, RES_HWORD Ph, RES_HWORD Inc)
|
||||
{
|
||||
|
@ -148,7 +148,7 @@ static RES_WORD FilterUp(const RES_HWORD Imp[], const RES_HWORD ImpD[],
|
|||
const RES_HWORD *End;
|
||||
RES_HWORD a = 0;
|
||||
RES_WORD v, t;
|
||||
|
||||
|
||||
v=0;
|
||||
Hp = &Imp[Ph>>Na];
|
||||
End = &Imp[Nwing];
|
||||
|
@ -178,8 +178,8 @@ static RES_WORD FilterUp(const RES_HWORD Imp[], const RES_HWORD ImpD[],
|
|||
Hp += Npc; /* Filter coeff step */
|
||||
|
||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
while (Hp < End) {
|
||||
t = *Hp; /* Get filter coeff */
|
||||
t *= *Xp; /* Mult coeff by input sample */
|
||||
|
@ -202,7 +202,7 @@ static RES_WORD FilterUD(const RES_HWORD Imp[], const RES_HWORD ImpD[],
|
|||
const RES_HWORD *Hp, *Hdp, *End;
|
||||
RES_WORD v, t;
|
||||
RES_UWORD Ho;
|
||||
|
||||
|
||||
v=0;
|
||||
Ho = (Ph*(RES_UWORD)dhb)>>Np;
|
||||
End = &Imp[Nwing];
|
||||
|
@ -227,7 +227,7 @@ static RES_WORD FilterUD(const RES_HWORD Imp[], const RES_HWORD ImpD[],
|
|||
Ho += dhb; /* IR step */
|
||||
Xp += Inc; /* Input signal step. NO CHECK ON BOUNDS */
|
||||
}
|
||||
else
|
||||
else
|
||||
while ((Hp = &Imp[Ho>>Na]) < End) {
|
||||
t = *Hp; /* Get IR sample */
|
||||
t *= *Xp; /* Mult coeff by input sample */
|
||||
|
@ -244,27 +244,27 @@ static RES_WORD FilterUD(const RES_HWORD Imp[], const RES_HWORD ImpD[],
|
|||
/* Sampling rate up-conversion only subroutine;
|
||||
* Slightly faster than down-conversion;
|
||||
*/
|
||||
static int SrcUp(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
||||
static int SrcUp(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
||||
RES_UHWORD nx, RES_UHWORD pNwing, RES_UHWORD pLpScl,
|
||||
const RES_HWORD pImp[], const RES_HWORD pImpD[], RES_BOOL Interp)
|
||||
{
|
||||
const RES_HWORD *xp;
|
||||
RES_HWORD *Ystart, *Yend;
|
||||
RES_WORD v;
|
||||
|
||||
double dt; /* Step through input signal */
|
||||
|
||||
double dt; /* Step through input signal */
|
||||
RES_UWORD dtb; /* Fixed-point version of Dt */
|
||||
RES_UWORD time = 0;
|
||||
RES_UWORD endTime; /* When time reaches EndTime, return to user */
|
||||
|
||||
//RES_UWORD endTime; /* When time reaches EndTime, return to user */
|
||||
|
||||
dt = 1.0/pFactor; /* Output sampling period */
|
||||
dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */
|
||||
|
||||
|
||||
Ystart = Y;
|
||||
Yend = Ystart + (unsigned)(nx * pFactor + 0.5);
|
||||
endTime = time + (1<<Np)*(RES_WORD)nx;
|
||||
//endTime = time + (1<<Np)*(RES_WORD)nx;
|
||||
|
||||
// Integer round down in dtb calculation may cause (endTime % dtb > 0),
|
||||
// Integer round down in dtb calculation may cause (endTime % dtb > 0),
|
||||
// so it may cause resample write pass the output buffer (Y >= Yend).
|
||||
// while (time < endTime)
|
||||
while (Y < Yend)
|
||||
|
@ -288,31 +288,31 @@ static int SrcUp(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
|||
|
||||
/* Sampling rate conversion subroutine */
|
||||
|
||||
static int SrcUD(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
||||
static int SrcUD(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
||||
RES_UHWORD nx, RES_UHWORD pNwing, RES_UHWORD pLpScl,
|
||||
const RES_HWORD pImp[], const RES_HWORD pImpD[], RES_BOOL Interp)
|
||||
{
|
||||
const RES_HWORD *xp;
|
||||
RES_HWORD *Ystart, *Yend;
|
||||
RES_WORD v;
|
||||
|
||||
|
||||
double dh; /* Step through filter impulse response */
|
||||
double dt; /* Step through input signal */
|
||||
RES_UWORD time = 0;
|
||||
RES_UWORD endTime; /* When time reaches EndTime, return to user */
|
||||
//RES_UWORD endTime; /* When time reaches EndTime, return to user */
|
||||
RES_UWORD dhb, dtb; /* Fixed-point versions of Dh,Dt */
|
||||
|
||||
|
||||
dt = 1.0/pFactor; /* Output sampling period */
|
||||
dtb = dt*(1<<Np) + 0.5; /* Fixed-point representation */
|
||||
|
||||
|
||||
dh = MIN(Npc, pFactor*Npc); /* Filter sampling period */
|
||||
dhb = dh*(1<<Na) + 0.5; /* Fixed-point representation */
|
||||
|
||||
|
||||
Ystart = Y;
|
||||
Yend = Ystart + (unsigned)(nx * pFactor + 0.5);
|
||||
endTime = time + (1<<Np)*(RES_WORD)nx;
|
||||
//endTime = time + (1<<Np)*(RES_WORD)nx;
|
||||
|
||||
// Integer round down in dtb calculation may cause (endTime % dtb > 0),
|
||||
// Integer round down in dtb calculation may cause (endTime % dtb > 0),
|
||||
// so it may cause resample write pass the output buffer (Y >= Yend).
|
||||
// while (time < endTime)
|
||||
while (Y < Yend)
|
||||
|
@ -331,13 +331,13 @@ static int SrcUD(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
|||
}
|
||||
|
||||
|
||||
DECL(int) res_SrcLinear(const RES_HWORD X[], RES_HWORD Y[],
|
||||
DECL(int) res_SrcLinear(const RES_HWORD X[], RES_HWORD Y[],
|
||||
double pFactor, RES_UHWORD nx)
|
||||
{
|
||||
return SrcLinear(X, Y, pFactor, nx);
|
||||
}
|
||||
|
||||
DECL(int) res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
||||
DECL(int) res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
||||
RES_UHWORD nx, RES_BOOL LargeF, RES_BOOL Interp)
|
||||
{
|
||||
if (pFactor >= 1) {
|
||||
|
@ -354,11 +354,11 @@ DECL(int) res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
|||
} else {
|
||||
|
||||
if (LargeF)
|
||||
return SrcUD(X, Y, pFactor, nx,
|
||||
return SrcUD(X, Y, pFactor, nx,
|
||||
LARGE_FILTER_NWING, LARGE_FILTER_SCALE * pFactor + 0.5,
|
||||
LARGE_FILTER_IMP, LARGE_FILTER_IMPD, Interp);
|
||||
else
|
||||
return SrcUD(X, Y, pFactor, nx,
|
||||
return SrcUD(X, Y, pFactor, nx,
|
||||
SMALL_FILTER_NWING, SMALL_FILTER_SCALE * pFactor + 0.5,
|
||||
SMALL_FILTER_IMP, SMALL_FILTER_IMPD, Interp);
|
||||
|
||||
|
@ -368,10 +368,10 @@ DECL(int) res_Resample(const RES_HWORD X[], RES_HWORD Y[], double pFactor,
|
|||
DECL(int) res_GetXOFF(double pFactor, RES_BOOL LargeF)
|
||||
{
|
||||
if (LargeF)
|
||||
return (LARGE_FILTER_NMULT + 1) / 2.0 *
|
||||
return (LARGE_FILTER_NMULT + 1) / 2.0 *
|
||||
MAX(1.0, 1.0/pFactor);
|
||||
else
|
||||
return (SMALL_FILTER_NMULT + 1) / 2.0 *
|
||||
return (SMALL_FILTER_NMULT + 1) / 2.0 *
|
||||
MAX(1.0, 1.0/pFactor);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue