From e61d385993ac3127fee2716e2a2db18acbf153f5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 18 May 2005 10:47:52 +0000 Subject: [PATCH] Add protocl version check - Added protocl version check. The caller of snd_pcm_{io|ext}plug_create() must fill version field with SND_PCM_{IO|EXT}PLUG_VERSION beforehand. - Added poll_descriptors and poll_descriptors_count callbacks for ioplug. --- include/pcm_extplug.h | 15 +++++++++++++++ include/pcm_ioplug.h | 23 +++++++++++++++++++++++ src/pcm/pcm_extplug.c | 7 +++++++ src/pcm/pcm_ioplug.c | 36 +++++++++++++++++++++++++++++++++++- 4 files changed, 80 insertions(+), 1 deletion(-) diff --git a/include/pcm_extplug.h b/include/pcm_extplug.h index 85c9e29b..566c18ef 100644 --- a/include/pcm_extplug.h +++ b/include/pcm_extplug.h @@ -32,8 +32,23 @@ enum { typedef struct snd_pcm_extplug snd_pcm_extplug_t; typedef struct snd_pcm_extplug_callback snd_pcm_extplug_callback_t; +/** + * Protocol version + */ +#define SND_PCM_EXTPLUG_VERSION_MAJOR 1 +#define SND_PCM_EXTPLUG_VERSION_MINOR 0 +#define SND_PCM_EXTPLUG_VERSION_TINY 0 +#define SND_PCM_EXTPLUG_VERSION ((SND_PCM_EXTPLUG_VERSION_MAJOR<<16) |\ + (SND_PCM_EXTPLUG_VERSION_MINOR<<8) |\ + (SND_PCM_EXTPLUG_VERSION_TINY)) + /** handle of extplug */ struct snd_pcm_extplug { + /** + * protocol version; SND_PCM_EXTPLUG_VERSION must be filled here + * before calling #snd_pcm_extplug_create() + */ + unsigned int version; /** * name of this plugin; must be filled before calling #snd_pcm_extplug_create() */ diff --git a/include/pcm_ioplug.h b/include/pcm_ioplug.h index b4781ac0..5dee834d 100644 --- a/include/pcm_ioplug.h +++ b/include/pcm_ioplug.h @@ -42,8 +42,23 @@ typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t; */ #define SND_PCM_IOPLUG_FLAG_LISTED (1<<0) /* list up this PCM */ +/** + * Protocol version + */ +#define SND_PCM_IOPLUG_VERSION_MAJOR 1 +#define SND_PCM_IOPLUG_VERSION_MINOR 0 +#define SND_PCM_IOPLUG_VERSION_TINY 0 +#define SND_PCM_IOPLUG_VERSION ((SND_PCM_IOPLUG_VERSION_MAJOR<<16) |\ + (SND_PCM_IOPLUG_VERSION_MINOR<<8) |\ + (SND_PCM_IOPLUG_VERSION_TINY)) + /** handle of ioplug */ struct snd_pcm_ioplug { + /** + * protocol version; SND_PCM_IOPLUG_VERSION must be filled here + * before calling #snd_pcm_ioplug_create() + */ + unsigned int version; /** * name of this plugin; must be filled before calling #snd_pcm_ioplug_create() */ @@ -132,6 +147,14 @@ struct snd_pcm_ioplug_callback { * resume; optional */ int (*resume)(snd_pcm_ioplug_t *io); + /** + * poll descriptors count; optional + */ + int (*poll_descriptors_count)(snd_pcm_ioplug_t *io); + /** + * poll descriptors; optional + */ + int (*poll_descriptors)(snd_pcm_ioplug_t *io, struct pollfd *pfd, unsigned int space); /** * mangle poll events; optional */ diff --git a/src/pcm/pcm_extplug.c b/src/pcm/pcm_extplug.c index 42628c45..f32a40c6 100644 --- a/src/pcm/pcm_extplug.c +++ b/src/pcm/pcm_extplug.c @@ -423,6 +423,8 @@ static snd_pcm_ops_t snd_pcm_extplug_ops = { .dump = snd_pcm_extplug_dump, .nonblock = snd_pcm_generic_nonblock, .async = snd_pcm_generic_async, + .poll_descriptors_count = snd_pcm_generic_poll_descriptors_count, + .poll_descriptors = snd_pcm_generic_poll_descriptors, .poll_revents = snd_pcm_generic_poll_revents, .mmap = snd_pcm_generic_mmap, .munmap = snd_pcm_generic_munmap, @@ -478,6 +480,11 @@ int snd_pcm_extplug_create(snd_pcm_extplug_t *extplug, const char *name, assert(extplug->callback->transfer); assert(slave_conf); + if (extplug->version != SND_PCM_EXTPLUG_VERSION) { + SNDERR("extplug: Plugin version mismatch\n"); + return -ENXIO; + } + err = snd_pcm_slave_conf(root, slave_conf, &sconf, 0); if (err < 0) return err; diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c index 415e7e0a..2704131e 100644 --- a/src/pcm/pcm_ioplug.c +++ b/src/pcm/pcm_ioplug.c @@ -238,7 +238,7 @@ static int snd_pcm_ioplug_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) int change = 0, change1, change2, err; ioplug_priv_t *io = pcm->private_data; struct snd_ext_parm *p; - int i; + unsigned int i; /* access, format */ for (i = SND_PCM_IOPLUG_HW_ACCESS; i <= SND_PCM_IOPLUG_HW_FORMAT; i++) { @@ -616,6 +616,33 @@ static int snd_pcm_ioplug_nonblock(snd_pcm_t *pcm, int nonblock) return 0; } +static int snd_pcm_ioplug_poll_descriptors_count(snd_pcm_t *pcm) +{ + ioplug_priv_t *io = pcm->private_data; + + if (io->data->callback->poll_descriptors_count) + return io->data->callback->poll_descriptors_count(io->data); + else + return 1; +} + +static int snd_pcm_ioplug_poll_descriptors(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int space) +{ + ioplug_priv_t *io = pcm->private_data; + + if (io->data->callback->poll_descriptors) + return io->data->callback->poll_descriptors(io->data, pfds, space); + if (pcm->poll_fd < 0) + return -EIO; + if (space >= 1 && pfds) { + pfds->fd = pcm->poll_fd; + pfds->events = pcm->poll_events | POLLERR | POLLNVAL; + } else { + return 0; + } + return 1; +} + static int snd_pcm_ioplug_poll_revents(snd_pcm_t *pcm, struct pollfd *pfds, unsigned int nfds, unsigned short *revents) { ioplug_priv_t *io = pcm->private_data; @@ -685,6 +712,8 @@ static snd_pcm_ops_t snd_pcm_ioplug_ops = { .close = snd_pcm_ioplug_close, .nonblock = snd_pcm_ioplug_nonblock, .async = snd_pcm_ioplug_async, + .poll_descriptors_count = snd_pcm_ioplug_poll_descriptors_count, + .poll_descriptors = snd_pcm_ioplug_poll_descriptors, .poll_revents = snd_pcm_ioplug_poll_revents, .info = snd_pcm_ioplug_info, .hw_refine = snd_pcm_ioplug_hw_refine, @@ -764,6 +793,11 @@ int snd_pcm_ioplug_create(snd_pcm_ioplug_t *ioplug, const char *name, ioplug->callback->stop && ioplug->callback->pointer); + if (ioplug->version != SND_PCM_IOPLUG_VERSION) { + SNDERR("ioplug: Plugin version mismatch\n"); + return -ENXIO; + } + io = calloc(1, sizeof(*io)); if (! io) return -ENOMEM; -- 2.47.1