Esempio n. 1
0
static struct ao2_container *get_container(const char *regex, ao2_sort_fn sort_fn, ao2_callback_fn compare_fn)
{
	struct ao2_container *child_container;
	regex_t regexbuf;
	RAII_VAR(struct ao2_container *, parent_container,
		stasis_cache_dump(ast_channel_cache_by_name(), ast_channel_snapshot_type()), ao2_cleanup);

	if (!parent_container) {
		return NULL;
	}

	child_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, sort_fn, compare_fn);
	if (!child_container) {
		return NULL;
	}

	ao2_callback(parent_container, OBJ_MULTIPLE | OBJ_NODATA, cli_message_to_snapshot, child_container);

	if (!ast_strlen_zero(regex)) {
		if (regcomp(&regexbuf, regex, REG_EXTENDED | REG_NOSUB)) {
			ao2_ref(child_container, -1);
			return NULL;
		}
		ao2_callback(child_container, OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA, cli_filter_channels, &regexbuf);
		regfree(&regexbuf);
	}

	return child_container;
}
Esempio n. 2
0
/*!
 * \brief Change the size of the threadpool
 *
 * This can either result in shrinking or growing the threadpool depending
 * on the new desired size and the current size.
 *
 * This function is run from the threadpool control taskprocessor thread
 *
 * \param data A set_size_data used for determining how to act
 * \return 0
 */
static int queued_set_size(void *data)
{
	RAII_VAR(struct set_size_data *, ssd, data, ao2_cleanup);
	struct ast_threadpool *pool = ssd->pool;
	unsigned int num_threads = ssd->size;

	/* We don't count zombie threads as being "live" when potentially resizing */
	unsigned int current_size = ao2_container_count(pool->active_threads) +
			ao2_container_count(pool->idle_threads);

	if (current_size == num_threads) {
		ast_debug(3, "Not changing threadpool size since new size %u is the same as current %u\n",
			  num_threads, current_size);
		return 0;
	}

	if (current_size < num_threads) {
		ao2_callback(pool->idle_threads, OBJ_UNLINK | OBJ_NOLOCK | OBJ_NODATA | OBJ_MULTIPLE,
				activate_thread, pool);

		/* As the above may have altered the number of current threads update it */
		current_size = ao2_container_count(pool->active_threads) +
				ao2_container_count(pool->idle_threads);
		grow(pool, num_threads - current_size);
		ao2_callback(pool->idle_threads, OBJ_UNLINK | OBJ_NOLOCK | OBJ_NODATA | OBJ_MULTIPLE,
				activate_thread, pool);
	} else {
		shrink(pool, current_size - num_threads);
	}

	threadpool_send_state_changed(pool);
	return 0;
}
Esempio n. 3
0
static struct ao2_container *cli_contact_get_container(const char *regex)
{
	RAII_VAR(struct ao2_container *, parent_container, NULL, ao2_cleanup);
	struct ao2_container *child_container;
	regex_t regexbuf;

	parent_container =  cli_aor_get_container("");
	if (!parent_container) {
		return NULL;
	}

