Esempio n. 1
0
/*! \internal
 * \brief determine if a list of attribute key value pairs are set on a format
 */
static int format_isset_helper(const struct ast_format *format, va_list ap)
{
	int res;
	struct interface_ao2_wrapper *wrapper;
	struct ast_format tmp = {
		.id = format->id,
		.fattr = { { 0, }, },
	};

	if (!(wrapper = find_interface(format))) {
		return -1;
	}

	ao2_rdlock(wrapper);
	if (!wrapper->interface ||
		!wrapper->interface->format_attr_set ||
		!wrapper->interface->format_attr_cmp) {

		ao2_unlock(wrapper);
		ao2_ref(wrapper, -1);
		return -1;
	}

	/* if isset is present, use that function, else just build a new
	 * format and use the cmp function */
	if (wrapper->interface->format_attr_isset) {
		res = wrapper->interface->format_attr_isset(&format->fattr, ap);
	} else {
		wrapper->interface->format_attr_set(&tmp.fattr, ap);
		/* use our tmp structure to tell if the attributes are set or not */
		res = wrapper->interface->format_attr_cmp(&tmp.fattr, &format->fattr);
		res = (res == AST_FORMAT_CMP_NOT_EQUAL) ? -1 : 0;
	}

	ao2_unlock(wrapper);
	ao2_ref(wrapper, -1);

	return res;
}

int ast_format_isset(const struct ast_format *format, ... )
{
	va_list ap;
	int res;

	va_start(ap, format);
	res = format_isset_helper(format, ap);
	va_end(ap);
	return res;
}
Esempio n. 2
0
/*!
 * \internal
 * \brief Adjust an object's lock to the requested level.
 *
 * \param user_data An ao2 object to adjust lock level.
 * \param lock_how What level to adjust lock.
 * \param keep_stronger TRUE if keep original lock level if it is stronger.
 *
 * \pre The ao2 object is already locked.
 *
 * \details
 * An ao2 object with a RWLOCK will have its lock level adjusted
 * to the specified level if it is not already there.  An ao2
 * object with a different type of lock is not affected.
 *
 * \return Original lock level.
 */
enum ao2_lock_req __adjust_lock(void *user_data, enum ao2_lock_req lock_how, int keep_stronger)
{
	struct astobj2 *obj = INTERNAL_OBJ(user_data);
	struct astobj2_rwlock *obj_rwlock;
	enum ao2_lock_req orig_lock;

	switch (obj->priv_data.options & AO2_ALLOC_OPT_LOCK_MASK) {
	case AO2_ALLOC_OPT_LOCK_RWLOCK:
		obj_rwlock = INTERNAL_OBJ_RWLOCK(user_data);
		if (obj_rwlock->rwlock.num_lockers < 0) {
			orig_lock = AO2_LOCK_REQ_WRLOCK;
		} else {
			orig_lock = AO2_LOCK_REQ_RDLOCK;
		}
		switch (lock_how) {
		case AO2_LOCK_REQ_MUTEX:
			lock_how = AO2_LOCK_REQ_WRLOCK;
			/* Fall through */
		case AO2_LOCK_REQ_WRLOCK:
			if (lock_how != orig_lock) {
				/* Switch from read lock to write lock. */
				ao2_unlock(user_data);
				ao2_wrlock(user_data);
			}
			break;
		case AO2_LOCK_REQ_RDLOCK:
			if (!keep_stronger && lock_how != orig_lock) {
				/* Switch from write lock to read lock. */
				ao2_unlock(user_data);
				ao2_rdlock(user_data);
			}
			break;
		}
		break;
	default:
		ast_log(LOG_ERROR, "Invalid lock option on ao2 object %p\n", user_data);
		/* Fall through */
	case AO2_ALLOC_OPT_LOCK_NOLOCK:
	case AO2_ALLOC_OPT_LOCK_MUTEX:
		orig_lock = AO2_LOCK_REQ_MUTEX;
		break;
	}

	return orig_lock;
}
Esempio n. 3
0
/*! \internal
 * \brief get joint format attributes using an interface
 */
static int format_joint_helper(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result)
{
	int res = 0;
	struct interface_ao2_wrapper *wrapper;

	if (!(wrapper = find_interface(format1))) {
		/* if no interface is present, we assume formats are joint by id alone */
		return res;
	}

	ao2_rdlock(wrapper);
	if (wrapper->interface && wrapper->interface->format_attr_get_joint) {
		res = wrapper->interface->format_attr_get_joint(&format1->fattr, &format2->fattr, &result->fattr);
	}
	ao2_unlock(wrapper);

	ao2_ref(wrapper, -1);

	return res;
}
Esempio n. 4
0
/*! \internal
 * \brief cmp format attributes using an interface
 */
