Example #1
0
/*!
 * \brief Finds the control object for a channel, filling the response with an
 * error, if appropriate.
 * \param[out] response Response to fill with an error if control is not found.
 * \param channel_id ID of the channel to lookup.
 * \return Channel control object.
 * \return \c NULL if control object does not exist.
 */
static struct stasis_app_control *find_channel_control(
	struct ast_ari_response *response,
	const char *channel_id)
{
	RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);

	ast_assert(response != NULL);

	control = stasis_app_control_find_by_channel_id(channel_id);
	if (control == NULL) {
		/* Distinguish between 400 and 422 errors */
		RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL,
			ao2_cleanup);
		snapshot = ast_channel_snapshot_get_latest(channel_id);
		if (snapshot == NULL) {
			ast_log(LOG_DEBUG, "Couldn't find '%s'\n", channel_id);
			ast_ari_response_error(response, 400, "Bad Request",
				"Channel not found");
			return NULL;
		}

		ast_log(LOG_DEBUG, "Found non-stasis '%s'\n", channel_id);
		ast_ari_response_error(response, 422, "Unprocessable Entity",
			"Channel not in Stasis application");
		return NULL;
	}

	ao2_ref(control, +1);
	return control;
}
Example #2
0
struct ast_named_lock *__ast_named_lock_get(const char *filename, int lineno, const char *func,
	enum ast_named_lock_type lock_type, const char *keyspace, const char *key)
{
	struct ast_named_lock *lock = NULL;
	int concat_key_buff_len = strlen(keyspace) + strlen(key) + 2;
	char *concat_key = ast_alloca(concat_key_buff_len);

	sprintf(concat_key, "%s-%s", keyspace, key); /* Safe */

	ao2_lock(named_locks);
	lock = ao2_find(named_locks, concat_key, OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (lock) {
		ao2_unlock(named_locks);
		ast_assert((ao2_options_get(lock) & AO2_ALLOC_OPT_LOCK_MASK) == lock_type);
		return lock;
	}

	lock = ao2_alloc_options(sizeof(*lock) + concat_key_buff_len, NULL, lock_type);
	if (lock) {
		strcpy(lock->key, concat_key); /* Safe */
		ao2_link_flags(named_locks, lock, OBJ_NOLOCK);
	}
	ao2_unlock(named_locks);

	return lock;
}
Example #3
0
static struct ast_manager_event_blob *call_pickup_to_ami(struct stasis_message *message)
{
	struct ast_multi_channel_blob *contents = stasis_message_data(message);
	struct ast_channel_snapshot *chan;
	struct ast_channel_snapshot *target;
	struct ast_manager_event_blob *res;

	RAII_VAR(struct ast_str *, channel_str, NULL, ast_free);
	RAII_VAR(struct ast_str *, target_str, NULL, ast_free);

	chan = ast_multi_channel_blob_get_channel(contents, "channel");
	target = ast_multi_channel_blob_get_channel(contents, "target");

	ast_assert(chan != NULL && target != NULL);

	if (!(channel_str = ast_manager_build_channel_state_string(chan))) {
		return NULL;
	}

	if (!(target_str = ast_manager_build_channel_state_string_prefix(target, "Target"))) {
		return NULL;
	}

	res = ast_manager_event_blob_create(EVENT_FLAG_CALL, "Pickup",
		"%s"
		"%s",
		ast_str_buffer(channel_str),
		ast_str_buffer(target_str));

	return res;
}
Example #4
0
/*!
 * \brief Finds a bridge, filling the response with an error, if appropriate.
 *
 * \param[out] response Response to fill with an error if control is not found.
 * \param bridge_id ID of the bridge to lookup.
 *
 * \return Bridget.
 * \return \c NULL if bridge does not exist.
 */
static struct ast_bridge *find_bridge(
	struct ast_ari_response *response,
	const char *bridge_id)
{
	RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);

	ast_assert(response != NULL);