	child_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
		cli_contact_sort, cli_contact_compare);
	if (!child_container) {
		return NULL;
	}

	ao2_callback(parent_container, OBJ_NODATA, cli_aor_gather_contacts, child_container);

	if (!ast_strlen_zero(regex)) {
		if (regcomp(&regexbuf, regex, REG_EXTENDED | REG_NOSUB)) {
			ao2_ref(child_container, -1);
			return NULL;
		}
		ao2_callback(child_container, OBJ_UNLINK | OBJ_MULTIPLE | OBJ_NODATA, cli_filter_contacts, &regexbuf);
		regfree(&regexbuf);
	}

	return child_container;
}
Esempio n. 4
0
static void qualify_and_schedule_all(void)
{
	struct ast_variable *var = ast_variable_new("qualify_frequency >", "0", "");
	struct ao2_container *aors;
	struct ao2_container *contacts;

	if (!var) {
		return;
	}
	aors = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
		"aor", AST_RETRIEVE_FLAG_MULTIPLE, var);

	ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, unschedule_all_cb, NULL);

	if (aors) {
		ao2_callback(aors, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
		ao2_ref(aors, -1);
	}

	contacts = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
		"contact", AST_RETRIEVE_FLAG_MULTIPLE, var);
	if (contacts) {
		ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb_without_aor, NULL);
		ao2_ref(contacts, -1);
	}

	ast_variables_destroy(var);

}
Esempio n. 5
0
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;

	snprintf(regex, sizeof(regex), "^%s;@", ast_sorcery_object_get_id(aor));

	if (!(contacts = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "contact", regex))) {
		return NULL;
	}

	/* Prune any expired contacts and delete them, we do this first because static contacts can never expire */
	ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, contact_expire, NULL);

	/* Add any permanent contacts from the AOR */
	if (aor->permanent_contacts) {
		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;
}
Esempio n. 6
0
static void send_mwi_notify(struct mwi_subscription *sub)
{
	struct ast_sip_message_accumulator counter = {
		.old_msgs = 0,
		.new_msgs = 0,
	};
	struct ast_sip_body_data data = {
		.body_type = AST_SIP_MESSAGE_ACCUMULATOR,
		.body_data = &counter,
	};

	ao2_callback(sub->stasis_subs, OBJ_NODATA, get_message_count, &counter);

	if (sub->is_solicited) {
		ast_sip_subscription_notify(sub->sip_sub, &data, 0);
		return;
	}

	send_unsolicited_mwi_notify(sub, &counter);
}

static int unsubscribe_stasis(void *obj, void *arg, int flags)
{
	struct mwi_stasis_subscription *mwi_stasis = obj;
	if (mwi_stasis->stasis_sub) {
		ast_debug(3, "Removing stasis subscription to mailbox %s\n", mwi_stasis->mailbox);
		mwi_stasis->stasis_sub = stasis_unsubscribe(mwi_stasis->stasis_sub);
	}
	return CMP_MATCH;
}

static void mwi_subscription_shutdown(struct ast_sip_subscription *sub)
{
	struct mwi_subscription *mwi_sub;
	RAII_VAR(struct ast_datastore *, mwi_datastore,
			ast_sip_subscription_get_datastore(sub, MWI_DATASTORE), ao2_cleanup);

	if (!mwi_datastore) {
		return;
	}

	mwi_sub = mwi_datastore->data;
	ao2_callback(mwi_sub->stasis_subs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe_stasis, NULL);
}

static struct ast_datastore_info mwi_ds_info = { };

static int add_mwi_datastore(struct mwi_subscription *sub)
{
	RAII_VAR(struct ast_datastore *, mwi_datastore, NULL, ao2_cleanup);

	mwi_datastore = ast_sip_subscription_alloc_datastore(&mwi_ds_info, MWI_DATASTORE);
	if (!mwi_datastore) {
		return -1;
	}
	mwi_datastore->data = sub;

	ast_sip_subscription_add_datastore(sub->sip_sub, mwi_datastore);
	return 0;
}
Esempio n. 7
0
struct parked_user *parking_lot_retrieve_parked_user(struct parking_lot *lot, int target)
{
	RAII_VAR(struct parked_user *, user, NULL, ao2_cleanup);

	if (target < 0) {
		user = ao2_callback(lot->parked_users, 0, NULL, NULL);
	} else {
		user = ao2_callback(lot->parked_users, 0, retrieve_parked_user_targeted, &target);
	}

	if (!user) {
		return NULL;
	}

	ao2_lock(user);
	if (user->resolution != PARK_UNSET) {
		/* Abandon. Something else has resolved the parked user before we got to it. */
		ao2_unlock(user);
		return NULL;
	}

	ao2_unlink(lot->parked_users, user);
	user->resolution = PARK_ANSWERED;
	ao2_unlock(user);

