示例#1
0
/*!
 * \internal
 * \brief Initialize the start time on a contact status so the round
 *        trip time can be calculated upon a valid response.
 */
static void init_start_time(const struct ast_sip_contact *contact)
{
	struct ast_sip_contact_status *status;
	struct ast_sip_contact_status *update;

	status = ast_res_pjsip_find_or_create_contact_status(contact);
	if (!status) {
		ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n",
			contact->uri);
		return;
	}

	update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
		ast_sorcery_object_get_id(status));
	if (!update) {
		ast_log(LOG_ERROR, "Unable to copy ast_sip_contact_status for contact %s\n",
			contact->uri);
		return;
	}

	update->status = status->status;
	update->last_status = status->last_status;
	update->rtt = status->rtt;
	update->rtt_start = ast_tvnow();

	if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
		ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n",
			contact->uri);
	}

	ao2_ref(status, -1);
	ao2_ref(update, -1);
}
示例#2
0
/*!
 * \internal
 * \brief Initialize the start time on a contact status so the round
 *        trip time can be calculated upon a valid response.
 */
static void init_start_time(const struct ast_sip_contact *contact)
{
	RAII_VAR(struct ast_sip_contact_status *, status, NULL, ao2_cleanup);
	RAII_VAR(struct ast_sip_contact_status *, update, NULL, ao2_cleanup);

	status = ast_res_pjsip_find_or_create_contact_status(contact);
	if (!status) {
		ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n",
			contact->uri);
		return;
	}

	update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
		ast_sorcery_object_get_id(status));
	if (!update) {
		ast_log(LOG_ERROR, "Unable to copy ast_sip_contact_status for contact %s\n",
			contact->uri);
		return;
	}

	ast_string_field_set(status, uri, contact->uri);
	update->status = status->status;
	update->last_status = status->last_status;
	update->rtt = status->rtt;
	update->rtt_start = ast_tvnow();

	if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
		ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n",
			contact->uri);
	}
}
示例#3
0
int ast_mwi_mailbox_update(struct ast_mwi_mailbox_object *mailbox)
{
	const struct ast_mwi_mailbox_object *exists;
	int res;

	exists = ast_sorcery_retrieve_by_id(mwi_sorcery, MWI_MAILBOX_TYPE,
		ast_sorcery_object_get_id(mailbox));
	if (exists) {
		res = ast_sorcery_update(mwi_sorcery, mailbox);
		ast_mwi_mailbox_unref(exists);
	} else {
		res = ast_sorcery_create(mwi_sorcery, mailbox);
	}
	return res;
}
示例#4
0
/*!
 * \internal
 * \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)
{
	struct ast_sip_contact_status *status;
	struct ast_sip_contact_status *update;

	status = ast_res_pjsip_find_or_create_contact_status(contact);
	if (!status) {
		ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n",
			contact->uri);
		return;
	}

	update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
		ast_sorcery_object_get_id(status));
	if (!update) {
		ast_log(LOG_ERROR, "Unable to allocate ast_sip_contact_status for contact %s\n",
			contact->uri);
		return;
	}

	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",
			contact->uri);
	}

	ao2_ref(status, -1);
	ao2_ref(update, -1);
}
示例#5
0
/*!
 * \internal
 * \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)
{
	struct ast_sip_contact_status *status;
	struct ast_sip_contact_status *update;

	status = find_or_create_contact_status(contact);
	if (!status) {
		return;
	}

	update = ast_sorcery_alloc(ast_sip_get_sorcery(), CONTACT_STATUS,
		ast_sorcery_object_get_id(status));
	if (!update) {
		ast_log(LOG_ERROR, "Unable to create update ast_sip_contact_status for contact %s\n",
			contact->uri);
		ao2_ref(status, -1);
		return;
	}

	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 ?
		ast_tvdiff_us(ast_tvnow(), status->rtt_start) : 0;

	update->rtt_start = ast_tv(0, 0);

	if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
		ast_log(LOG_ERROR, "Unable to update ast_sip_contact_status for contact %s\n",
			contact->uri);
	}

	ao2_ref(update, -1);
	ao2_ref(status, -1);
}
示例#6
0
int ast_sip_location_update_contact(struct ast_sip_contact *contact)
{
	return ast_sorcery_update(ast_sip_get_sorcery(), contact);
}
示例#7
0
void ast_ari_asterisk_update_object(struct ast_variable *headers, struct ast_ari_asterisk_update_object_args *args, struct ast_ari_response *response)
{
	RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
	RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
	RAII_VAR(void *, sorcery_obj, NULL, ao2_cleanup);
	struct ast_json *fields;
	struct ast_variable *update_set = NULL;
	int created = 0;

	sorcery = ast_sorcery_retrieve_by_module_name(args->config_class);
	if (!sorcery) {
		ast_ari_response_error(
			response, 404, "Not Found",
			"configClass '%s' not found",
			args->config_class);
		return;
	}

	object_type = ast_sorcery_get_object_type(sorcery, args->object_type);
	if (!object_type) {
		ast_ari_response_error(
			response, 404, "Not Found",
			"objectType '%s' not found",
			args->object_type);
		return;
	}

	sorcery_obj = ast_sorcery_retrieve_by_id(sorcery, args->object_type, args->id);
	if (!sorcery_obj) {
		ast_debug(5, "Sorcery object '%s' does not exist; creating it\n", args->id);
		sorcery_obj = ast_sorcery_alloc(sorcery, args->object_type, args->id);
		if (!sorcery_obj) {
			ast_ari_response_alloc_failed(response);
			return;
		}

		created = 1;
	} else {
		void *copy;

		copy = ast_sorcery_copy(sorcery, sorcery_obj);
		if (!copy) {
			ast_ari_response_alloc_failed(response);
			return;
		}

		ao2_ref(sorcery_obj, -1);
		sorcery_obj = copy;
	}

	fields = ast_json_object_get(args->fields, "fields");
	if (!fields && !created) {
		/* Whoops. We need data. */
		ast_ari_response_error(
			response, 400, "Bad request",
			"Fields must be provided to update object '%s'",
			args->id);
		return;
	} else if (fields) {
		size_t i;

		for (i = 0; i < ast_json_array_size(fields); i++) {
			struct ast_variable *new_var;
			struct ast_json *json_value = ast_json_array_get(fields, i);

			if (!json_value) {
				continue;
			}

			new_var = ast_variable_new(
				ast_json_string_get(ast_json_object_get(json_value, "attribute")),
				ast_json_string_get(ast_json_object_get(json_value, "value")),
				"");
			if (!new_var) {
				ast_variables_destroy(update_set);
				ast_ari_response_alloc_failed(response);
				return;
			}
			ast_variable_list_append(&update_set, new_var);
		}
	}

	/* APPLY! Note that a NULL update_set is fine (and necessary), as it
	 * will force validation on a newly created object.
	 */
	if (ast_sorcery_objectset_apply(sorcery, sorcery_obj, update_set)) {
		ast_variables_destroy(update_set);
		ast_ari_response_error(
			response, 400, "Bad request",
			"%s of object '%s' failed field value validation",
			created ? "Creation" : "Update",
			args->id);
		return;
	}

	ast_variables_destroy(update_set);

	if (created) {
		if (ast_sorcery_create(sorcery, sorcery_obj)) {
			ast_ari_response_error(
				response, 403, "Forbidden",
				"Cannot create sorcery objects of type '%s'",
				args->object_type);
			return;
		}
	} else {
		if (ast_sorcery_update(sorcery, sorcery_obj)) {
			ast_ari_response_error(
				response, 403, "Forbidden",
				"Cannot update sorcery objects of type '%s'",
				args->object_type);
			return;
		}
	}

	return_sorcery_object(sorcery, sorcery_obj, response);
}
示例#8
0
/*!
 * \internal
 * \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, 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);

	status = ast_res_pjsip_find_or_create_contact_status(contact);
	if (!status) {
		ast_log(LOG_ERROR, "Unable to find ast_sip_contact_status for contact %s\n",
			contact->uri);
		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) {
		ast_log(LOG_ERROR, "Unable to allocate ast_sip_contact_status for contact %s\n",
			contact->uri);
		return;
	}

	ast_string_field_set(update, uri, contact->uri);

	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",
			contact->uri);
	}
}