	bridge = stasis_app_bridge_find_by_id(bridge_id);
	if (bridge == NULL) {
		RAII_VAR(struct ast_bridge_snapshot *, snapshot,
			ast_bridge_snapshot_get_latest(bridge_id), ao2_cleanup);
		if (!snapshot) {
			ast_ari_response_error(response, 404, "Not found",
				"Bridge not found");
			return NULL;
		}

		ast_ari_response_error(response, 409, "Conflict",
			"Bridge not in Stasis application");
		return NULL;
	}

	ao2_ref(bridge, +1);
	return bridge;
}
Example #5
0
static int wait_bridge_sort_fn(const void *obj_left, const void *obj_right, const int flags)
{
	const struct wait_bridge_wrapper *left = obj_left;
	const struct wait_bridge_wrapper *right = obj_right;
	const char *right_key = obj_right;
	int cmp;

	switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
	case OBJ_POINTER:
		right_key = right->name;
		/* Fall through */
	case OBJ_KEY:
		cmp = strcmp(left->name, right_key);
		break;
	case OBJ_PARTIAL_KEY:
		cmp = strncmp(left->name, right_key, strlen(right_key));
		break;
	default:
		/* Sort can only work on something with a full or partial key. */
		ast_assert(0);
		cmp = 0;
		break;
	}
	return cmp;
}
Example #6
0
int ast_ari_remove_handler(struct stasis_rest_handlers *handler)
{
	RAII_VAR(struct stasis_rest_handlers *, new_handler, NULL, ao2_cleanup);
	size_t size, i, j;

	ast_assert(root_handler != NULL);

	ast_mutex_lock(&root_handler_lock);
	size = sizeof(*new_handler) +
		root_handler->num_children * sizeof(handler);

	new_handler = ao2_alloc(size, NULL);
	if (!new_handler) {
		return -1;
	}
	memcpy(new_handler, root_handler, sizeof(*new_handler));

	for (i = 0, j = 0; i < root_handler->num_children; ++i) {
		if (root_handler->children[i] == handler) {
			ast_module_unref(ast_module_info->self);
			continue;
		}
		new_handler->children[j++] = root_handler->children[i];
	}
	new_handler->num_children = j;

	ao2_cleanup(root_handler);
	ao2_ref(new_handler, +1);
	root_handler = new_handler;
	ast_mutex_unlock(&root_handler_lock);
	return 0;
}
Example #7
0
void ast_ari_websocket_events_event_websocket_established(
		struct ast_ari_websocket_session *ws_session, struct ast_variable *headers,
		struct ast_ari_events_event_websocket_args *args)
{
	RAII_VAR(struct event_session *, session, NULL, event_session_cleanup);
	struct ast_json *msg;
	const char *session_id;

	ast_debug(3, "/events WebSocket established\n");

	ast_assert(ws_session != NULL);

	session_id = ast_ari_websocket_session_id(ws_session);

	/* Find the event_session and update its websocket  */
	session = ao2_find(event_session_registry, session_id, OBJ_SEARCH_KEY);

	if (session) {
		ao2_unlink(event_session_registry, session);
		event_session_update_websocket(session, ws_session);
	} else {
		ast_log(LOG_WARNING,
			"Failed to locate an event session for the provided websocket session\n");
	}

	/* We don't process any input, but we'll consume it waiting for EOF */
	while ((msg = ast_ari_websocket_session_read(ws_session))) {
		ast_json_unref(msg);
	}
}
Example #8
0
/*!
 * \internal
 * \brief Create a ast_sip_contact_status object.
 */