	parking_lot_remove_if_unused(user->lot);

	/* Bump the ref count by 1 since the RAII_VAR will eat the reference otherwise */
	ao2_ref(user, +1);
	return user;
}
Esempio n. 8
0
static void create_mwi_subscriptions(void)
{
	struct ao2_container *mwi_subscriptions = ao2_container_alloc(MWI_BUCKETS, mwi_sub_hash, mwi_sub_cmp);
	RAII_VAR(struct ao2_container *, old_mwi_subscriptions, ao2_global_obj_ref(unsolicited_mwi), ao2_cleanup);
	RAII_VAR(struct ao2_container *, endpoints, ast_sorcery_retrieve_by_fields(
				ast_sip_get_sorcery(), "endpoint", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL),
			ao2_cleanup);

	if (!mwi_subscriptions) {
		return;
	}

	/* We remove all the old stasis subscriptions first before applying the new configuration. This
	 * prevents a situation where there might be multiple overlapping stasis subscriptions for an
	 * endpoint for mailboxes. Though there may be mailbox changes during the gap between unsubscribing
	 * and resubscribing, up-to-date mailbox state will be sent out to the endpoint when the
	 * new stasis subscription is established
	 */
	if (old_mwi_subscriptions) {
		ao2_callback(old_mwi_subscriptions, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
	}
	ao2_callback(endpoints, OBJ_NODATA, create_mwi_subscriptions_for_endpoint, mwi_subscriptions);
	ao2_global_obj_replace_unref(unsolicited_mwi, mwi_subscriptions);
	ao2_ref(mwi_subscriptions, -1);
}
Esempio n. 9
0
void stasis_app_to_cli(const struct stasis_app *app, struct ast_cli_args *a)
{
	struct ao2_iterator *channels;
	struct ao2_iterator *endpoints;
	struct ao2_iterator *bridges;
	struct app_forwards *forward;
	enum forward_type forward_type;

	ast_cli(a->fd, "Name: %s\n"
		"  Debug: %s\n"
		"  Subscription Model: %s\n",
		app->name,
		app->debug ? "Yes" : "No",
		app->subscription_model == STASIS_APP_SUBSCRIBE_ALL ?
			"Global Resource Subscription" :
			"Application/Explicit Resource Subscription");
	ast_cli(a->fd, "  Subscriptions: %d\n", ao2_container_count(app->forwards));

	ast_cli(a->fd, "    Channels:\n");
	forward_type = FORWARD_CHANNEL;
	channels = ao2_callback(app->forwards, OBJ_MULTIPLE,
		forwards_filter_by_type, &forward_type);
	if (channels) {
		while ((forward = ao2_iterator_next(channels))) {
			ast_cli(a->fd, "      %s (%d)\n", forward->id, forward->interested);
			ao2_ref(forward, -1);
		}
		ao2_iterator_destroy(channels);
	}

	ast_cli(a->fd, "    Bridges:\n");
	forward_type = FORWARD_BRIDGE;
	bridges = ao2_callback(app->forwards, OBJ_MULTIPLE,
		forwards_filter_by_type, &forward_type);
	if (bridges) {
		while ((forward = ao2_iterator_next(bridges))) {
			ast_cli(a->fd, "      %s (%d)\n", forward->id, forward->interested);
			ao2_ref(forward, -1);
		}
		ao2_iterator_destroy(bridges);
	}

	ast_cli(a->fd, "    Endpoints:\n");
	forward_type = FORWARD_ENDPOINT;
	endpoints = ao2_callback(app->forwards, OBJ_MULTIPLE,
		forwards_filter_by_type, &forward_type);
	if (endpoints) {
		while ((forward = ao2_iterator_next(endpoints))) {
			ast_cli(a->fd, "      %s (%d)\n", forward->id, forward->interested);
			ao2_ref(forward, -1);
		}
		ao2_iterator_destroy(endpoints);
	}
}
Esempio n. 10
0
static void qualify_and_schedule_all(void)
{
	struct ao2_container *endpoints = ast_sip_get_endpoints();

	ao2_callback(sched_qualifies, OBJ_NODATA | OBJ_MULTIPLE | OBJ_UNLINK, unschedule_all_cb, NULL);

	if (!endpoints) {
		return;
	}

	ao2_callback(endpoints, OBJ_NODATA, qualify_and_schedule_all_cb, NULL);
	ao2_ref(endpoints, -1);
}
Esempio n. 11
0
static int on_aor_update_endpoint_state(void *obj, void *arg, int flags)
{
	struct ast_sip_aor *aor = obj;
	struct ao2_container *endpoints;
	RAII_VAR(struct ast_variable *, var, NULL, ast_variables_destroy);
	const char *aor_name = ast_sorcery_object_get_id(aor);
	char *aor_like;

	if (ast_strlen_zero(aor_name)) {
		return -1;
	}

	if (aor->permanent_contacts && ((int)(aor->qualify_frequency * 1000)) <= 0) {
		aor_like = ast_alloca(strlen(aor_name) + 3);
		sprintf(aor_like, "%%%s%%", aor_name);
		var = ast_variable_new("aors LIKE", aor_like, "");
		if (!var) {
			return -1;
		}
		endpoints = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(),
			"endpoint", AST_RETRIEVE_FLAG_MULTIPLE, var);

		if (endpoints) {
		    /*
		     * Because aors are a string list, we have to use a pattern match but since a simple
		     * pattern match could return an endpoint that has an aor of "aaabccc" when searching
		     * for "abc", we still have to iterate over them to find an exact aor match.
		     */
		    ao2_callback(endpoints, 0, aor_update_endpoint_state, (char *)aor_name);
		    ao2_ref(endpoints, -1);
		}
	}

	return 0;
}
Esempio n. 12
0
void ast_format_cap_remove_bytype(struct ast_format_cap *cap, enum ast_format_type type)
{
	ao2_callback(cap->formats,
		OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE | cap->nolock,
		multiple_by_type_cb,
		&type);
}
Esempio n. 13
0
/*!
 * \internal
 * \brief Send a NOTIFY request to the endpoint.
 *
 * \detail Iterates over an endpoint's AORs sending a NOTIFY request
 *         with the appropriate payload information to each contact.
 */