static enum ast_format_cmp_res format_cmp_helper(const struct ast_format *format1, const struct ast_format *format2)
{
	enum ast_format_cmp_res res = AST_FORMAT_CMP_EQUAL;
	struct interface_ao2_wrapper *wrapper;

	if (!(wrapper = find_interface(format1))) {
		return res;
	}

	ao2_rdlock(wrapper);
	if (!wrapper->interface || !wrapper->interface->format_attr_cmp) {
		ao2_unlock(wrapper);
		ao2_ref(wrapper, -1);
		return res;
	}

	res = wrapper->interface->format_attr_cmp(&format1->fattr, &format2->fattr);

	ao2_unlock(wrapper);
	ao2_ref(wrapper, -1);

	return res;
}
Esempio n. 5
0
int ast_format_get_value(const struct ast_format *format, int key, void *value)
{
	int res = 0;
	struct interface_ao2_wrapper *wrapper;

	if (!(wrapper = find_interface(format))) {
		return -1;
	}
	ao2_rdlock(wrapper);
	if (!wrapper->interface ||
		!wrapper->interface->format_attr_get_val) {

		ao2_unlock(wrapper);
		ao2_ref(wrapper, -1);
		return -1;
	}

	res = wrapper->interface->format_attr_get_val(&format->fattr, key, value);

	ao2_unlock(wrapper);
	ao2_ref(wrapper, -1);

	return res;
}
Esempio n. 6
0
static char *cli_show_tasks(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	struct ao2_iterator i;
	struct ast_sip_sched_task *schtd;
	const char *log_format = ast_logger_get_dateformat();
	struct ast_tm tm;
	char queued[32];
	char last_start[32];
	char last_end[32];
	int datelen;
	struct timeval now = ast_tvnow();
	const char *separator = "======================================";

	switch (cmd) {
	case CLI_INIT:
		e->command = "pjsip show scheduled_tasks";
		e->usage = "Usage: pjsip show scheduled_tasks\n"
		            "      Show all scheduled tasks\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}

	if (a->argc != 3) {
		return CLI_SHOWUSAGE;
	}

	ast_localtime(&now, &tm, NULL);
	datelen = ast_strftime(queued, sizeof(queued), log_format, &tm);

	ast_cli(a->fd, "PJSIP Scheduled Tasks:\n\n");

	ast_cli(a->fd, " %1$-24s %2$-8s %3$-9s %4$-7s  %6$-*5$s  %7$-*5$s  %8$-*5$s\n",
		"Task Name", "Interval", "Times Run", "State",
		datelen, "Queued", "Last Started", "Last Ended");

	ast_cli(a->fd, " %1$-24.24s %2$-8.8s %3$-9.9s %4$-7.7s  %6$-*5$.*5$s  %7$-*5$.*5$s  %8$-*5$.*5$s\n",
		separator, separator, separator, separator,
		datelen, separator, separator, separator);


	ao2_ref(tasks, +1);
	ao2_rdlock(tasks);
	i = ao2_iterator_init(tasks, 0);
	while ((schtd = ao2_iterator_next(&i))) {

		ast_localtime(&schtd->when_queued, &tm, NULL);
		ast_strftime(queued, sizeof(queued), log_format, &tm);

		if (ast_tvzero(schtd->last_start)) {
			strcpy(last_start, "not yet started");
		} else {
			ast_localtime(&schtd->last_start, &tm, NULL);
			ast_strftime(last_start, sizeof(last_start), log_format, &tm);
		}

		if (ast_tvzero(schtd->last_end)) {
			if (ast_tvzero(schtd->last_start)) {
				strcpy(last_end, "not yet started");
			} else {
				strcpy(last_end, "running");
			}
		} else {
			ast_localtime(&schtd->last_end, &tm, NULL);
			ast_strftime(last_end, sizeof(last_end), log_format, &tm);
		}

		ast_cli(a->fd, " %1$-24.24s %2$-8.3f %3$-9d %4$-7s  %6$-*5$s  %7$-*5$s  %8$-*5$s\n",
			schtd->name,
			schtd->interval / 1000.0,
			schtd->run_count,
			schtd->is_running ? "running" : "waiting",
			datelen, queued, last_start, last_end);
		ao2_cleanup(schtd);
	}
	ao2_iterator_destroy(&i);
	ao2_unlock(tasks);
	ao2_ref(tasks, -1);
	ast_cli(a->fd, "\n");

	return CLI_SUCCESS;
}
Esempio n. 7
0
static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
	struct ao2_iterator i;
	struct ast_codec *codec;

	switch (cmd) {
	case CLI_INIT:
		e->command = "core show codecs [audio|video|image|text]";
		e->usage =
			"Usage: core show codecs [audio|video|image|text]\n"
			"       Displays codec mapping\n";
		return NULL;
	case CLI_GENERATE:
		return NULL;
	}

	if ((a->argc < 3) || (a->argc > 4)) {
		return CLI_SHOWUSAGE;
	}

	if (!ast_opt_dont_warn) {
		ast_cli(a->fd, "Disclaimer: this command is for informational purposes only.\n"
				"\tIt does not indicate anything about your configuration.\n");
	}

	ast_cli(a->fd, "%8s %5s %8s %s\n","ID","TYPE","NAME","DESCRIPTION");
	ast_cli(a->fd, "-----------------------------------------------------------------------------------\n");

	ao2_rdlock(codecs);
	i = ao2_iterator_init(codecs, AO2_ITERATOR_DONTLOCK);

	for (; (codec = ao2_iterator_next(&i)); ao2_ref(codec, -1)) {
		if (a->argc == 4) {
			if (!strcasecmp(a->argv[3], "audio")) {
				if (codec->type != AST_MEDIA_TYPE_AUDIO) {
					continue;
				}
			} else if (!strcasecmp(a->argv[3], "video")) {
				if (codec->type != AST_MEDIA_TYPE_VIDEO) {
					continue;
				}
			} else if (!strcasecmp(a->argv[3], "image")) {
				if (codec->type != AST_MEDIA_TYPE_IMAGE) {
					continue;
				}
			} else if (!strcasecmp(a->argv[3], "text")) {
				if (codec->type != AST_MEDIA_TYPE_TEXT) {
					continue;
				}
			} else {
				continue;
			}
		}

		ast_cli(a->fd, "%8u %5s %8s (%s)\n",
			codec->id,
			ast_codec_media_type2str(codec->type),
			codec->name,
			codec->description);
	}

	ao2_iterator_destroy(&i);
	ao2_unlock(codecs);

	return CLI_SUCCESS;
}
Esempio n. 8
0
static struct interface_ao2_wrapper *find_interface(const struct ast_format *format)
{
	struct interface_ao2_wrapper tmp_wrapper = {
		.id = format->id,
	};