static void *contact_status_alloc(const char *name)
{
	struct ast_sip_contact_status *status = ast_sorcery_generic_alloc(sizeof(*status), contact_status_destroy);
	char *id = ast_strdupa(name);
	char *aor = id;
	char *aor_separator = NULL;

	if (!status) {
		ast_log(LOG_ERROR, "Unable to allocate ast_sip_contact_status\n");
		return NULL;
	}

	if (ast_string_field_init(status, 256)) {
		ast_log(LOG_ERROR, "Unable to allocate ast_sip_contact_status stringfields\n");
		ao2_cleanup(status);
		return NULL;
	}

	/* Dynamic contacts are delimited with ";@" and static ones with "@@" */
	if ((aor_separator = strstr(id, ";@")) || (aor_separator = strstr(id, "@@"))) {
		*aor_separator = '\0';
	}
	ast_assert(aor_separator != NULL);

	ast_string_field_set(status, aor, aor);
	status->status = CREATED;

	return status;
}
Example #9
0
/*! \brief Publish a received device state \ref ast_event to \ref stasis */
static void publish_device_state_to_stasis(struct ast_event *event)
{
	const char *device;
	enum ast_device_state state;
	unsigned int cachable;
	struct ast_eid *event_eid;

	ast_assert(ast_event_get_type(event) == AST_EVENT_DEVICE_STATE_CHANGE);

	device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
	state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
	cachable = ast_event_get_ie_uint(event, AST_EVENT_IE_CACHABLE);
	event_eid = (struct ast_eid *)ast_event_get_ie_raw(event, AST_EVENT_IE_EID);

	if (ast_strlen_zero(device)) {
		return;
	}

	if (ast_publish_device_state_full(device, state, cachable, event_eid)) {
		char eid[18];
		ast_eid_to_str(eid, sizeof(eid), event_eid);
		ast_log(LOG_WARNING, "Failed to publish device state message for %s from %s\n",
			device, eid);
	}
}
Example #10
0
/*!
 * \brief convert from a pointer _p to a user-defined object
 *
 * \return the pointer to the astobj2 structure
 */
static struct astobj2 *INTERNAL_OBJ(void *user_data)
{
	struct astobj2 *p;

	if (!user_data) {
		ast_log(LOG_ERROR, "user_data is NULL\n");
		return NULL;
	}

	p = (struct astobj2 *) ((char *) user_data - sizeof(*p));
	if (AO2_MAGIC != p->priv_data.magic) {
		if (p->priv_data.magic) {
			ast_log(LOG_ERROR, "bad magic number 0x%x for object %p\n",
				p->priv_data.magic, user_data);
		} else {
			ast_log(LOG_ERROR,
				"bad magic number for object %p. Object is likely destroyed.\n",
				user_data);
		}
		ast_assert(0);
		return NULL;
	}

