1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2021-2022 Hans Petter Selasky 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <stdio.h> 29 #include <stdint.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <unistd.h> 33 #include <err.h> 34 #include <sysexits.h> 35 #include <stdarg.h> 36 #include <fcntl.h> 37 38 #include "virtual_oss.h" 39 40 static void __dead2 41 usage(void) 42 { 43 fprintf(stderr, "usage: %s <control_device> [virtual_oss(8) command " 44 "line options]\n", getprogname()); 45 exit(EX_USAGE); 46 } 47 48 int 49 main(int argc, char **argv) 50 { 51 char options[VIRTUAL_OSS_OPTIONS_MAX] = {}; 52 size_t offset = 0; 53 size_t len = VIRTUAL_OSS_OPTIONS_MAX - 1; 54 int fd; 55 56 /* check if no options */ 57 if (argc < 2) 58 usage(); 59 60 fd = open(argv[1], O_RDWR); 61 if (fd < 0) 62 err(EX_SOFTWARE, "Could not open control device: %s", argv[1]); 63 64 for (int x = 2; x != argc; x++) { 65 size_t tmp = strlen(argv[x]) + 1; 66 if (tmp > len) 67 errx(EX_SOFTWARE, "Too many options passed"); 68 memcpy(options + offset, argv[x], tmp); 69 options[offset + tmp - 1] = ' '; 70 offset += tmp; 71 len -= tmp; 72 } 73 74 if (options[0] == 0) { 75 struct virtual_oss_system_info info; 76 if (ioctl(fd, VIRTUAL_OSS_GET_SYSTEM_INFO, &info) < 0) 77 errx(EX_SOFTWARE, "Cannot get system information"); 78 79 info.rx_device_name[sizeof(info.rx_device_name) - 1] = 0; 80 info.tx_device_name[sizeof(info.tx_device_name) - 1] = 0; 81 82 printf("Sample rate: %u Hz\n" 83 "Sample width: %u bits\n" 84 "Sample channels: %u\n" 85 "Output jitter: %u / %u\n" 86 "Input device name: %s\n" 87 "Output device name: %s\n", 88 info.sample_rate, 89 info.sample_bits, 90 info.sample_channels, 91 info.tx_jitter_down, 92 info.tx_jitter_up, 93 info.rx_device_name, 94 info.tx_device_name); 95 } else { 96 /* execute options */ 97 if (ioctl(fd, VIRTUAL_OSS_ADD_OPTIONS, options) < 0) 98 errx(EX_SOFTWARE, "One or more invalid options"); 99 /* show error, if any */ 100 if (options[0] != '\0') 101 errx(EX_SOFTWARE, "%s", options); 102 } 103 104 close(fd); 105 return (0); 106 } 107