	return ao2_find(interfaces, &tmp_wrapper, OBJ_POINTER);
}

static int has_interface(const struct ast_format *format)
{
	struct interface_ao2_wrapper *wrapper;

	wrapper = find_interface(format);
	if (!wrapper) {
		return 0;
	}
	ao2_ref(wrapper, -1);
	return 1;
}

int ast_format_sdp_parse(struct ast_format *format, const char *attributes)
{
	struct interface_ao2_wrapper *wrapper;
	int res;

	if (!(wrapper = find_interface(format))) {
		return 0;
	}

	ao2_rdlock(wrapper);
	if (!(wrapper->interface || !wrapper->interface->format_attr_sdp_parse)) {
		ao2_unlock(wrapper);
		ao2_ref(wrapper, -1);
		return 0;
	}

	res = wrapper->interface->format_attr_sdp_parse(&format->fattr, attributes);

	ao2_unlock(wrapper);
	ao2_ref(wrapper, -1);

	return res;
}

void ast_format_sdp_generate(const struct ast_format *format, unsigned int payload, struct ast_str **str)
{
	struct interface_ao2_wrapper *wrapper;

	if (!(wrapper = find_interface(format))) {
		return;
	}

	ao2_rdlock(wrapper);
	if (!(wrapper->interface || !wrapper->interface->format_attr_sdp_generate)) {
		ao2_unlock(wrapper);
		ao2_ref(wrapper, -1);
		return;
	}

	wrapper->interface->format_attr_sdp_generate(&format->fattr, payload, str);

	ao2_unlock(wrapper);
	ao2_ref(wrapper, -1);
}

/*! \internal
 * \brief set format attributes using an interface
 */
static int format_set_helper(struct ast_format *format, va_list ap)
{
	struct interface_ao2_wrapper *wrapper;

	if (!(wrapper = find_interface(format))) {
		ast_log(LOG_WARNING, "Could not find format interface to set.\n");
		return -1;
	}

	ao2_rdlock(wrapper);
	if (!wrapper->interface || !wrapper->interface->format_attr_set) {
		ao2_unlock(wrapper);
		ao2_ref(wrapper, -1);
		return -1;
	}

	wrapper->interface->format_attr_set(&format->fattr, ap);

	ao2_unlock(wrapper);
	ao2_ref(wrapper, -1);

	return 0;
}

struct ast_format *ast_format_append(struct ast_format *format, ... )
{
	va_list ap;
	va_start(ap, format);
	format_set_helper(format, ap);
	va_end(ap);

	return format;
}