	return p;
}
Example #11
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;
}
Example #12
0
void ast_ari_get_global_var(struct ast_variable *headers, struct ast_get_global_var_args *args, struct ast_ari_response *response)
{
	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
	RAII_VAR(struct ast_str *, tmp, NULL, ast_free);

	const char *value;

	ast_assert(response != NULL);

	if (ast_strlen_zero(args->variable)) {
		ast_ari_response_error(
			response, 400, "Bad Request",
			"Variable name is required");
		return;
	}

	tmp = ast_str_create(32);
	if (!tmp) {
		ast_ari_response_alloc_failed(response);
		return;
	}

	value = ast_str_retrieve_variable(&tmp, 0, NULL, NULL, args->variable);

	if (!(json = ast_json_pack("{s: s}", "value", S_OR(value, "")))) {
		ast_ari_response_alloc_failed(response);
		return;
	}

	ast_ari_response_ok(response, ast_json_ref(json));
}
Example #13
0
int __ao2_ref_debug(void *user_data, int delta, const char *tag, const char *file, int line, const char *func)
{
	struct astobj2 *obj = INTERNAL_OBJ(user_data);
	int old_refcount = -1;

	if (obj) {
		old_refcount = internal_ao2_ref(user_data, delta, file, line, func);
	}

	if (ref_log && user_data) {
		if (!obj) {
			/* Invalid object: Bad magic number. */
			fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**invalid**,%s\n",
				user_data, delta, ast_get_tid(), file, line, func, tag);
			fflush(ref_log);
		} else if (old_refcount + delta == 0) {
			fprintf(ref_log, "%p,%d,%d,%s,%d,%s,**destructor**,%s\n",
				user_data, delta, ast_get_tid(), file, line, func, tag);
			fflush(ref_log);
		} else if (delta != 0) {
			fprintf(ref_log, "%p,%s%d,%d,%s,%d,%s,%d,%s\n", user_data, (delta < 0 ? "" : "+"),
				delta, ast_get_tid(), file, line, func, old_refcount, tag);
			fflush(ref_log);
		}
	}

	if (obj == NULL) {
		ast_assert(0);
	}

	return old_refcount;
}
Example #14
0
static void send_subscription_subscribe(struct stasis_topic *topic, struct stasis_subscription *sub)
{
	struct stasis_subscription_change *change;
	struct stasis_message *msg;

	/* This assumes that we have already unsubscribed */
	ast_assert(stasis_subscription_is_subscribed(sub));

	if (!stasis_subscription_change_type()) {
		return;
	}

	change = subscription_change_alloc(topic, sub->uniqueid, "Subscribe");
	if (!change) {
		return;
	}

	msg = stasis_message_create(stasis_subscription_change_type(), change);
	if (!msg) {
		ao2_cleanup(change);
		return;
	}

	stasis_publish(topic, msg);
	ao2_cleanup(msg);
	ao2_cleanup(change);
}
Example #15
0
static int cli_aor_print_header(void *obj, void *arg, int flags)
{
	struct ast_sip_cli_context *context = arg;
	RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup);

	int indent = CLI_INDENT_TO_SPACES(context->indent_level);
	int filler = CLI_LAST_TABSTOP - indent - 7;

	ast_assert(context->output_buffer != NULL);

	ast_str_append(&context->output_buffer, 0,
		"%*s:  <Aor%*.*s>  <MaxContact>\n",
		indent, "Aor", filler, filler, CLI_HEADER_FILLER);

	if (context->recurse) {
		context->indent_level++;
		formatter_entry = ast_sip_lookup_cli_formatter("contact");
		if (formatter_entry) {
			formatter_entry->print_header(NULL, context, 0);
		}
		context->indent_level--;
	}

	return 0;
}
Example #16
0
static int format_cmp_cb(void *obj, void *arg, int flags)
{
	const struct ast_format *left = obj;
	const struct ast_format *right = arg;
	const char *right_key = arg;
	int cmp;

	switch (flags & OBJ_SEARCH_MASK) {
	case OBJ_SEARCH_OBJECT:
		right_key = ast_format_get_name(right);
		/* Fall through */
	case OBJ_SEARCH_KEY:
		cmp = strcasecmp(ast_format_get_name(left), right_key);
		break;
	case OBJ_SEARCH_PARTIAL_KEY:
		cmp = strncasecmp(ast_format_get_name(left), right_key, strlen(right_key));
		break;
	default:
		ast_assert(0);
		cmp = 0;
		break;
	}
	if (cmp) {
		return 0;
	}

	return CMP_MATCH;
}
Example #17
0
void ast_ari_channels_get(struct ast_variable *headers,
	struct ast_ari_channels_get_args *args,
	struct ast_ari_response *response)
{
	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
	struct stasis_cache *cache;
	struct ast_channel_snapshot *snapshot;

	cache = ast_channel_cache();
	if (!cache) {
		ast_ari_response_error(
			response, 500, "Internal Server Error",
			"Message bus not initialized");
		return;
	}

	msg = stasis_cache_get(cache, ast_channel_snapshot_type(),
				   args->channel_id);
	if (!msg) {
		ast_ari_response_error(
			response, 404, "Not Found",
			"Channel not found");
		return;
	}

	snapshot = stasis_message_data(msg);
	ast_assert(snapshot != NULL);

	ast_ari_response_ok(response,
				ast_channel_snapshot_to_json(snapshot, NULL));
}
Example #18
0
static int permanent_uri_sort_fn(const void *obj_left, const void *obj_right, int flags)
{
	const struct ast_sip_contact *object_left = obj_left;
	const struct ast_sip_contact *object_right = obj_right;
	const char *right_key = obj_right;
	int cmp;

	switch (flags & OBJ_SEARCH_MASK) {
	case OBJ_SEARCH_OBJECT:
		right_key = ast_sorcery_object_get_id(object_right);
		/* Fall through */
	case OBJ_SEARCH_KEY:
		cmp = strcmp(ast_sorcery_object_get_id(object_left), right_key);
		break;
	case OBJ_SEARCH_PARTIAL_KEY:
		/*
		 * We could also use a partial key struct containing a length
		 * so strlen() does not get called for every comparison instead.
		 */
		cmp = strncmp(ast_sorcery_object_get_id(object_left), right_key, strlen(right_key));
		break;
	default:
		/* Sort can only work on something with a full or partial key. */
		ast_assert(0);
		cmp = 0;
		break;
	}
	return cmp;
}
Example #19
0
/*!
 * \brief Finds the control object for a channel, filling the response with an
 * error, if appropriate.
 * \param[out] response Response to fill with an error if control is not found.
 * \param channel_id ID of the channel to lookup.
 * \return Channel control object.
 * \return \c NULL if control object does not exist.
 */
