diff options
author | Joshua Colp <jcolp@digium.com> | 2017-06-07 08:33:53 -0500 |
---|---|---|
committer | Gerrit Code Review <gerrit2@gerrit.digium.api> | 2017-06-07 08:33:53 -0500 |
commit | 9f054955f2f7830d4a7d20326d9fea7dff277456 (patch) | |
tree | fbc5bffc5710d84a175776aae75efb3abcd09ae3 /res | |
parent | 29f87a5530f1326d3244232ddb6f48aa801bf9bd (diff) | |
parent | 861984eac0d9d3582db6922a89e2d75796ae108f (diff) |
Merge "res_pjsip: Add support for returning only reachable contacts and use it."
Diffstat (limited to 'res')
-rw-r--r-- | res/res_pjsip.c | 2 | ||||
-rw-r--r-- | res/res_pjsip/location.c | 53 | ||||
-rw-r--r-- | res/res_pjsip_session.c | 3 |
3 files changed, 53 insertions, 5 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 102bc3933..d994f2824 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -3040,7 +3040,7 @@ pjsip_dialog *ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, if (res != PJ_SUCCESS) { if (res == PJSIP_EINVALIDURI) { ast_log(LOG_ERROR, - "Endpoint '%s': Could not create dialog to invalid URI '%s'. Is endpoint registered?\n", + "Endpoint '%s': Could not create dialog to invalid URI '%s'. Is endpoint registered and reachable?\n", ast_sorcery_object_get_id(endpoint), uri); } return NULL; diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 5abfcabad..6213046e3 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -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); @@ -193,6 +217,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]; struct ao2_container *contacts; @@ -211,24 +241,41 @@ 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; diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 9e3abf253..8447be36e 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -1719,7 +1719,8 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint if (location || !contact) { location = S_OR(location, endpoint->aors); - ast_sip_location_retrieve_contact_and_aor_from_list(location, &found_aor, &found_contact); + ast_sip_location_retrieve_contact_and_aor_from_list_filtered(location, AST_SIP_CONTACT_FILTER_REACHABLE, + &found_aor, &found_contact); if (!found_contact || ast_strlen_zero(found_contact->uri)) { uri = location; } else { |