1*4d8b188fSratchov /* $OpenBSD: amsg.h,v 1.16 2024/05/24 15:16:09 ratchov Exp $ */ 2509f01d9Sratchov /* 3509f01d9Sratchov * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> 4509f01d9Sratchov * 5509f01d9Sratchov * Permission to use, copy, modify, and distribute this software for any 6509f01d9Sratchov * purpose with or without fee is hereby granted, provided that the above 7509f01d9Sratchov * copyright notice and this permission notice appear in all copies. 8509f01d9Sratchov * 9509f01d9Sratchov * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10509f01d9Sratchov * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11509f01d9Sratchov * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12509f01d9Sratchov * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13509f01d9Sratchov * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14509f01d9Sratchov * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15509f01d9Sratchov * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16509f01d9Sratchov */ 17509f01d9Sratchov #ifndef AMSG_H 18509f01d9Sratchov #define AMSG_H 19509f01d9Sratchov 20509f01d9Sratchov #include <stdint.h> 21509f01d9Sratchov 22509f01d9Sratchov /* 23000d99eaSratchov * unix-domain socket name is: 24000d99eaSratchov * 25000d99eaSratchov * DIR [ '-' UID ] '/' FILE UNIT 26000d99eaSratchov * 27f259df27Sratchov * example: "/tmp/sndio-1000/sock0" 28000d99eaSratchov * 29509f01d9Sratchov */ 30f259df27Sratchov #define SOCKPATH_DIR "/tmp/sndio" 31f259df27Sratchov #define SOCKPATH_FILE "sock" 32dadd32d9Sratchov #define SOCKPATH_MAX (1 + \ 33dadd32d9Sratchov sizeof(SOCKPATH_DIR) - 1 + \ 34dadd32d9Sratchov sizeof(char) + \ 35dadd32d9Sratchov sizeof(int) * 3 + \ 36dadd32d9Sratchov sizeof(char) + \ 37dadd32d9Sratchov sizeof(SOCKPATH_FILE) - 1 + \ 38dadd32d9Sratchov sizeof(int) * 3) 39000d99eaSratchov 40000d99eaSratchov /* 41000d99eaSratchov * server TCP base port number 42000d99eaSratchov */ 43edc7bd3bSratchov #define AUCAT_PORT 11025 44509f01d9Sratchov 45509f01d9Sratchov /* 46d07fece6Sratchov * limits 47d07fece6Sratchov */ 48d07fece6Sratchov #define AMSG_CTL_NAMEMAX 16 /* max name length */ 49*4d8b188fSratchov #define AMSG_CTL_DISPLAYMAX 32 /* max display string length */ 50*4d8b188fSratchov 51*4d8b188fSratchov /* 52*4d8b188fSratchov * Size of the struct amsg_ctl_desc expected by clients 53*4d8b188fSratchov * using the AMSG_CTLSUB_OLD request 54*4d8b188fSratchov */ 55*4d8b188fSratchov #define AMSG_OLD_DESC_SIZE 92 56d07fece6Sratchov 57d07fece6Sratchov /* 58509f01d9Sratchov * WARNING: since the protocol may be simultaneously used by static 59509f01d9Sratchov * binaries or by different versions of a shared library, we are not 60509f01d9Sratchov * allowed to change the packet binary representation in a backward 61509f01d9Sratchov * incompatible way. 62509f01d9Sratchov * 63509f01d9Sratchov * Especially, make sure the amsg_xxx structures are not larger 64509f01d9Sratchov * than 32 bytes. 65509f01d9Sratchov */ 66509f01d9Sratchov struct amsg { 67509f01d9Sratchov #define AMSG_ACK 0 /* ack for START/STOP */ 68509f01d9Sratchov #define AMSG_GETPAR 1 /* get the current parameters */ 69509f01d9Sratchov #define AMSG_SETPAR 2 /* set the current parameters */ 70509f01d9Sratchov #define AMSG_START 3 /* request the server to start the stream */ 71509f01d9Sratchov #define AMSG_STOP 4 /* request the server to stop the stream */ 72509f01d9Sratchov #define AMSG_DATA 5 /* data block */ 735ffd5747Sratchov #define AMSG_FLOWCTL 6 /* feedback about buffer usage */ 74509f01d9Sratchov #define AMSG_MOVE 7 /* position changed */ 75509f01d9Sratchov #define AMSG_SETVOL 9 /* set volume */ 76509f01d9Sratchov #define AMSG_HELLO 10 /* say hello, check versions and so ... */ 77509f01d9Sratchov #define AMSG_BYE 11 /* ask server to drop connection */ 78509f01d9Sratchov #define AMSG_AUTH 12 /* send authentication cookie */ 79*4d8b188fSratchov #define AMSG_CTLSUB_OLD 13 /* amsg_ctl_desc with no "display" attribute */ 80d07fece6Sratchov #define AMSG_CTLSET 14 /* set control value */ 81d07fece6Sratchov #define AMSG_CTLSYNC 15 /* end of controls descriptions */ 82*4d8b188fSratchov #define AMSG_CTLSUB 16 /* ondesc/onctl subscription */ 83509f01d9Sratchov uint32_t cmd; 84509f01d9Sratchov uint32_t __pad; 85509f01d9Sratchov union { 86509f01d9Sratchov struct amsg_par { 87509f01d9Sratchov uint8_t legacy_mode; /* compat for old libs */ 88509f01d9Sratchov uint8_t xrun; /* one of above */ 89509f01d9Sratchov uint8_t bps; /* bytes per sample */ 90509f01d9Sratchov uint8_t bits; /* actually used bits */ 91509f01d9Sratchov uint8_t msb; /* 1 if MSB justified */ 92509f01d9Sratchov uint8_t le; /* 1 if little endian */ 93509f01d9Sratchov uint8_t sig; /* 1 if signed */ 94509f01d9Sratchov uint8_t __pad1; 95509f01d9Sratchov uint16_t pchan; /* play channels */ 96509f01d9Sratchov uint16_t rchan; /* record channels */ 97509f01d9Sratchov uint32_t rate; /* frames per second */ 98509f01d9Sratchov uint32_t bufsz; /* total buffered frames */ 99509f01d9Sratchov uint32_t round; 100509f01d9Sratchov uint32_t appbufsz; /* client side bufsz */ 101509f01d9Sratchov uint32_t _reserved[1]; /* for future use */ 102509f01d9Sratchov } par; 103509f01d9Sratchov struct amsg_data { 104509f01d9Sratchov #define AMSG_DATAMAX 0x1000 105509f01d9Sratchov uint32_t size; 106509f01d9Sratchov } data; 107ec8a3410Sratchov struct amsg_stop { 108ec8a3410Sratchov uint8_t drain; 109ec8a3410Sratchov } stop; 110509f01d9Sratchov struct amsg_ts { 111509f01d9Sratchov int32_t delta; 112509f01d9Sratchov } ts; 113509f01d9Sratchov struct amsg_vol { 114509f01d9Sratchov uint32_t ctl; 115509f01d9Sratchov } vol; 116509f01d9Sratchov struct amsg_hello { 117509f01d9Sratchov uint16_t mode; /* bitmap of MODE_XXX */ 11807e4e28eSratchov #define AMSG_VERSION 7 119509f01d9Sratchov uint8_t version; /* protocol version */ 12036355b88Sratchov #define AMSG_NODEV 255 121b3956098Sratchov uint8_t devnum; /* device number */ 1222988007fSratchov uint32_t id; /* client id */ 123b3956098Sratchov #define AMSG_OPTMAX 12 124b3956098Sratchov char opt[AMSG_OPTMAX]; /* profile name */ 125509f01d9Sratchov char who[12]; /* hint for leases */ 126509f01d9Sratchov } hello; 127509f01d9Sratchov struct amsg_auth { 128509f01d9Sratchov #define AMSG_COOKIELEN 16 129509f01d9Sratchov uint8_t cookie[AMSG_COOKIELEN]; 130509f01d9Sratchov } auth; 131d07fece6Sratchov struct amsg_ctlsub { 132d07fece6Sratchov uint8_t desc, val; 133d07fece6Sratchov } ctlsub; 134d07fece6Sratchov struct amsg_ctlset { 135d07fece6Sratchov uint16_t addr, val; 136d07fece6Sratchov } ctlset; 137509f01d9Sratchov } u; 138509f01d9Sratchov }; 139509f01d9Sratchov 140509f01d9Sratchov /* 141d07fece6Sratchov * network representation of sioctl_node structure 142d07fece6Sratchov */ 143d07fece6Sratchov struct amsg_ctl_node { 144d07fece6Sratchov char name[AMSG_CTL_NAMEMAX]; 145d07fece6Sratchov int16_t unit; 146d07fece6Sratchov uint8_t __pad[2]; 147d07fece6Sratchov }; 148d07fece6Sratchov 149d07fece6Sratchov /* 150d07fece6Sratchov * network representation of sioctl_desc structure 151d07fece6Sratchov */ 152d07fece6Sratchov struct amsg_ctl_desc { 153d07fece6Sratchov struct amsg_ctl_node node0; /* affected channels */ 154d07fece6Sratchov struct amsg_ctl_node node1; /* dito for AMSG_CTL_{SEL,VEC,LIST} */ 155d07fece6Sratchov char func[AMSG_CTL_NAMEMAX]; /* parameter function name */ 156d07fece6Sratchov char group[AMSG_CTL_NAMEMAX]; /* group of the control */ 157d07fece6Sratchov uint8_t type; /* see sioctl_desc structure */ 158d07fece6Sratchov uint8_t __pad1[1]; 159d07fece6Sratchov uint16_t addr; /* control address */ 160d07fece6Sratchov uint16_t maxval; 161d07fece6Sratchov uint16_t curval; 162*4d8b188fSratchov uint32_t __pad2[4]; 163*4d8b188fSratchov char display[AMSG_CTL_DISPLAYMAX]; /* free-format hint */ 164d07fece6Sratchov }; 165d07fece6Sratchov 166d07fece6Sratchov /* 167509f01d9Sratchov * Initialize an amsg structure: fill all fields with 0xff, so the read 168509f01d9Sratchov * can test which fields were set. 169509f01d9Sratchov */ 170509f01d9Sratchov #define AMSG_INIT(m) do { memset((m), 0xff, sizeof(struct amsg)); } while (0) 171509f01d9Sratchov 172509f01d9Sratchov /* 173509f01d9Sratchov * Since the structure is memset to 0xff, the MSB can be used to check 174509f01d9Sratchov * if any field was set. 175509f01d9Sratchov */ 176509f01d9Sratchov #define AMSG_ISSET(x) (((x) & (1 << (8 * sizeof(x) - 1))) == 0) 177509f01d9Sratchov 178509f01d9Sratchov #endif /* !defined(AMSG_H) */ 179