static struct stasis_app_control *find_control(
	struct ast_ari_response *response,
	const char *channel_id)
{
	RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);

	ast_assert(response != NULL);

	control = stasis_app_control_find_by_channel_id(channel_id);
	if (control == NULL) {
		/* Distinguish between 404 and 409 errors */
		RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
		chan = ast_channel_get_by_name(channel_id);
		if (chan == NULL) {
			ast_ari_response_error(response, 404, "Not Found",
				   "Channel not found");
			return NULL;
		}

		ast_ari_response_error(response, 409, "Conflict",
			   "Channel not in Stasis application");
		return NULL;
	}

	ao2_ref(control, +1);
	return control;
}
Example #20
0
static int corosync_node_cmp_fn(void *obj, void *arg, int flags)
{
	struct corosync_node *left = obj;
	struct corosync_node *right = arg;
	const int *id = arg;
	int cmp;

	switch (flags & OBJ_SEARCH_MASK) {
	case OBJ_SEARCH_OBJECT:
		id = &right->id;
		/* Fall through */
	case OBJ_SEARCH_KEY:
		cmp = (left->id == *id);
		break;
	case OBJ_SEARCH_PARTIAL_KEY:
		cmp = (left->id == right->id);
		break;
	default:
		/* Sort can only work on something with a full or partial key. */
		ast_assert(0);
		cmp = 1;
		break;
	}
	return cmp ? CMP_MATCH : 0;
}
Example #21
0
void ast_json_free(void *p)
{
	struct json_mem *mem;
	struct json_mem_list *free_list;
	mem = to_json_mem(p);

	if (!mem) {
		return;
	}

	/* Since the unref is holding a lock in mem, we can't free it
	 * immediately. Store it off on a thread local list to be freed by
	 * ast_json_unref().
	 */
	free_list = json_free_list();
	if (!free_list) {
		ast_log(LOG_ERROR, "Error allocating free list\n");
		ast_assert(0);
		/* It's not ideal to free the memory immediately, but that's the
		 * best we can do if the threadlocal allocation fails */
		json_mem_free(mem);
		return;
	}

	AST_LIST_INSERT_HEAD(free_list, mem, list);
}
Example #22
0
int ast_format_cache_set(struct ast_format *format)
{
	SCOPED_AO2WRLOCK(lock, formats);
	struct ast_format *old_format;

	ast_assert(format != NULL);

	if (ast_strlen_zero(ast_format_get_name(format))) {
		return -1;
	}

	old_format = ao2_find(formats, ast_format_get_name(format), OBJ_SEARCH_KEY | OBJ_NOLOCK);
	if (old_format) {
		ao2_unlink_flags(formats, old_format, OBJ_NOLOCK);
	}
	ao2_link_flags(formats, format, OBJ_NOLOCK);

	set_cached_format(ast_format_get_name(format), format);

	ast_verb(2, "%s cached format with name '%s'\n",
		old_format ? "Updated" : "Created",
		ast_format_get_name(format));

	ao2_cleanup(old_format);

	return 0;
}
Example #23
0
void ast_channel_publish_varset(struct ast_channel *chan, const char *name, const char *value)
{
	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);

	ast_assert(name != NULL);
	ast_assert(value != NULL);

	blob = ast_json_pack("{s: s, s: s}",
			     "variable", name,
			     "value", value);
	if (!blob) {
		ast_log(LOG_ERROR, "Error creating message\n");
		return;
	}

	ast_channel_publish_blob(chan, ast_channel_varset_type(), blob);
}
Example #24
0
static void app_dtor(void *obj)
{
	struct stasis_app *app = obj;

	ast_verb(1, "Destroying Stasis app %s\n", app->name);

	ast_assert(app->router == NULL);
	ast_assert(app->bridge_router == NULL);
	ast_assert(app->endpoint_router == NULL);

	ao2_cleanup(app->topic);
	app->topic = NULL;
	ao2_cleanup(app->forwards);
	app->forwards = NULL;
	ao2_cleanup(app->data);
	app->data = NULL;
}
Example #25
0
static void subscription_dtor(void *obj)
{
	struct stasis_subscription *sub = obj;

	/* Subscriptions need to be manually unsubscribed before destruction
	 * b/c there's a cyclic reference between topics and subscriptions */
	ast_assert(!stasis_subscription_is_subscribed(sub));
	/* If there are any messages in flight to this subscription; that would
	 * be bad. */
	ast_assert(stasis_subscription_is_done(sub));

	ao2_cleanup(sub->topic);
	sub->topic = NULL;
	ast_taskprocessor_unreference(sub->mailbox);
	sub->mailbox = NULL;
	ast_cond_destroy(&sub->join_cond);
}
Example #26
0
static void test_handler(void *data, const char *app_name, struct ast_json *message)
{
	struct app_data *actual = data;
	int res;
	++(actual->invocations);
	res = ast_json_array_append(actual->messages, ast_json_copy(message));
	ast_assert(res == 0);
}
Example #27
0
static void jb_get_and_deliver(struct ast_channel *chan)
{
	struct ast_jb *jb = ast_channel_jb(chan);
	const struct ast_jb_impl *jbimpl = jb->impl;
	void *jbobj = jb->jbobj;
	struct ast_frame *f, finterp = { .frametype = AST_FRAME_VOICE, };
	long now;
	int interpolation_len, res;

	now = get_now(jb, NULL);
	jb->next = jbimpl->next(jbobj);
	if (now < jb->next) {
		jb_framelog("\tJB_GET {now=%ld}: now < next=%ld\n", now, jb->next);
		return;
	}

	while (now >= jb->next) {
		interpolation_len = ast_codec_interp_len(&jb->last_format);

		res = jbimpl->get(jbobj, &f, now, interpolation_len);

		switch (res) {
		case AST_JB_IMPL_OK:
			/* deliver the frame */
			ast_write(chan, f);
		case AST_JB_IMPL_DROP:
			jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n",
				now, jb_get_actions[res], f->ts, f->len);
			ast_format_copy(&jb->last_format, &f->subclass.format);
			ast_frfree(f);
			break;
		case AST_JB_IMPL_INTERP:
			/* interpolate a frame */
			f = &finterp;
			ast_format_copy(&f->subclass.format, &jb->last_format);
			f->samples  = interpolation_len * 8;
			f->src  = "JB interpolation";
			f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000));
			f->offset = AST_FRIENDLY_OFFSET;
			/* deliver the interpolated frame */
			ast_write(chan, f);
			jb_framelog("\tJB_GET {now=%ld}: Interpolated frame with len=%d\n", now, interpolation_len);
			break;
		case AST_JB_IMPL_NOFRAME:
			ast_log(LOG_WARNING,
				"AST_JB_IMPL_NOFRAME is returned from the %s jb when now=%ld >= next=%ld, jbnext=%ld!\n",
				jbimpl->name, now, jb->next, jbimpl->next(jbobj));
			jb_framelog("\tJB_GET {now=%ld}: No frame for now!?\n", now);
			return;
		default:
			ast_log(LOG_ERROR, "This should never happen!\n");
			ast_assert("JB type unknown" == NULL);
			break;
		}

		jb->next = jbimpl->next(jbobj);
	}
}
Example #28
0
int __ao2_trylock(void *user_data, enum ao2_lock_req lock_how, const char *file, const char *func, int line, const char *var)
{
	struct astobj2 *obj = INTERNAL_OBJ(user_data);
	struct astobj2_lock *obj_mutex;
	struct astobj2_rwlock *obj_rwlock;
	int res = 0;

	if (obj == NULL) {
		ast_assert(0);
		return -1;
	}

	switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
	case AO2_ALLOC_OPT_LOCK_MUTEX:
		obj_mutex = INTERNAL_OBJ_MUTEX(user_data);
		res = __ast_pthread_mutex_trylock(file, line, func, var, &obj_mutex->mutex.lock);
#ifdef AO2_DEBUG
		if (!res) {
			ast_atomic_fetchadd_int(&ao2.total_locked, 1);
		}
#endif
		break;
	case AO2_ALLOC_OPT_LOCK_RWLOCK:
		obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
		switch (lock_how) {
		case AO2_LOCK_REQ_MUTEX:
		case AO2_LOCK_REQ_WRLOCK:
			res = __ast_rwlock_trywrlock(file, line, func, &obj_rwlock->rwlock.lock, var);
			if (!res) {
				ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, -1);
#ifdef AO2_DEBUG
				ast_atomic_fetchadd_int(&ao2.total_locked, 1);
#endif
			}
			break;
		case AO2_LOCK_REQ_RDLOCK:
			res = __ast_rwlock_tryrdlock(file, line, func, &obj_rwlock->rwlock.lock, var);
			if (!res) {
				ast_atomic_fetchadd_int(&obj_rwlock->rwlock.num_lockers, +1);
#ifdef AO2_DEBUG
				ast_atomic_fetchadd_int(&ao2.total_locked, 1);
#endif
			}
			break;
		}
		break;
	case AO2_ALLOC_OPT_LOCK_NOLOCK:
		/* The ao2 object has no lock. */
		return 0;
	default:
		ast_log(__LOG_ERROR, file, line, func, "Invalid lock option on ao2 object %p\n",
			user_data);
		return -1;
	}


	return res;
}
void stasis_message_router_publish_sync(struct stasis_message_router *router,
	struct stasis_message *message)
{
	ast_assert(router != NULL);

