sndiod: Propagate the controls' display string to clients.
authorratchov <ratchov@openbsd.org>
Fri, 24 May 2024 15:16:09 +0000 (15:16 +0000)
committerratchov <ratchov@openbsd.org>
Fri, 24 May 2024 15:16:09 +0000 (15:16 +0000)
with help from edd@ and armani@

lib/libsndio/amsg.h
lib/libsndio/sioctl_aucat.c
usr.bin/sndiod/dev.c
usr.bin/sndiod/dev.h
usr.bin/sndiod/dev_sioctl.c
usr.bin/sndiod/opt.c
usr.bin/sndiod/sock.c
usr.bin/sndiod/sock.h

index 6d1a185..331f811 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: amsg.h,v 1.15 2022/04/29 08:30:48 ratchov Exp $       */
+/*     $OpenBSD: amsg.h,v 1.16 2024/05/24 15:16:09 ratchov Exp $       */
 /*
  * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
  *
  * limits
  */
 #define AMSG_CTL_NAMEMAX       16      /* max name length */
+#define AMSG_CTL_DISPLAYMAX    32      /* max display string length */
+
+/*
+ * Size of the struct amsg_ctl_desc expected by clients
+ * using the AMSG_CTLSUB_OLD request
+ */
+#define AMSG_OLD_DESC_SIZE     92
 
 /*
  * WARNING: since the protocol may be simultaneously used by static
@@ -69,9 +76,10 @@ struct amsg {
 #define AMSG_HELLO     10      /* say hello, check versions and so ... */
 #define AMSG_BYE       11      /* ask server to drop connection */
 #define AMSG_AUTH      12      /* send authentication cookie */
-#define AMSG_CTLSUB    13      /* ondesc/onctl subscription */
+#define AMSG_CTLSUB_OLD        13      /* amsg_ctl_desc with no "display" attribute */
 #define AMSG_CTLSET    14      /* set control value */
 #define AMSG_CTLSYNC   15      /* end of controls descriptions */
