From 809f515013da012b5a370095cbbf7cd0d2b89f4a Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sun, 21 Jun 2020 21:19:36 +0900 Subject: [PATCH] ctl: add an API to retrieve current version of protocol in control interface Signed-off-by: Takashi Sakamoto --- src/ctl/alsactl.map | 1 + src/ctl/card.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/ctl/card.h | 4 ++++ tests/alsactl-card | 1 + 4 files changed, 49 insertions(+) diff --git a/src/ctl/alsactl.map b/src/ctl/alsactl.map index 396eafd..e5989f5 100644 --- a/src/ctl/alsactl.map +++ b/src/ctl/alsactl.map @@ -14,6 +14,7 @@ ALSA_GOBJECT_0_0_0 { "alsactl_card_get_type"; "alsactl_card_new"; "alsactl_card_open"; + "alsactl_card_get_protocol_version"; "alsactl_card_get_info"; "alsactl_card_get_elem_id_list"; "alsactl_card_lock_elem"; diff --git a/src/ctl/card.c b/src/ctl/card.c index 5324da1..0a49fbb 100644 --- a/src/ctl/card.c +++ b/src/ctl/card.c @@ -26,6 +26,7 @@ struct _ALSACtlCardPrivate { int fd; char *devnode; gint subscribers; + guint16 proto_ver_triplet[3]; }; G_DEFINE_TYPE_WITH_PRIVATE(ALSACtlCard, alsactl_card, G_TYPE_OBJECT) @@ -179,6 +180,7 @@ void alsactl_card_open(ALSACtlCard *self, guint card_id, gint open_flag, { ALSACtlCardPrivate *priv; char *devnode; + int proto_ver; g_return_if_fail(ALSACTL_IS_CARD(self)); priv = alsactl_card_get_instance_private(self); @@ -195,7 +197,48 @@ void alsactl_card_open(ALSACtlCard *self, guint card_id, gint open_flag, return; } + // Remember the version of protocol currently used. + if (ioctl(priv->fd, SNDRV_CTL_IOCTL_PVERSION, &proto_ver) < 0) { + generate_error(error, errno); + close(priv->fd); + priv->fd = -1; + g_free(devnode); + return; + } + priv->devnode = devnode; + priv->proto_ver_triplet[0] = SNDRV_PROTOCOL_MAJOR(proto_ver); + priv->proto_ver_triplet[1] = SNDRV_PROTOCOL_MINOR(proto_ver); + priv->proto_ver_triplet[2] = SNDRV_PROTOCOL_MICRO(proto_ver); +} + +/** + * alsactl_card_get_protocol_version: + * @self: A #ALSACtlCard. + * @proto_ver_triplet: (array fixed-size=3)(out)(transfer none): The version of + * protocol currently used. + * @error: A #GError. + * + * Get the version of control protocol currently used. The version is + * represented as the array with three elements; major, minor, and micro version + * in the order. The length of major version is 16 bit, the length of minor + * and micro version is 8 bit each. + */ +void alsactl_card_get_protocol_version(ALSACtlCard *self, + const guint16 *proto_ver_triplet[3], + GError **error) +{ + ALSACtlCardPrivate *priv; + + g_return_if_fail(ALSACTL_IS_CARD(self)); + priv = alsactl_card_get_instance_private(self); + + if (priv->fd < 0) { + generate_error(error, ENXIO); + return; + } + + *proto_ver_triplet = (const guint16 *)priv->proto_ver_triplet; } /** diff --git a/src/ctl/card.h b/src/ctl/card.h index 08694d3..d26b464 100644 --- a/src/ctl/card.h +++ b/src/ctl/card.h @@ -79,6 +79,10 @@ ALSACtlCard *alsactl_card_new(); void alsactl_card_open(ALSACtlCard *self, guint card_id, gint open_flag, GError **error); +void alsactl_card_get_protocol_version(ALSACtlCard *self, + const guint16 *proto_ver_triplet[3], + GError **error); + void alsactl_card_get_info(ALSACtlCard *self, ALSACtlCardInfo **card_info, GError **error); diff --git a/tests/alsactl-card b/tests/alsactl-card index e1e089c..e9d7702 100644 --- a/tests/alsactl-card +++ b/tests/alsactl-card @@ -17,6 +17,7 @@ props = ( methods = ( 'new', 'open', + 'get_protocol_version', 'get_info', 'get_elem_id_list', 'lock_elem', -- 2.47.3