static int notify_endpoint(void *obj)
{
	RAII_VAR(struct notify_data *, data, obj, ao2_cleanup);
	char *aor_name, *aors;

	if (ast_strlen_zero(data->endpoint->aors)) {
		ast_log(LOG_WARNING, "Unable to NOTIFY - "
			"endpoint has no configured AORs\n");
		return -1;
	}

	aors = ast_strdupa(data->endpoint->aors);

	while ((aor_name = ast_strip(strsep(&aors, ",")))) {
		RAII_VAR(struct ast_sip_aor *, aor,
			 ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
		RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);

		if (!aor || !(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
			continue;
		}

		ao2_callback(contacts, OBJ_NODATA, notify_contact, data);
	}

	return 0;
}
Esempio n. 14
0
static void *do_timing(void *arg)
{
	struct timeval next_wakeup = ast_tvnow();

	while (!timing_thread.stop) {
		struct timespec ts = { 0, };

		ao2_callback(pthread_timers, OBJ_NODATA, run_timer, NULL);

		next_wakeup = ast_tvadd(next_wakeup, ast_tv(0, 5000));

		ts.tv_sec = next_wakeup.tv_sec;
		ts.tv_nsec = next_wakeup.tv_usec * 1000;

		ast_mutex_lock(&timing_thread.lock);
		if (!timing_thread.stop) {
			if (ao2_container_count(pthread_timers)) {
				ast_cond_timedwait(&timing_thread.cond, &timing_thread.lock, &ts);
			} else {
				ast_cond_wait(&timing_thread.cond, &timing_thread.lock);
			}
		}
		ast_mutex_unlock(&timing_thread.lock);
	}

	return NULL;
}
static struct ast_sip_endpoint *anonymous_identify(pjsip_rx_data *rdata)
{
	char domain_name[DOMAIN_NAME_LEN + 1];
	struct ast_sip_endpoint *endpoint;

	if (get_endpoint_details(rdata, domain_name, sizeof(domain_name))) {
		return NULL;
	}

	if (!ast_sip_get_disable_multi_domain()) {
		struct ast_sip_domain_alias *alias;
		struct ao2_container *transport_states;
		struct ast_sip_transport_state *transport_state = NULL;
		struct ast_sip_transport *transport = NULL;
		char id[sizeof("anonymous@") + DOMAIN_NAME_LEN];

		/* Attempt to find the endpoint given the name and domain provided */
		snprintf(id, sizeof(id), "anonymous@%s", domain_name);
		endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id);
		if (endpoint) {
			goto done;
		}

		/* See if an alias exists for the domain provided */
		alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias",
			domain_name);
		if (alias) {
			snprintf(id, sizeof(id), "anonymous@%s", alias->domain);
			ao2_ref(alias, -1);
			endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id);
			if (endpoint) {
				goto done;
			}
		}

		/* See if the transport this came in on has a provided domain */
		if ((transport_states = ast_sip_get_transport_states())
			&& (transport_state = ao2_callback(transport_states, 0, find_transport_state_in_use, rdata))
			&& (transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id))
			&& !ast_strlen_zero(transport->domain)) {
			snprintf(id, sizeof(id), "anonymous@%s", transport->domain);
			endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id);
		}
		ao2_cleanup(transport);
		ao2_cleanup(transport_state);
		ao2_cleanup(transport_states);
		if (endpoint) {
			goto done;
		}
	}

	/* Fall back to no domain */
	endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", "anonymous");