+#define AMSG_CTLSUB    16      /* ondesc/onctl subscription */
        uint32_t cmd;
        uint32_t __pad;
        union {
@@ -151,7 +159,8 @@ struct amsg_ctl_desc {
        uint16_t addr;                  /* control address */
        uint16_t maxval;
        uint16_t curval;
-       uint32_t __pad2[3];
+       uint32_t __pad2[4];
+       char display[AMSG_CTL_DISPLAYMAX];      /* free-format hint */
 };
 
 /*
index 241dcb7..e912e45 100644 (file)
@@ -87,7 +87,7 @@ sioctl_aucat_rdata(struct sioctl_aucat_hdl *hdl)
                        strlcpy(desc.node1.name, c->node1.name, SIOCTL_NAMEMAX);
                        desc.node1.unit = (int16_t)ntohs(c->node1.unit);
                        strlcpy(desc.func, c->func, SIOCTL_NAMEMAX);
-                       strlcpy(desc.display, "", SIOCTL_DISPLAYMAX);
+                       strlcpy(desc.display, c->display, SIOCTL_DISPLAYMAX);
                        desc.type = c->type;
                        desc.addr = ntohs(c->addr);
                        desc.maxval = ntohs(c->maxval);
index eaa29fb..b96d70e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dev.c,v 1.114 2024/05/24 15:01:53 ratchov Exp $       */
+/*     $OpenBSD: dev.c,v 1.115 2024/05/24 15:16:09 ratchov Exp $       */
 /*
  * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
  *
@@ -1776,7 +1776,7 @@ slot_new(struct opt *opt, unsigned int id, char *who,
        s->opt = opt;
        slot_ctlname(s, ctl_name, CTL_NAMEMAX);
        ctl_new(CTL_SLOT_LEVEL, s, NULL,
-           CTL_NUM, "app", ctl_name, -1, "level",
+           CTL_NUM, "", "app", ctl_name, -1, "level",
            NULL, -1, 127, s->vol);
 
 found:
@@ -2413,6 +2413,11 @@ ctl_log(struct ctl *c)
        default:
                log_puts("unknown");
        }
+       if (c->display[0] != 0) {
+               log_puts(" (");
+               log_puts(c->display);
+               log_puts(")");
+       }
 }
 
 int
@@ -2475,7 +2480,7 @@ ctl_setval(struct ctl *c, int val)
  */
 struct ctl *
 ctl_new(int scope, void *arg0, void *arg1,
-    int type, char *gstr,
+    int type, char *display, char *gstr,
     char *str0, int unit0, char *func,
     char *str1, int unit1, int maxval, int val)
 {
@@ -2499,6 +2504,7 @@ ctl_new(int scope, void *arg0, void *arg1,
        c->type = type;
        strlcpy(c->func, func, CTL_NAMEMAX);
        strlcpy(c->group, gstr, CTL_NAMEMAX);
+       strlcpy(c->display, display, CTL_DISPLAYMAX);
        strlcpy(c->node0.name, str0, CTL_NAMEMAX);
        c->node0.unit = unit0;
        if (c->type == CTL_VEC || c->type == CTL_LIST || c->type == CTL_SEL) {
@@ -2644,11 +2650,32 @@ ctl_del(int scope, void *arg0, void *arg1)
        }
 }
 
+char *
+dev_getdisplay(struct dev *d)
+{
+       struct ctl *c;
+       char *display;
+
+       display = "";
+       for (c = ctl_list; c != NULL; c = c->next) {
+               if (c->scope == CTL_HW &&
+                   c->u.hw.dev == d &&
+                   c->type == CTL_SEL &&
+                   strcmp(c->group, d->name) == 0 &&
+                   strcmp(c->node0.name, "server") == 0 &&
+                   strcmp(c->func, "device") == 0 &&
+                   c->curval == 1)
+                       display = c->display;
+       }
+       return display;
+}
+
 void
 dev_ctlsync(struct dev *d)
 {
        struct ctl *c;
        struct ctlslot *s;
+       const char *display;
        int found, i;
 
        found = 0;
@@ -2676,10 +2703,23 @@ dev_ctlsync(struct dev *d)
                }
                d->master_enabled = 1;
                ctl_new(CTL_DEV_MASTER, d, NULL,
-                   CTL_NUM, d->name, "output", -1, "level",
+                   CTL_NUM, "", d->name, "output", -1, "level",
                    NULL, -1, 127, d->master);
        }
 
+       /*
+        * if the hardware's server.device changed, update the display name
+        */
+       display = dev_getdisplay(d);
+       for (c = ctl_list; c != NULL; c = c->next) {
+               if (c->scope != CTL_OPT_DEV ||
+                   c->u.opt_dev.dev != d ||
+                   strcmp(c->display, display) == 0)
+                       continue;
+               strlcpy(c->display, display, CTL_DISPLAYMAX);
+               c->desc_mask = ~0;
+       }
+
        for (s = ctlslot_array, i = 0; i < DEV_NCTLSLOT; i++, s++) {
                if (s->ops == NULL)
                        continue;
index 6e7cdf6..49a085b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dev.h,v 1.45 2024/05/19 00:05:43 jsg Exp $    */
+/*     $OpenBSD: dev.h,v 1.46 2024/05/24 15:16:09 ratchov Exp $        */
 /*
  * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
  *
@@ -155,9 +155,11 @@ struct ctl {
        } u;
 
        unsigned int addr;              /* slot side control address */
-#define CTL_NAMEMAX    16              /* max name length */
+#define CTL_NAMEMAX    12              /* max name length */
+#define CTL_DISPLAYMAX 24              /* max name length */
        char func[CTL_NAMEMAX];         /* parameter function name */
        char group[CTL_NAMEMAX];        /* group aka namespace */
+       char display[CTL_DISPLAYMAX];   /* free-format hint */
        struct ctl_node {
                char name[CTL_NAMEMAX]; /* stream name */
                int unit;
@@ -350,7 +352,7 @@ void slot_detach(struct slot *);
  */
 
 struct ctl *ctl_new(int, void *, void *,
-    int, char *, char *, int, char *, char *, int, int, int);
+    int, char *, char *, char *, int, char *, char *, int, int, int);
 int ctl_del(int, void *, void *);
 void ctl_log(struct ctl *);
 int ctl_setval(struct ctl *c, int val);
@@ -365,6 +367,7 @@ int ctlslot_visible(struct ctlslot *, struct ctl *);
 struct ctl *ctlslot_lookup(struct ctlslot *, int);
 void ctlslot_update(struct ctlslot *);
 
+char *dev_getdisplay(struct dev *);
 void dev_ctlsync(struct dev *);
 
 #endif /* !defined(DEV_H) */
index 7df7dce..6ec3e7a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dev_sioctl.c,v 1.9 2024/05/24 15:00:15 ratchov Exp $  */
+/*     $OpenBSD: dev_sioctl.c,v 1.10 2024/05/24 15:16:09 ratchov Exp $ */
 /*
  * Copyright (c) 2014-2020 Alexandre Ratchov <alex@caoua.org>
  *
@@ -70,7 +70,7 @@ dev_sioctl_ondesc(void *arg, struct sioctl_desc *desc, int val)
        }
 
        ctl_new(CTL_HW, d, &desc->addr,
-           desc->type, group,
+           desc->type, desc->display, group,
            desc->node0.name, desc->node0.unit, desc->func,
            desc->node1.name, desc->node1.unit, desc->maxval, val);
 }
index 17d2456..1954166 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: opt.c,v 1.10 2024/04/22 10:42:04 ratchov Exp $        */
+/*     $OpenBSD: opt.c,v 1.11 2024/05/24 15:16:09 ratchov Exp $        */
 /*
  * Copyright (c) 2008-2011 Alexandre Ratchov <alex@caoua.org>
  *
@@ -351,7 +351,7 @@ opt_init(struct opt *o)
        if (strcmp(o->name, o->dev->name) != 0) {
                for (d = dev_list; d != NULL; d = d->next) {
                        ctl_new(CTL_OPT_DEV, o, d,
-                           CTL_SEL, o->name, "server", -1, "device",
+                           CTL_SEL, "", o->name, "server", -1, "device",
                            d->name, -1, 1, o->dev == d);
                }
        }
index 7b2fe5d..86a78cb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sock.c,v 1.48 2024/05/24 15:03:12 ratchov Exp $       */
+/*     $OpenBSD: sock.c,v 1.49 2024/05/24 15:16:09 ratchov Exp $       */
 /*
  * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
  *
@@ -1284,6 +1284,7 @@ sock_execmsg(struct sock *f)
                dev_midi_vol(s->opt->dev, s);
                ctl_onval(CTL_SLOT_LEVEL, s, NULL, ctl);
                break;
+       case AMSG_CTLSUB_OLD:
        case AMSG_CTLSUB:
 #ifdef DEBUG
                if (log_level >= 3) {
@@ -1316,6 +1317,9 @@ sock_execmsg(struct sock *f)
                                }
                                f->ctlops |= SOCK_CTLDESC;
                                f->ctlsyncpending = 1;
+                               f->ctl_desc_size = (cmd == AMSG_CTLSUB) ?
+                                   sizeof(struct amsg_ctl_desc) :
+                                   AMSG_OLD_DESC_SIZE;
                        }
                } else
                        f->ctlops &= ~SOCK_CTLDESC;
@@ -1613,7 +1617,7 @@ sock_buildmsg(struct sock *f)
                                pc = &c->next;
                                continue;
                        }
-                       if (size + sizeof(struct amsg_ctl_desc) > SOCK_CTLDESC_SIZE)
+                       if (size + f->ctl_desc_size > SOCK_CTLDESC_SIZE)
                                break;
                        desc = (struct amsg_ctl_desc *)(f->ctldesc + size);
                        c->desc_mask &= ~mask;
@@ -1632,7 +1636,14 @@ sock_buildmsg(struct sock *f)
                        desc->addr = htons(c->addr);
                        desc->maxval = htons(c->maxval);
                        desc->curval = htons(c->curval);
-                       size += sizeof(struct amsg_ctl_desc);
+
+                       /* old clients don't have the 'display' member */
+                       if (f->ctl_desc_size >= offsetof(struct amsg_ctl_desc,
+                               display) + AMSG_CTL_DISPLAYMAX) {
+                               strlcpy(desc->display, c->display, AMSG_CTL_DISPLAYMAX);
+                       }
+
+                       size += f->ctl_desc_size;
 
                        /* if this is a deleted entry unref it */
                        if (type == CTL_NONE) {
index 682be1d..6fee8aa 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sock.h,v 1.8 2024/05/24 15:03:12 ratchov Exp $        */
+/*     $OpenBSD: sock.h,v 1.9 2024/05/24 15:16:09 ratchov Exp $        */
 /*
  * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
  *
@@ -60,6 +60,7 @@ struct sock {
        struct port *port;              /* midi port */
        struct ctlslot *ctlslot;
        unsigned char *ctldesc;         /* temporary buffer */
+       size_t ctl_desc_size;           /* size of client amsg_ctl_desc */
 #define SOCK_CTLDESC   1               /* dump desc and send changes */
 #define SOCK_CTLVAL    2               /* send value changes */
        unsigned int ctlops;            /* bitmap of above */