Merge "res_pjsip: Fix statsd regression."

changes/84/3184/1
Joshua Colp 9 years ago committed by Gerrit Code Review
commit e049248161

@ -408,8 +408,6 @@ res_pjsip
"contact_deny" - List of Contact header addresses to deny
"contact_permit" - List of Contact header addresses to permit
* Added new status Updated to AMI event ContactStatus on update registration
* Added "reg_server" to contacts.
If the Asterisk system name is set in asterisk.conf, it will be stored
into the "reg_server" field in the ps_contacts table to facilitate

@ -271,7 +271,6 @@ enum ast_sip_contact_status_type {
UNKNOWN,
CREATED,
REMOVED,
UPDATED,
};
/*!
@ -296,6 +295,8 @@ struct ast_sip_contact_status {
int64_t rtt;
/*! Last status for a contact (default - unavailable) */
enum ast_sip_contact_status_type last_status;
/*! TRUE if the contact was refreshed. e.g., re-registered */
unsigned int refresh:1;
};
/*!

@ -105,6 +105,40 @@ static void endpoint_update_state(struct ast_endpoint *endpoint, enum ast_endpoi
ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "PJSIP/%s", ast_endpoint_get_resource(endpoint));
}
static void endpoint_publish_contact_status(struct ast_endpoint *endpoint, struct ast_sip_contact_status *contact)
{
struct ast_json *blob;
char rtt[32];
snprintf(rtt, sizeof(rtt), "%" PRId64, contact->rtt);
blob = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
"contact_status", ast_sip_get_contact_status_label(contact->status),
"aor", contact->aor,
"uri", contact->uri,
"roundtrip_usec", rtt,
"endpoint_name", ast_endpoint_get_resource(endpoint));
if (blob) {
ast_endpoint_blob_publish(endpoint, ast_endpoint_contact_state_type(), blob);
ast_json_unref(blob);
}
}
/*! \brief Callback function for publishing the status of an endpoint */
static int persistent_endpoint_publish_status(void *obj, void *arg, int flags)
{
struct sip_persistent_endpoint *persistent = obj;
struct ast_endpoint *endpoint = persistent->endpoint;
struct ast_sip_contact_status *status = arg;
/* If the status' aor isn't one of the endpoint's, we skip */
if (!strstr(persistent->aors, status->aor)) {
return 0;
}
endpoint_publish_contact_status(endpoint, status);
return 0;
}
/*! \brief Callback function for changing the state of an endpoint */
static int persistent_endpoint_update_state(void *obj, void *arg, int flags)
{
@ -112,30 +146,17 @@ static int persistent_endpoint_update_state(void *obj, void *arg, int flags)
struct ast_endpoint *endpoint = persistent->endpoint;
struct ast_sip_contact_status *status = arg;
struct ao2_container *contacts;
struct ast_json *blob;
struct ao2_iterator i;
struct ast_sip_contact *contact;
enum ast_endpoint_state state = AST_ENDPOINT_OFFLINE;
if (status) {
char rtt[32];
/* If the status' aor isn't one of the endpoint's, we skip */
if (!strstr(persistent->aors, status->aor)) {
return 0;
}
snprintf(rtt, sizeof(rtt), "%" PRId64, status->rtt);
blob = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
"contact_status", ast_sip_get_contact_status_label(status->status),
"aor", status->aor,
"uri", status->uri,
"roundtrip_usec", rtt,
"endpoint_name", ast_endpoint_get_resource(endpoint));
ast_endpoint_blob_publish(endpoint, ast_endpoint_contact_state_type(), blob);
ast_json_unref(blob);
/* If the status' aor isn't one of the endpoint's, we skip */
if (!strstr(persistent->aors, status->aor)) {
return 0;
}
endpoint_publish_contact_status(endpoint, status);
/* Find all the contacts for this endpoint. If ANY are available,
* mark the endpoint as ONLINE.
*/
@ -222,6 +243,13 @@ static void persistent_endpoint_contact_status_observer(const void *object)
{
struct ast_sip_contact_status *contact_status = (struct ast_sip_contact_status *)object;
if (contact_status->refresh) {
/* We are only re-publishing the contact status. */
ao2_callback(persistent_endpoints, OBJ_NODATA,
persistent_endpoint_publish_status, contact_status);
return;
}
/* If rtt_start is set (this is the outgoing OPTIONS), ignore. */
if (contact_status->rtt_start.tv_sec > 0) {
return;

@ -43,7 +43,6 @@ static const char *status_map [] = {
[UNKNOWN] = "Unknown",
[CREATED] = "Created",
[REMOVED] = "Removed",
[UPDATED] = "Updated",
};
static const char *short_status_map [] = {
@ -52,7 +51,6 @@ static const char *short_status_map [] = {
[UNKNOWN] = "Unknown",
[CREATED] = "Created",
[REMOVED] = "Removed",
[UPDATED] = "Updated",
};
const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status)
@ -157,7 +155,7 @@ struct ast_sip_contact_status *ast_res_pjsip_find_or_create_contact_status(const
* \brief Update an ast_sip_contact_status's elements.
*/
static void update_contact_status(const struct ast_sip_contact *contact,
enum ast_sip_contact_status_type value)
enum ast_sip_contact_status_type value, int is_contact_refresh)
{
RAII_VAR(struct ast_sip_contact_status *, status, NULL, ao2_cleanup);
RAII_VAR(struct ast_sip_contact_status *, update, NULL, ao2_cleanup);
@ -169,6 +167,26 @@ static void update_contact_status(const struct ast_sip_contact *contact,
return;
}
if (is_contact_refresh
&& status->status == CREATED) {
/*
* The contact status hasn't been updated since creation
* and we don't want to re-send a created status.
*/
if (contact->qualify_frequency
|| status->rtt_start.tv_sec > 0) {
/* Ignore, the status will change soon. */
return;
}
/*
* Convert to a regular contact status update
* because the status may never change.
*/
is_contact_refresh = 0;
value = UNKNOWN;
}
update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
ast_sorcery_object_get_id(status));
if (!update) {
@ -178,22 +196,35 @@ static void update_contact_status(const struct ast_sip_contact *contact,
}
ast_string_field_set(update, uri, contact->uri);
update->last_status = status->status;
update->status = value;
/* if the contact is available calculate the rtt as
the diff between the last start time and "now" */
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: %" PRId64,
ast_sorcery_object_get_id(update),
ast_sip_get_contact_status_label(update->status),
update->rtt);
if (is_contact_refresh) {
/* Copy everything just to set the refresh flag. */
update->status = status->status;
update->last_status = status->last_status;
update->rtt = status->rtt;
update->rtt_start = status->rtt_start;
update->refresh = 1;
} else {
update->last_status = status->status;
update->status = value;
/*
* if the contact is available calculate the rtt as
* the diff between the last start time and "now"
*/
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: %" PRId64,
ast_sorcery_object_get_id(update),
ast_sip_get_contact_status_label(update->status),
update->rtt);
}
if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n",
@ -306,10 +337,10 @@ static void qualify_contact_cb(void *token, pjsip_event *e)
/* Fall through */
case PJSIP_EVENT_TRANSPORT_ERROR:
case PJSIP_EVENT_TIMER:
update_contact_status(contact, UNAVAILABLE);
update_contact_status(contact, UNAVAILABLE, 0);
break;
case PJSIP_EVENT_RX_MSG:
update_contact_status(contact, AVAILABLE);
update_contact_status(contact, AVAILABLE, 0);
break;
}
ao2_cleanup(contact);
@ -365,7 +396,7 @@ static int qualify_contact(struct ast_sip_endpoint *endpoint, struct ast_sip_con
!= PJ_SUCCESS) {
ast_log(LOG_ERROR, "Unable to send request to qualify contact %s\n",
contact->uri);
update_contact_status(contact, UNAVAILABLE);
update_contact_status(contact, UNAVAILABLE, 0);
ao2_ref(contact, -1);
return -1;
}
@ -525,7 +556,7 @@ static void qualify_and_schedule(struct ast_sip_contact *contact)
schedule_qualify(contact, contact->qualify_frequency * 1000);
} else {
update_contact_status(contact, UNKNOWN);
update_contact_status(contact, UNKNOWN, 0);
}
}
@ -544,8 +575,7 @@ static void contact_created(const void *obj)
*/
static void contact_updated(const void *obj)
{
update_contact_status((struct ast_sip_contact *) obj, UPDATED);
qualify_and_schedule((struct ast_sip_contact *) obj);
update_contact_status(obj, AVAILABLE, 1);
}
/*!
@ -574,8 +604,8 @@ static void contact_deleted(const void *obj)
static const struct ast_sorcery_observer contact_observer = {
.created = contact_created,
.updated = contact_updated,
.deleted = contact_deleted,
.updated = contact_updated
};
static pj_bool_t options_start(void)
@ -1051,7 +1081,7 @@ static void qualify_and_schedule_contact(struct ast_sip_contact *contact)
if (contact->qualify_frequency) {
schedule_qualify(contact, initial_interval);
} else {
update_contact_status(contact, UNKNOWN);
update_contact_status(contact, UNKNOWN, 0);
}
}

Loading…
Cancel
Save