@ -177,12 +177,36 @@ static int contact_link_static(void *obj, void *arg, int flags)
return 0 ;
}
/*! \brief Internal callback function which removes any contact which is unreachable */
static int contact_remove_unreachable ( void * obj , void * arg , int flags )
{
struct ast_sip_contact * contact = obj ;
struct ast_sip_contact_status * status ;
int unreachable ;
status = ast_res_pjsip_find_or_create_contact_status ( contact ) ;
if ( ! status ) {
return 0 ;
}
unreachable = ( status - > status = = UNAVAILABLE ) ;
ao2_ref ( status , - 1 ) ;
return unreachable ? CMP_MATCH : 0 ;
}
struct ast_sip_contact * ast_sip_location_retrieve_first_aor_contact ( const struct ast_sip_aor * aor )
{
return ast_sip_location_retrieve_first_aor_contact_filtered ( aor , AST_SIP_CONTACT_FILTER_DEFAULT ) ;
}
struct ast_sip_contact * ast_sip_location_retrieve_first_aor_contact_filtered ( const struct ast_sip_aor * aor ,
unsigned int flags )
{
struct ao2_container * contacts ;
struct ast_sip_contact * contact = NULL ;
contacts = ast_sip_location_retrieve_aor_contacts ( aor ) ;
contacts = ast_sip_location_retrieve_aor_contacts _filtered ( aor , flags ) ;
if ( contacts & & ao2_container_count ( contacts ) ) {
/* Get the first AOR contact in the container. */
contact = ao2_callback ( contacts , 0 , NULL , NULL ) ;
@ -192,6 +216,12 @@ struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct
}
struct ao2_container * ast_sip_location_retrieve_aor_contacts_nolock ( const struct ast_sip_aor * aor )
{
return ast_sip_location_retrieve_aor_contacts_nolock_filtered ( aor , AST_SIP_CONTACT_FILTER_DEFAULT ) ;
}
struct ao2_container * ast_sip_location_retrieve_aor_contacts_nolock_filtered ( const struct ast_sip_aor * aor ,
unsigned int flags )
{
/* Give enough space for ^ at the beginning and ;@ at the end, since that is our object naming scheme */
char regex [ strlen ( ast_sorcery_object_get_id ( aor ) ) + 4 ] ;
@ -211,23 +241,40 @@ struct ao2_container *ast_sip_location_retrieve_aor_contacts_nolock(const struct
ao2_callback ( aor - > permanent_contacts , OBJ_NODATA , contact_link_static , contacts ) ;
}
if ( flags & AST_SIP_CONTACT_FILTER_REACHABLE ) {
ao2_callback ( contacts , OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK , contact_remove_unreachable , NULL ) ;
}
return contacts ;
}
struct ao2_container * ast_sip_location_retrieve_aor_contacts ( const struct ast_sip_aor * aor )
{
return ast_sip_location_retrieve_aor_contacts_filtered ( aor , AST_SIP_CONTACT_FILTER_DEFAULT ) ;
}
struct ao2_container * ast_sip_location_retrieve_aor_contacts_filtered ( const struct ast_sip_aor * aor ,
unsigned int flags )
{
struct ao2_container * contacts ;
/* ao2_lock / ao2_unlock do not actually write aor since it has an ao2 lockobj. */
ao2_lock ( ( void * ) aor ) ;
contacts = ast_sip_location_retrieve_aor_contacts_nolock ( aor ) ;
contacts = ast_sip_location_retrieve_aor_contacts_nolock _filtered ( aor , flags ) ;
ao2_unlock ( ( void * ) aor ) ;
return contacts ;
}
void ast_sip_location_retrieve_contact_and_aor_from_list ( const char * aor_list , struct ast_sip_aor * * aor ,
struct ast_sip_contact * * contact )
{
ast_sip_location_retrieve_contact_and_aor_from_list_filtered ( aor_list , AST_SIP_CONTACT_FILTER_DEFAULT , aor , contact ) ;
}
void ast_sip_location_retrieve_contact_and_aor_from_list_filtered ( const char * aor_list , unsigned int flags ,
struct ast_sip_aor * * aor , struct ast_sip_contact * * contact )
{
char * aor_name ;
char * rest ;
@ -247,7 +294,7 @@ void ast_sip_location_retrieve_contact_and_aor_from_list(const char *aor_list, s
if ( ! ( * aor ) ) {
continue ;
}
* contact = ast_sip_location_retrieve_first_aor_contact ( * aor ) ;
* contact = ast_sip_location_retrieve_first_aor_contact _filtered ( * aor , flags ) ;
/* If a valid contact is available use its URI for dialing */
if ( * contact ) {
break ;