done:
	if (endpoint) {
		ast_debug(3, "Retrieved anonymous endpoint '%s'\n", ast_sorcery_object_get_id(endpoint));
	}
	return endpoint;
}
Esempio n. 16
0
/*! Continuously iterate through all the entries in the hash */
static void *hash_test_count(void *d)
{
    const struct hash_test *data = d;
    int count = 0;
    int last_count = 0;

    while (count < data->max_grow) {
        last_count = count;
        count = 0;
        ao2_callback(data->to_be_thrashed, OBJ_MULTIPLE, increment_count, &count);

        if (last_count == count) {
            /* Allow other threads to run. */
            sched_yield();
        } else if (last_count > count) {
            /* Make sure the ao2 container never shrinks */
            return "ao2 container unexpectedly shrank";
        }

        if (is_timed_out(data)) {
            return "Count timed out";
        }
    }

    /* Successfully iterated over all of the expected elements */
    return NULL;
}
Esempio n. 17
0
struct ao2_container *ast_multi_channel_blob_get_channels(struct ast_multi_channel_blob *obj, const char *role)
{
	RAII_VAR(struct ao2_container *, ret_container,
		ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS, channel_snapshot_hash_cb, channel_snapshot_cmp_cb),
		ao2_cleanup);
	struct ao2_iterator *it_role_snapshots;
	struct channel_role_snapshot *role_snapshot;
	char *arg;

	if (!obj || ast_strlen_zero(role) || !ret_container) {
		return NULL;
	}
	arg = ast_strdupa(role);

	it_role_snapshots = ao2_callback(obj->channel_snapshots, OBJ_MULTIPLE | OBJ_KEY, channel_role_multi_cmp_cb, arg);
	if (!it_role_snapshots) {
		return NULL;
	}

	while ((role_snapshot = ao2_iterator_next(it_role_snapshots))) {
		ao2_link(ret_container, role_snapshot->snapshot);
		ao2_ref(role_snapshot, -1);
	}
	ao2_iterator_destroy(it_role_snapshots);

	ao2_ref(ret_container, +1);
	return ret_container;
}
Esempio n. 18
0
int ast_format_cap_remove_byid(struct ast_format_cap *cap, enum ast_format_id id)
{
	struct ast_format format = {
		.id = id,
	};
	struct multiple_by_id_data data = {
		.format = &format,
		.match_found = 0,
	};

	ao2_callback(cap->formats,
		OBJ_NODATA | cap->nolock | OBJ_MULTIPLE | OBJ_UNLINK,
		multiple_by_id_cb,
		&data);

	/* match_found will be set if at least one item was removed */
	if (data.match_found) {
		return 0;
	}

	return -1;
}