	ao2_bump(router);
	stasis_publish_sync(router->subscription, message);
	ao2_cleanup(router);
}
Example #30
0
/*! Forward a endpoint's topics to an app */
static struct app_forwards *forwards_create_endpoint(struct stasis_app *app,
	struct ast_endpoint *endpoint)
{
	struct app_forwards *forwards;
	int ret = 0;

	if (!app) {
		return NULL;
	}

	forwards = forwards_create(app, endpoint ? ast_endpoint_get_id(endpoint) : ENDPOINT_ALL);
	if (!forwards) {
		return NULL;
	}

	forwards->forward_type = FORWARD_ENDPOINT;
	if (endpoint) {
		forwards->topic_forward = stasis_forward_all(ast_endpoint_topic(endpoint),
			app->topic);
		forwards->topic_cached_forward = stasis_forward_all(
			ast_endpoint_topic_cached(endpoint), app->topic);

		if (!forwards->topic_forward || !forwards->topic_cached_forward) {
			/* Half-subscribed is a bad thing */
			forwards_unsubscribe(forwards);
			ao2_ref(forwards, -1);
			return NULL;
		}
	} else {
		/* Since endpoint subscriptions also subscribe to channels, in the case
		 * of all endpoint subscriptions, we only want messages for the endpoints.
		 * As such, we route those particular messages and then re-publish them
		 * on the app's topic.
		 */
		ast_assert(app->endpoint_router == NULL);
		app->endpoint_router = stasis_message_router_create(ast_endpoint_topic_all_cached());
		if (!app->endpoint_router) {
			forwards_unsubscribe(forwards);
			ao2_ref(forwards, -1);
			return NULL;
		}

		ret |= stasis_message_router_add(app->endpoint_router,
			ast_endpoint_state_type(), endpoint_state_cb, app);
		ret |= stasis_message_router_add(app->endpoint_router,
			ast_endpoint_contact_state_type(), endpoint_state_cb, app);

		if (ret) {
			ao2_ref(app->endpoint_router, -1);
			app->endpoint_router = NULL;
			ao2_ref(forwards, -1);
			return NULL;
		}
	}

	return forwards;
}