diff --git a/funcs/func_pjsip_contact.c b/funcs/func_pjsip_contact.c index fc65ae9222e3bec2592998e421bc2086e383b02f..e9737049d84966b6452d0d7b893a0106f3e0a47b 100644 --- a/funcs/func_pjsip_contact.c +++ b/funcs/func_pjsip_contact.c @@ -147,15 +147,9 @@ static int pjsip_contact_function_read(struct ast_channel *chan, contact_status = ast_sorcery_retrieve_by_id(pjsip_sorcery, CONTACT_STATUS, ast_sorcery_object_get_id(contact_obj)); if (!strcmp(args.field_name, "status")) { - if (!contact_status) { - ast_str_set(buf, len, "%s", "Unknown"); - } else if (contact_status->status == UNAVAILABLE) { - ast_str_set(buf, len, "%s", "Unreachable"); - } else if (contact_status->status == AVAILABLE) { - ast_str_set(buf, len, "%s", "Reachable"); - } + ast_str_set(buf, len, "%s", ast_sip_get_contact_status_label(contact_status->status)); } else if (!strcmp(args.field_name, "rtt")) { - if (!contact_status) { + if (contact_status->status == UNKNOWN) { ast_str_set(buf, len, "%s", "N/A"); } else { ast_str_set(buf, len, "%" PRId64, contact_status->rtt); diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 99b65ab088b2810e12ceeae84db728f9467d3112..12fc400d2dbe33b192f49a455ea2e47b8fb44649 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -177,7 +177,8 @@ struct ast_sip_contact { */ enum ast_sip_contact_status_type { UNAVAILABLE, - AVAILABLE + AVAILABLE, + UNKNOWN }; /*! @@ -2002,5 +2003,13 @@ unsigned int ast_sip_get_keep_alive_interval(void); */ unsigned int ast_sip_get_max_initial_qualify_time(void); +/*! + * \brief translate ast_sip_contact_status_type to character string. + * + * \retval the character string equivalent. + */ + +const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status); +const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status); #endif /* _RES_PJSIP_H */ diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index f784cb40fbeaa5581e492f3f3eb53fd30395c5ef..21650417fe0ab3dd4b527e5b6409b4fd94cc9472 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -747,8 +747,8 @@ static int cli_contact_print_body(void *obj, void *arg, int flags) "Contact", flexwidth, flexwidth, wrapper->contact_id, - (status ? (status->status == AVAILABLE ? "Avail" : "Unavail") : "Unknown"), - (status ? ((long long) status->rtt) / 1000.0 : NAN)); + ast_sip_get_contact_short_status_label(status->status), + (status->status != UNKNOWN ? ((long long) status->rtt) / 1000.0 : NAN)); return 0; } diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index ab0d08449433a5f241a30518294dae84ea5228bc..54fdb658bf8f103b24b557f231491b087e2d2cd3 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -86,7 +86,7 @@ static int persistent_endpoint_update_state(void *obj, void *arg, int flags) contact_status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, contact_id); - if (contact_status && contact_status->status == AVAILABLE) { + if (contact_status && contact_status->status != UNAVAILABLE) { state = AST_ENDPOINT_ONLINE; } ao2_cleanup(contact_status); @@ -184,10 +184,10 @@ static void persistent_endpoint_contact_status_observer(const void *object) "Contact: %s\r\n" "Status: %s", ast_sorcery_object_get_id(contact_status), - (contact_status->status == AVAILABLE ? "Available" : "Unavailable")); + ast_sip_get_contact_status_label(contact_status->status)); ast_verb(1, "Contact %s/%s is now %s\n", aor, contact, - contact_status->status == AVAILABLE ? "Available" : "Unavailable"); + ast_sip_get_contact_status_label(contact_status->status)); ao2_callback(persistent_endpoints, OBJ_NODATA, persistent_endpoint_update_state, aor); } diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index 9c0a1379d0905987fdac38c8c294a750bd44a4c1..692cbdbf55bfa97ecbf4873e3eea4513004ee258 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -35,6 +35,28 @@ #define DEFAULT_ENCODING "text/plain" #define QUALIFIED_BUCKETS 211 +static const char *status_map [] = { + [UNAVAILABLE] = "Unreachable", + [AVAILABLE] = "Reachable", + [UNKNOWN] = "Unknown", +}; + +static const char *short_status_map [] = { + [UNAVAILABLE] = "Unavail", + [AVAILABLE] = "Avail", + [UNKNOWN] = "Unknown", +}; + +const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status) +{ + return status_map[status]; +} + +const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status) +{ + return short_status_map[status]; +} + /*! * \internal * \brief Create a ast_sip_contact_status object. @@ -48,7 +70,7 @@ static void *contact_status_alloc(const char *name) return NULL; } - status->status = UNAVAILABLE; + status->status = UNKNOWN; return status; } @@ -86,19 +108,6 @@ static struct ast_sip_contact_status *find_or_create_contact_status(const struct return status; } -static void delete_contact_status(const struct ast_sip_contact *contact) -{ - struct ast_sip_contact_status *status = ast_sorcery_retrieve_by_id( - ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact)); - - if (!status) { - return; - } - - ast_sorcery_delete(ast_sip_get_sorcery(), status); - ao2_ref(status, -1); -} - /*! * \internal * \brief Update an ast_sip_contact_status's elements. @@ -129,17 +138,19 @@ static void update_contact_status(const struct ast_sip_contact *contact, /* if the contact is available calculate the rtt as the diff between the last start time and "now" */ - update->rtt = update->status == AVAILABLE ? + update->rtt = update->status == AVAILABLE && status->rtt_start.tv_sec > 0 ? ast_tvdiff_us(ast_tvnow(), status->rtt_start) : 0; update->rtt_start = ast_tv(0, 0); + + ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT", "Contact: %s\r\n" "Status: %s\r\n" "RTT: %ld", ast_sorcery_object_get_id(update), - (update->status == AVAILABLE ? "Available" : "Unavailable"), + ast_sip_get_contact_status_label(update->status), update->rtt); if (ast_sorcery_update(ast_sip_get_sorcery(), update)) { @@ -499,7 +510,7 @@ static void qualify_and_schedule(struct ast_sip_contact *contact) schedule_qualify(contact, contact->qualify_frequency * 1000); } else { - delete_contact_status(contact); + update_contact_status(contact, UNKNOWN); } } @@ -1011,6 +1022,8 @@ static int qualify_and_schedule_cb(void *obj, void *arg, int flags) if (contact->qualify_frequency) { schedule_qualify(contact, initial_interval); + } else { + update_contact_status(contact, UNKNOWN); } return 0; @@ -1082,11 +1095,6 @@ static void qualify_and_schedule_all(void) ao2_ref(endpoints, -1); } -static const char *status_map [] = { - [UNAVAILABLE] = "Unreachable", - [AVAILABLE] = "Reachable", -}; - static int format_contact_status(void *obj, void *arg, int flags) { struct ast_sip_contact_wrapper *wrapper = obj; @@ -1107,12 +1115,11 @@ static int format_contact_status(void *obj, void *arg, int flags) ast_str_append(&buf, 0, "AOR: %s\r\n", wrapper->aor_id); ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri); - if (status) { - ast_str_append(&buf, 0, "Status: %s\r\n", status_map[status->status]); - ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt); - } else { - ast_str_append(&buf, 0, "Status: Unknown\r\n"); + ast_str_append(&buf, 0, "Status: %s\r\n", ast_sip_get_contact_status_label(status->status)); + if (status->status == UNKNOWN) { ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n"); + } else { + ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt); } ast_str_append(&buf, 0, "EndpointName: %s\r\n", ast_sorcery_object_get_id(endpoint));