static int multiple_by_type_cb(void *obj, void *arg, int flag)
{
	int *type = arg;
	struct ast_format *format = obj;
	return ((AST_FORMAT_GET_TYPE(format->id)) == *type) ? CMP_MATCH : 0;
}
Esempio n. 19
0
/*! \brief Load (or reload) configuration. */
static int process_config(int reload)
{
	RAII_VAR(struct ast_ari_conf *, conf, NULL, ao2_cleanup);

	switch (aco_process_config(&cfg_info, reload)) {
	case ACO_PROCESS_ERROR:
		return -1;
	case ACO_PROCESS_OK:
	case ACO_PROCESS_UNCHANGED:
		break;
	}

	conf = ast_ari_config_get();
	if (!conf) {
		ast_assert(0); /* We just configured; it should be there */
		return -1;
	}

	if (conf->general->enabled) {
		if (ao2_container_count(conf->users) == 0) {
			ast_log(LOG_ERROR, "No configured users for ARI\n");
		} else {
			ao2_callback(conf->users, OBJ_NODATA, validate_user_cb, NULL);
		}
	}

	return 0;
}
Esempio n. 20
0
static int unsubscribe(void *obj, void *arg, int flags)
{
	struct mwi_subscription *mwi_sub = obj;

	ao2_callback(mwi_sub->stasis_subs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe_stasis, NULL);
	return CMP_MATCH;
}
Esempio n. 21
0
/*!
 * \internal
 * \brief Qualify and schedule an endpoint's contacts
 *
 * \details For the given endpoint retrieve its list of aors, qualify all
 *         contacts, and schedule for checks if configured.
 */
