1 /* $OpenBSD: amsg.h,v 1.16 2024/05/24 15:16:09 ratchov Exp $ */ 2 /* 3 * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #ifndef AMSG_H 18 #define AMSG_H 19 20 #include <stdint.h> 21 22 /* 23 * unix-domain socket name is: 24 * 25 * DIR [ '-' UID ] '/' FILE UNIT 26 * 27 * example: "/tmp/sndio-1000/sock0" 28 * 29 */ 30 #define SOCKPATH_DIR "/tmp/sndio" 31 #define SOCKPATH_FILE "sock" 32 #define SOCKPATH_MAX (1 + \ 33 sizeof(SOCKPATH_DIR) - 1 + \ 34 sizeof(char) + \ 35 sizeof(int) * 3 + \ 36 sizeof(char) + \ 37 sizeof(SOCKPATH_FILE) - 1 + \ 38 sizeof(int) * 3) 39 40 /* 41 * server TCP base port number 42 */ 43 #define AUCAT_PORT 11025 44 45 /* 46 * limits 47 */ 48 #define AMSG_CTL_NAMEMAX 16 /* max name length */ 49 #define AMSG_CTL_DISPLAYMAX 32 /* max display string length */ 50 51 /* 52 * Size of the struct amsg_ctl_desc expected by clients 53 * using the AMSG_CTLSUB_OLD request 54 */ 55 #define AMSG_OLD_DESC_SIZE 92 56 57 /* 58 * WARNING: since the protocol may be simultaneously used by static 59 * binaries or by different versions of a shared library, we are not 60 * allowed to change the packet binary representation in a backward 61 * incompatible way. 62 * 63 * Especially, make sure the amsg_xxx structures are not larger 64 * than 32 bytes. 65 */ 66 struct amsg { 67 #define AMSG_ACK 0 /* ack for START/STOP */ 68 #define AMSG_GETPAR 1 /* get the current parameters */ 69 #define AMSG_SETPAR 2 /* set the current parameters */ 70 #define AMSG_START 3 /* request the server to start the stream */ 71 #define AMSG_STOP 4 /* request the server to stop the stream */ 72 #define AMSG_DATA 5 /* data block */ 73 #define AMSG_FLOWCTL 6 /* feedback about buffer usage */ 74 #define AMSG_MOVE 7 /* position changed */ 75 #define AMSG_SETVOL 9 /* set volume */ 76 #define AMSG_HELLO 10 /* say hello, check versions and so ... */ 77 #define AMSG_BYE 11 /* ask server to drop connection */ 78 #define AMSG_AUTH 12 /* send authentication cookie */ 79 #define AMSG_CTLSUB_OLD 13 /* amsg_ctl_desc with no "display" attribute */ 80 #define AMSG_CTLSET 14 /* set control value */ 81 #define AMSG_CTLSYNC 15 /* end of controls descriptions */ 82 #define AMSG_CTLSUB 16 /* ondesc/onctl subscription */ 83 uint32_t cmd; 84 uint32_t __pad; 85 union { 86 struct amsg_par { 87 uint8_t legacy_mode; /* compat for old libs */ 88 uint8_t xrun; /* one of above */ 89 uint8_t bps; /* bytes per sample */ 90 uint8_t bits; /* actually used bits */ 91 uint8_t msb; /* 1 if MSB justified */ 92 uint8_t le; /* 1 if little endian */ 93 uint8_t sig; /* 1 if signed */ 94 uint8_t __pad1; 95 uint16_t pchan; /* play channels */ 96 uint16_t rchan; /* record channels */ 97 uint32_t rate; /* frames per second */ 98 uint32_t bufsz; /* total buffered frames */ 99 uint32_t round; 100 uint32_t appbufsz; /* client side bufsz */ 101 uint32_t _reserved[1]; /* for future use */ 102 } par; 103 struct amsg_data { 104 #define AMSG_DATAMAX 0x1000 105 uint32_t size; 106 } data; 107 struct amsg_stop { 108 uint8_t drain; 109 } stop; 110 struct amsg_ts { 111 int32_t delta; 112 } ts; 113 struct amsg_vol { 114 uint32_t ctl; 115 } vol; 116 struct amsg_hello { 117 uint16_t mode; /* bitmap of MODE_XXX */ 118 #define AMSG_VERSION 7 119 uint8_t version; /* protocol version */ 120 #define AMSG_NODEV 255 121 uint8_t devnum; /* device number */ 122 uint32_t id; /* client id */ 123 #define AMSG_OPTMAX 12 124 char opt[AMSG_OPTMAX]; /* profile name */ 125 char who[12]; /* hint for leases */ 126 } hello; 127 struct amsg_auth { 128 #define AMSG_COOKIELEN 16 129 uint8_t cookie[AMSG_COOKIELEN]; 130 } auth; 131 struct amsg_ctlsub { 132 uint8_t desc, val; 133 } ctlsub; 134 struct amsg_ctlset { 135 uint16_t addr, val; 136 } ctlset; 137 } u; 138 }; 139 140 /* 141 * network representation of sioctl_node structure 142 */ 143 struct amsg_ctl_node { 144 char name[AMSG_CTL_NAMEMAX]; 145 int16_t unit; 146 uint8_t __pad[2]; 147 }; 148 149 /* 150 * network representation of sioctl_desc structure 151 */ 152 struct amsg_ctl_desc { 153 struct amsg_ctl_node node0; /* affected channels */ 154 struct amsg_ctl_node node1; /* dito for AMSG_CTL_{SEL,VEC,LIST} */ 155 char func[AMSG_CTL_NAMEMAX]; /* parameter function name */ 156 char group[AMSG_CTL_NAMEMAX]; /* group of the control */ 157 uint8_t type; /* see sioctl_desc structure */ 158 uint8_t __pad1[1]; 159 uint16_t addr; /* control address */ 160 uint16_t maxval; 161 uint16_t curval; 162 uint32_t __pad2[4]; 163 char display[AMSG_CTL_DISPLAYMAX]; /* free-format hint */ 164 }; 165 166 /* 167 * Initialize an amsg structure: fill all fields with 0xff, so the read 168 * can test which fields were set. 169 */ 170 #define AMSG_INIT(m) do { memset((m), 0xff, sizeof(struct amsg)); } while (0) 171 172 /* 173 * Since the structure is memset to 0xff, the MSB can be used to check 174 * if any field was set. 175 */ 176 #define AMSG_ISSET(x) (((x) & (1 << (8 * sizeof(x) - 1))) == 0) 177 178 #endif /* !defined(AMSG_H) */ 179