]> git.alsa-project.org Git - alsa-gobject.git/commitdiff
ctl: card: add APIs to write/read/command Type-Length-Value data for element
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Mon, 18 Nov 2019 04:22:44 +0000 (13:22 +0900)
committerTakashi Sakamoto <o-takashi@sakamocchi.jp>
Thu, 12 Dec 2019 05:29:12 +0000 (14:29 +0900)
src/ctl/alsactl.map
src/ctl/card.c
src/ctl/card.h
tests/alsactl-card

index cb85df7846cebde908e170655a459117687eaa2c..44585d66a0d1f4e158fcc8e6fc5876425e353089 100644 (file)
@@ -18,6 +18,9 @@ ALSA_GOBJECT_0_0_0 {
     "alsactl_card_get_elem_id_list";
     "alsactl_card_lock_elem";
     "alsactl_card_get_elem_info";
+    "alsactl_card_write_elem_tlv";
+    "alsactl_card_read_elem_tlv";
+    "alsactl_card_command_elem_tlv";
 
     "alsactl_card_info_get_type";
 
index 061ab547a903cfb648c27e4878342395fac17169..e0b47742a5fe2918a7e69cbd006c6f55b9e92a79 100644 (file)
@@ -339,3 +339,142 @@ void alsactl_card_get_elem_info(ALSACtlCard *self, const ALSACtlElemId *elem_id,
     ctl_elem_info_refer_private(ALSACTL_ELEM_INFO(*elem_info), &info_ptr);
     *info_ptr = info;
 }
+
+/**
+ * alsactl_card_write_elem_tlv:
+ * @self: A #ALSACtlCard.
+ * @elem_id: A #ALSACtlElemId.
+ * @container: (array length=container_count): The array with qudalets for
+ *             Type-Length-Value data.
+ * @container_count: The number of quadlets in the container.
+ * @error: A #GError.
+ */
+void alsactl_card_write_elem_tlv(ALSACtlCard *self,
+                            const ALSACtlElemId *elem_id,
+                            const gint32 *container, gsize container_count,
+                            GError **error)
+{
+    ALSACtlCardPrivate *priv;
+    struct snd_ctl_tlv *packet;
+    size_t container_size;
+
+    g_return_if_fail(ALSACTL_IS_CARD(self));
+    g_return_if_fail(elem_id != NULL);
+    priv = alsactl_card_get_instance_private(self);
+
+    // At least two quadlets should be included for type and length.
+    if (container == NULL || container_count < 2) {
+        generate_error(error, EINVAL);
+        return;
+    }
+    container_size = container_count * sizeof(*container);
+
+    packet = g_malloc0(sizeof(*packet) + container_size);
+    if (packet == NULL) {
+        generate_error(error, ENOMEM);
+        return;
+    }
+
+    packet->numid = elem_id->numid;
+    packet->length = container_size;
+    memcpy(packet->tlv, container, container_size);
+
+    if (ioctl(priv->fd, SNDRV_CTL_IOCTL_TLV_WRITE, packet) < 0)
+        generate_error(error, errno);
+
+    g_free(packet);
+}
+
+/**
+ * alsactl_card_read_elem_tlv:
+ * @self: A #ALSACtlCard.
+ * @elem_id: A #ALSACtlElemId.
+ * @container: (array length=container_count)(inout): The array with qudalets
+ *             for Type-Length-Value data.
+ * @container_count: The number of quadlets in the container.
+ * @error: A #GError.
+ */
+void alsactl_card_read_elem_tlv(ALSACtlCard *self, const ALSACtlElemId *elem_id,
+                            gint32 *const *container, gsize *container_count,
+                            GError **error)
+{
+    ALSACtlCardPrivate *priv;
+    struct snd_ctl_tlv *packet;
+    size_t container_size;
+
+    g_return_if_fail(ALSACTL_IS_CARD(self));
+    g_return_if_fail(elem_id != NULL);
+    priv = alsactl_card_get_instance_private(self);
+
+    // At least two quadlets should be included for type and length.
+    if (*container == NULL || *container_count < 2) {
+        generate_error(error, EINVAL);
+        return;
+    }
+    container_size = *container_count * sizeof(**container);
+
+    packet = g_malloc0(sizeof(*packet) + container_size);
+    if (packet == NULL) {
+        generate_error(error, ENOMEM);
+        return;
+    }
+
+    packet->numid = elem_id->numid;
+    packet->length = container_size;
+
+    if (ioctl(priv->fd, SNDRV_CTL_IOCTL_TLV_READ, packet) < 0)
+        generate_error(error, errno);
+
+    memcpy(*container, packet->tlv, packet->length);
+    *container_count = packet->length / sizeof(**container);
+
+    g_free(packet);
+}
+
+/**
+ * alsactl_card_command_elem_tlv:
+ * @self: A #ALSACtlCard.
+ * @elem_id: A #ALSACtlElemId.
+ * @container: (array length=container_count)(inout): The array with qudalets
+ *             for Type-Length-Value data.
+ * @container_count: The number of quadlets in the container.
+ * @error: A #GError.
+ */
+void alsactl_card_command_elem_tlv(ALSACtlCard *self,
+                            const ALSACtlElemId *elem_id,
+                            gint32 *const *container, gsize *container_count,
+                            GError **error)
+{
+    ALSACtlCardPrivate *priv;
+    struct snd_ctl_tlv *packet;
+    size_t container_size;
+
+    g_return_if_fail(ALSACTL_IS_CARD(self));
+    g_return_if_fail(elem_id != NULL);
+    priv = alsactl_card_get_instance_private(self);
+
+    // At least two quadlets should be included for type and length.
+    if (*container == NULL || *container_count < 2) {
+        generate_error(error, EINVAL);
+        return;
+    }
+    container_size = *container_count * sizeof(**container);
+
+    packet = g_malloc0(sizeof(*packet) + container_size);
+    if (packet == NULL) {
+        generate_error(error, ENOMEM);
+        return;
+    }
+
+    packet->numid = elem_id->numid;
+    packet->length = container_size;
+    memcpy(packet->tlv, *container, container_size);
+
+    if (ioctl(priv->fd, SNDRV_CTL_IOCTL_TLV_COMMAND, packet) < 0)
+        generate_error(error, errno);
+
+    memcpy(*container, packet->tlv, packet->length);
+    *container_count = packet->length / sizeof(**container);
+
+    g_free(packet);
+}
index 8dacecb5f125fe5e87ea4aa136be92b43f44a0a1..c4c56818c15a748f93f6230984d370526243d164 100644 (file)
@@ -65,6 +65,18 @@ void alsactl_card_lock_elem(ALSACtlCard *self, const ALSACtlElemId *elem_id,
 void alsactl_card_get_elem_info(ALSACtlCard *self, const ALSACtlElemId *elem_id,
                                 ALSACtlElemInfo **elem_info, GError **error);
 
+void alsactl_card_write_elem_tlv(ALSACtlCard *self,
+                            const ALSACtlElemId *elem_id,
+                            const gint32 *container, gsize container_count,
+                            GError **error);
+void alsactl_card_read_elem_tlv(ALSACtlCard *self, const ALSACtlElemId *elem_id,
+                            gint32 *const *container, gsize *container_count,
+                            GError **error);
+void alsactl_card_command_elem_tlv(ALSACtlCard *self,
+                            const ALSACtlElemId *elem_id,
+                            gint32 *const *container, gsize *container_count,
+                            GError **error);
+
 G_END_DECLS
 
 #endif
index 12ca1c92083df79b89da36870edebfd206f422cb..83b93ee6065c99d1dc239e50d39086c0c843e200 100644 (file)
@@ -20,6 +20,9 @@ methods = (
     'get_elem_id_list',
     'lock_elem',
     'get_elem_info',
+    'write_elem_tlv',
+    'read_elem_tlv',
+    'command_elem_tlv',
 )
 signals = ()