static int qualify_and_schedule_all_cb(void *obj, void *arg, int flags)
{
	struct ast_sip_endpoint *endpoint = obj;
	char *aors;
	char *aor_name;

	if (ast_strlen_zero(endpoint->aors)) {
		return 0;
	}

	aors = ast_strdupa(endpoint->aors);
	while ((aor_name = strsep(&aors, ","))) {
		struct ast_sip_aor *aor;
		struct ao2_container *contacts;

		aor = ast_sip_location_retrieve_aor(aor_name);
		if (!aor) {
			continue;
		}

		contacts = ast_sip_location_retrieve_aor_contacts(aor);
		if (contacts) {
			ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb, aor);
			ao2_ref(contacts, -1);
		}

		ao2_ref(aor, -1);
	}

	return 0;
}
Esempio n. 22
0
/*! \brief Function called when a contact is updated */
static void mwi_contact_updated(const void *object)
{
	char *id = ast_strdupa(ast_sorcery_object_get_id(object)), *aor = NULL;

	aor = strsep(&id, ";@");

	ao2_callback(unsolicited_mwi, OBJ_NODATA, send_contact_notify, aor);
}
Esempio n. 23
0
static int unload_module(void)
{
	ao2_callback(unsolicited_mwi, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
	ao2_ref(unsolicited_mwi, -1);
	ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
	ast_sip_unregister_subscription_handler(&mwi_handler);
	return 0;
}
Esempio n. 24
0
static void traverse_elements(void)
{
#ifdef DEBUG
	printf("Traverse hashtab\n");
#endif
	ao2_callback(glob_hashtab, OBJ_NODATA, do_nothing_cb, NULL);
	els_traversals++; /* unprotected, sometimes off, but, not really important, either */
}
Esempio n. 25
0
static int do_reload(void)
{
	struct ast_config *config;
	const char *enabled_value;
	const char *val;
	int res = 0;
	struct ast_flags config_flags = { 0, };
	const char *s;

	ast_mutex_lock(&reload_lock);

	/* Reset all settings before reloading configuration */
	cel_enabled = CEL_ENALBED_DEFAULT;
	eventset = CEL_DEFAULT_EVENTS;
	*cel_dateformat = '\0';
	ao2_callback(appset, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, NULL, NULL);

	config = ast_config_load2("cel.conf", "cel", config_flags);

	if (config == CONFIG_STATUS_FILEMISSING) {
		config = NULL;
		goto return_cleanup;
	}

	if ((enabled_value = ast_variable_retrieve(config, "general", "enable"))) {
		cel_enabled = ast_true(enabled_value);
	}

	if (!cel_enabled) {
		goto return_cleanup;
	}

	/* get the date format for logging */
	if ((s = ast_variable_retrieve(config, "general", "dateformat"))) {
		ast_copy_string(cel_dateformat, s, sizeof(cel_dateformat));
	}

	if ((val = ast_variable_retrieve(config, "general", "events"))) {
		parse_events(val);
	}

	if ((val = ast_variable_retrieve(config, "general", "apps"))) {
		parse_apps(val);
	}

return_cleanup:
	ast_verb(3, "CEL logging %sabled.\n", cel_enabled ? "en" : "dis");

	ast_mutex_unlock(&reload_lock);

	if (config) {
		ast_config_destroy(config);
	}

	return res;
}
Esempio n. 26
0
static int prune_task(const void *data)
{
	unsigned int maxage;

	ast_sip_get_unidentified_request_thresholds(&unidentified_count, &unidentified_period, &unidentified_prune_interval);
	maxage = unidentified_period * 2;
	ao2_callback(unidentified_requests, OBJ_MULTIPLE | OBJ_NODATA | OBJ_UNLINK, expire_requests, &maxage);

	return unidentified_prune_interval * 1000;
}
Esempio n. 27
0
static int unload_module(void)
{
	RAII_VAR(struct ao2_container *, mwi_subscriptions, ao2_global_obj_ref(unsolicited_mwi), ao2_cleanup);
	if (mwi_subscriptions) {
		ao2_callback(mwi_subscriptions, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
		ao2_global_obj_release(unsolicited_mwi);
	}
	ast_sip_unregister_subscription_handler(&mwi_handler);
	return 0;
}
Esempio n. 28
0
/*!
 * \internal
 * \brief Find an endpoint associated with the given contact.
 */
static struct ast_sip_endpoint *find_an_endpoint(struct ast_sip_contact *contact)
{
	char *looking_for = (char *) ast_sorcery_object_get_id(contact);
	struct ao2_container *endpoints = ast_sip_get_endpoints();
	struct ast_sip_endpoint *endpoint;

	endpoint = ao2_callback(endpoints, 0, on_endpoint, looking_for);
	ao2_ref(endpoints, -1);
	return endpoint;
}
Esempio n. 29
0
static void aor_observer_modified(const void *obj)
{
	struct ast_sip_aor *aor = (void *)obj;
	struct ao2_container *contacts;

	contacts = ast_sip_location_retrieve_aor_contacts(aor);
	if (contacts) {
		ao2_callback(contacts, OBJ_NODATA, qualify_and_schedule_cb, aor);
		ao2_ref(contacts, -1);
	}
}
Esempio n. 30
0
static void aor_observer_deleted(const void *obj)
{
	const struct ast_sip_aor *aor = obj;
	struct ao2_container *contacts;

	contacts = ast_sip_location_retrieve_aor_contacts(aor);
	if (contacts) {
		ao2_callback(contacts, OBJ_NODATA, unschedule_contact_cb, NULL);
		ao2_ref(contacts, -1);
	}
}