@ -106,8 +106,9 @@ static const char *skip_sip(const char *fromto)
*
* Expects the given ' to ' to be in one of the following formats :
* sip [ s ] : endpoint [ / aor ]
* sip [ s ] : endpoint [ / uri ]
* sip [ s ] : uri < - - will use default outbound endpoint
* sip [ s ] : endpoint [ / uri ] - Where uri is : sip [ s ] : user @ domain
* sip [ s ] : endpoint [ @ domain ]
* sip [ s ] : unknown_user @ domain < - - will use default outbound endpoint
*
* If an optional aor is given it will try to find an associated uri
* to return . If an optional uri is given then that will be returned ,
@ -116,50 +117,60 @@ static const char *skip_sip(const char *fromto)
* \ param to ' From ' or ' To ' field with possible endpoint
* \ param uri Optional uri to return
*/
static struct ast_sip_endpoint * get_outbound_endpoint (
const char * to , char * * uri )
static struct ast_sip_endpoint * get_outbound_endpoint ( const char * to , char * * uri )
{
char * name , * aor_uri ;
struct ast_sip_endpoint * endpoint ;
RAII_VAR ( struct ast_sip_aor * , aor , NULL , ao2_cleanup ) ;
RAII_VAR ( struct ast_sip_contact * , contact , NULL , ao2_cleanup ) ;
char * name ;
char * aor_uri ;
struct ast_sip_endpoint * endpoint ;
name = ast_strdupa ( skip_sip ( to ) ) ;
/* attempt to extract the endpoint name */
if ( ( aor_uri = strchr ( name , ' / ' ) ) ) {
/* format was 'endpoint/ ' */
/* format was 'endpoint/ (aor_name | uri) ' */
* aor_uri + + = ' \0 ' ;
} else if ( ( aor_uri = strchr ( name , ' @ ' ) ) ) {
/* format was 'endpoint@ ' - don't use the rest */
/* format was 'endpoint@ domain' - discard the domain */
* aor_uri = ' \0 ' ;
}
/* at this point, if name is not empty then it
might be an endpoint , so try to retrieve it */
if ( ast_strlen_zero ( name ) | | ! ( endpoint = ast_sorcery_retrieve_by_id (
ast_sip_get_sorcery ( ) , " endpoint " , name ) ) ) {
if ( ast_strlen_zero ( name )
| | ! ( endpoint = ast_sorcery_retrieve_by_id ( ast_sip_get_sorcery ( ) , " endpoint " ,
name ) ) ) {
/* an endpoint was not found, so assume sending directly
to a uri and use the default outbound endpoint */
* uri = ast_strdup ( to ) ;
return ast_sip_default_outbound_endpoint ( ) ;
}
* uri = aor_uri ;
if ( * uri ) {
char * end = strchr ( * uri , ' > ' ) ;
if ( ast_strlen_zero ( aor_uri ) ) {
* uri = NULL ;
} else {
struct ast_sip_aor * aor ;
struct ast_sip_contact * contact = NULL ;
char * end ;
/* Trim off any stray angle bracket that shouldn't be here */
end = strchr ( aor_uri , ' > ' ) ;
if ( end ) {
* end + + = ' \0 ' ;
* end = ' \0 ' ;
}
/* if what's in 'uri' is a retrievable aor use the uri on it
instead , otherwise assume what ' s there is already a uri */
if ( ( aor = ast_sip_location_retrieve_aor ( * uri ) ) & &
( contact = ast_sip_location_retrieve_first_aor_contact ( aor ) ) ) {
* uri = ( char * ) contact - > uri ;
/*
* if what ' s in ' uri ' is a retrievable aor use the uri on it
* instead , otherwise assume what ' s there is already a uri
*/
aor = ast_sip_location_retrieve_aor ( aor_uri ) ;
if ( aor & & ( contact = ast_sip_location_retrieve_first_aor_contact ( aor ) ) ) {
aor_uri = ( char * ) contact - > uri ;
}
/* need to copy because underlying uri goes away */
* uri = ast_strdup ( * uri ) ;
* uri = ast_strdup ( aor_uri ) ;
ao2_cleanup ( contact ) ;
ao2_cleanup ( aor ) ;
}
return endpoint ;
@ -176,16 +187,16 @@ static struct ast_sip_endpoint* get_outbound_endpoint(
*/
static void update_to ( pjsip_tx_data * tdata , char * to )
{
pjsip_name_addr * name_addr = ( pjsip_name_addr * )
PJSIP_MSG_TO_HDR ( tdata - > msg ) - > uri ;
pjsip_uri * parsed ;
pjsip_name_addr * parsed_name_addr ;
if ( ( parsed = pjsip_parse_uri ( tdata - > pool , to , strlen ( to ) ,
PJSIP_PARSE_URI_AS_NAMEADDR ) ) ) {
pjsip_name_addr * parsed_name_addr = ( pjsip_name_addr * ) parsed ;
parsed_name_addr = ( pjsip_name_addr * ) pjsip_parse_uri ( tdata - > pool , to , strlen ( to ) ,
PJSIP_PARSE_URI_AS_NAMEADDR ) ;
if ( parsed_name_addr ) {
if ( pj_strlen ( & parsed_name_addr - > display ) ) {
pj_strdup ( tdata - > pool , & name_addr - > display ,
& parsed_name_addr - > display ) ;
pjsip_name_addr * name_addr =
( pjsip_name_addr * ) PJSIP_MSG_TO_HDR ( tdata - > msg ) - > uri ;
pj_strdup ( tdata - > pool , & name_addr - > display , & parsed_name_addr - > display ) ;
}
}
}
@ -204,22 +215,24 @@ static void update_to(pjsip_tx_data *tdata, char *to)
*/
static void update_from ( pjsip_tx_data * tdata , char * from )
{
pjsip_name_addr * name_addr = ( pjsip_name_addr * )
PJSIP_MSG_FROM_HDR ( tdata - > msg ) - > uri ;
pjsip_sip_uri * uri = pjsip_uri_get_uri ( name_addr ) ;
pjsip_uri * parsed ;
pjsip_name_addr * name_addr ;
pjsip_sip_uri * uri ;
pjsip_name_addr * parsed_name_addr ;
if ( ast_strlen_zero ( from ) ) {
return ;
}
if ( ( parsed = pjsip_parse_uri ( tdata - > pool , from , strlen ( from ) ,
PJSIP_PARSE_URI_AS_NAMEADDR ) ) ) {
pjsip_name_addr * parsed_name_addr = ( pjsip_name_addr * ) parsed ;
name_addr = ( pjsip_name_addr * ) PJSIP_MSG_FROM_HDR ( tdata - > msg ) - > uri ;
uri = pjsip_uri_get_uri ( name_addr ) ;
parsed_name_addr = ( pjsip_name_addr * ) pjsip_parse_uri ( tdata - > pool , from ,
strlen ( from ) , PJSIP_PARSE_URI_AS_NAMEADDR ) ;
if ( parsed_name_addr ) {
pjsip_sip_uri * parsed_uri = pjsip_uri_get_uri ( parsed_name_addr - > uri ) ;
if ( pj_strlen ( & parsed_name_addr - > display ) ) {
pj_strdup ( tdata - > pool , & name_addr - > display ,
& parsed_name_addr - > display ) ;
pj_strdup ( tdata - > pool , & name_addr - > display , & parsed_name_addr - > display ) ;
}
pj_strdup ( tdata - > pool , & uri - > user , & parsed_uri - > user ) ;
@ -228,11 +241,17 @@ static void update_from(pjsip_tx_data *tdata, char *from)
} else {
/* assume it is 'user[@domain]' format */
char * domain = strchr ( from , ' @ ' ) ;
if ( domain ) {
* domain + + = ' \0 ' ;
pj_strdup2 ( tdata - > pool , & uri - > host , domain ) ;
pj_str_t pj_from ;
pj_strset3 ( & pj_from , from , domain ) ;
pj_strdup ( tdata - > pool , & uri - > user , & pj_from ) ;
pj_strdup2 ( tdata - > pool , & uri - > host , domain + 1 ) ;
} else {
pj_strdup2 ( tdata - > pool , & uri - > user , from ) ;
}
pj_strdup2 ( tdata - > pool , & uri - > user , from ) ;
}
}
@ -526,7 +545,7 @@ static void msg_data_destroy(void *obj)
ast_msg_destroy ( mdata - > msg ) ;
}
static struct msg_data * msg_data_create ( const struct ast_msg * msg , const char * to , const char * from )
static struct msg_data * msg_data_create ( const struct ast_msg * msg , const char * to , const char * from )
{
char * tag ;
struct msg_data * mdata = ao2_alloc ( sizeof ( * mdata ) , msg_data_destroy ) ;
@ -536,17 +555,17 @@ static struct msg_data* msg_data_create(const struct ast_msg *msg, const char *t
}
/* typecast to suppress const warning */
mdata - > msg = ast_msg_ref ( ( struct ast_msg * ) msg ) ;
mdata - > msg = ast_msg_ref ( ( struct ast_msg * ) msg ) ;
/* starts with 'pjsip:' the 'pj' needs to be removed and maybe even
the entire string . */
/* To starts with 'pjsip:' which needs to be removed. */
if ( ! ( to = strchr ( to , ' : ' ) ) ) {
ao2_ref ( mdata , - 1 ) ;
return NULL ;
}
+ + to ; /* Now skip the ':' */
/* Make sure we start with sip: */
mdata - > to = ast_begins_with ( to , " sip: " ) ? ast_strdup ( + + to ) : ast_strdup ( to - 3 ) ;
mdata - > to = ast_begins_with ( to , " sip: " ) ? ast_strdup ( to ) : ast_strdup ( to - 4 ) ;
mdata - > from = ast_strdup ( from ) ;
if ( ! mdata - > to | | ! mdata - > from ) {
ao2_ref ( mdata , - 1 ) ;
@ -572,12 +591,13 @@ static int msg_send(void *data)
pjsip_tx_data * tdata ;
RAII_VAR ( char * , uri , NULL , ast_free ) ;
RAII_VAR ( struct ast_sip_endpoint * , endpoint , get_outbound_endpoint (
mdata - > to , & uri ) , ao2_cleanup ) ;
RAII_VAR ( struct ast_sip_endpoint * , endpoint , NULL , ao2_cleanup ) ;
endpoint = get_outbound_endpoint ( mdata - > to , & uri ) ;
if ( ! endpoint ) {
ast_log ( LOG_ERROR , " PJSIP MESSAGE - Could not find endpoint '%s' and "
" no default outbound endpoint configured \n " , mdata - > to ) ;
ast_log ( LOG_ERROR ,
" PJSIP MESSAGE - Could not find endpoint '%s' and no default outbound endpoint configured \n " ,
mdata - > to ) ;
return - 1 ;
}