xref: /src/usr.sbin/virtual_oss/virtual_oss_cmd/command.c (revision 6d5a428056b52c7ce47b01d6af8aaaff6feecfdd)
19cab9fdeSChristos Margiolis /*-
2*6d5a4280STuukka Pasanen  * SPDX-License-Identifier: BSD-2-Clause
3*6d5a4280STuukka Pasanen  *
49cab9fdeSChristos Margiolis  * Copyright (c) 2021-2022 Hans Petter Selasky
59cab9fdeSChristos Margiolis  *
69cab9fdeSChristos Margiolis  * Redistribution and use in source and binary forms, with or without
79cab9fdeSChristos Margiolis  * modification, are permitted provided that the following conditions
89cab9fdeSChristos Margiolis  * are met:
99cab9fdeSChristos Margiolis  * 1. Redistributions of source code must retain the above copyright
109cab9fdeSChristos Margiolis  *    notice, this list of conditions and the following disclaimer.
119cab9fdeSChristos Margiolis  * 2. Redistributions in binary form must reproduce the above copyright
129cab9fdeSChristos Margiolis  *    notice, this list of conditions and the following disclaimer in the
139cab9fdeSChristos Margiolis  *    documentation and/or other materials provided with the distribution.
149cab9fdeSChristos Margiolis  *
159cab9fdeSChristos Margiolis  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
169cab9fdeSChristos Margiolis  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
179cab9fdeSChristos Margiolis  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
189cab9fdeSChristos Margiolis  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199cab9fdeSChristos Margiolis  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
209cab9fdeSChristos Margiolis  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
219cab9fdeSChristos Margiolis  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
229cab9fdeSChristos Margiolis  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
239cab9fdeSChristos Margiolis  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
249cab9fdeSChristos Margiolis  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
259cab9fdeSChristos Margiolis  * SUCH DAMAGE.
269cab9fdeSChristos Margiolis  */
279cab9fdeSChristos Margiolis 
289cab9fdeSChristos Margiolis #include <stdio.h>
299cab9fdeSChristos Margiolis #include <stdint.h>
309cab9fdeSChristos Margiolis #include <stdlib.h>
319cab9fdeSChristos Margiolis #include <string.h>
329cab9fdeSChristos Margiolis #include <unistd.h>
339cab9fdeSChristos Margiolis #include <err.h>
349cab9fdeSChristos Margiolis #include <sysexits.h>
359cab9fdeSChristos Margiolis #include <stdarg.h>
369cab9fdeSChristos Margiolis #include <fcntl.h>
379cab9fdeSChristos Margiolis 
389cab9fdeSChristos Margiolis #include "virtual_oss.h"
399cab9fdeSChristos Margiolis 
409cab9fdeSChristos Margiolis static void
message(const char * fmt,...)419cab9fdeSChristos Margiolis message(const char *fmt, ...)
429cab9fdeSChristos Margiolis {
439cab9fdeSChristos Margiolis 	va_list list;
449cab9fdeSChristos Margiolis 
459cab9fdeSChristos Margiolis 	va_start(list, fmt);
469cab9fdeSChristos Margiolis 	vfprintf(stderr, fmt, list);
479cab9fdeSChristos Margiolis 	va_end(list);
489cab9fdeSChristos Margiolis }
499cab9fdeSChristos Margiolis 
509cab9fdeSChristos Margiolis static void
usage(void)519cab9fdeSChristos Margiolis usage(void)
529cab9fdeSChristos Margiolis {
539cab9fdeSChristos Margiolis 	message("Usage: virtual_oss_cmd /dev/vdsp.ctl [command line arguments to pass to virtual_oss]\n");
549cab9fdeSChristos Margiolis 	exit(EX_USAGE);
559cab9fdeSChristos Margiolis }
569cab9fdeSChristos Margiolis 
579cab9fdeSChristos Margiolis int
main(int argc,char ** argv)589cab9fdeSChristos Margiolis main(int argc, char **argv)
599cab9fdeSChristos Margiolis {
609cab9fdeSChristos Margiolis 	char options[VIRTUAL_OSS_OPTIONS_MAX] = {};
619cab9fdeSChristos Margiolis 	size_t offset = 0;
629cab9fdeSChristos Margiolis 	size_t len = VIRTUAL_OSS_OPTIONS_MAX - 1;
639cab9fdeSChristos Margiolis 	int fd;
649cab9fdeSChristos Margiolis 
659cab9fdeSChristos Margiolis 	/* check if no options */
669cab9fdeSChristos Margiolis 	if (argc < 2)
679cab9fdeSChristos Margiolis 		usage();
689cab9fdeSChristos Margiolis 
699cab9fdeSChristos Margiolis 	fd = open(argv[1], O_RDWR);
709cab9fdeSChristos Margiolis 	if (fd < 0)
719cab9fdeSChristos Margiolis 		errx(EX_SOFTWARE, "Could not open '%s'", argv[1]);
729cab9fdeSChristos Margiolis 
739cab9fdeSChristos Margiolis 	for (int x = 2; x != argc; x++) {
749cab9fdeSChristos Margiolis 		size_t tmp = strlen(argv[x]) + 1;
759cab9fdeSChristos Margiolis 		if (tmp > len)
769cab9fdeSChristos Margiolis 			errx(EX_SOFTWARE, "Too many options passed");
779cab9fdeSChristos Margiolis 		memcpy(options + offset, argv[x], tmp);
789cab9fdeSChristos Margiolis 		options[offset + tmp - 1] = ' ';
799cab9fdeSChristos Margiolis 		offset += tmp;
809cab9fdeSChristos Margiolis 		len -= tmp;
819cab9fdeSChristos Margiolis 	}
829cab9fdeSChristos Margiolis 
839cab9fdeSChristos Margiolis 	if (options[0] == 0) {
849cab9fdeSChristos Margiolis 		struct virtual_oss_system_info info;
859cab9fdeSChristos Margiolis 		if (ioctl(fd, VIRTUAL_OSS_GET_SYSTEM_INFO, &info) < 0)
869cab9fdeSChristos Margiolis 			errx(EX_SOFTWARE, "Cannot get system information");
879cab9fdeSChristos Margiolis 
889cab9fdeSChristos Margiolis 		info.rx_device_name[sizeof(info.rx_device_name) - 1] = 0;
899cab9fdeSChristos Margiolis 		info.tx_device_name[sizeof(info.tx_device_name) - 1] = 0;
909cab9fdeSChristos Margiolis 
919cab9fdeSChristos Margiolis 		printf("Sample rate: %u Hz\n"
929cab9fdeSChristos Margiolis 		       "Sample width: %u bits\n"
939cab9fdeSChristos Margiolis 		       "Sample channels: %u\n"
949cab9fdeSChristos Margiolis 		       "Output jitter: %u / %u\n"
959cab9fdeSChristos Margiolis 		       "Input device name: %s\n"
969cab9fdeSChristos Margiolis 		       "Output device name: %s\n",
979cab9fdeSChristos Margiolis 		       info.sample_rate,
989cab9fdeSChristos Margiolis 		       info.sample_bits,
999cab9fdeSChristos Margiolis 		       info.sample_channels,
1009cab9fdeSChristos Margiolis 		       info.tx_jitter_down,
1019cab9fdeSChristos Margiolis 		       info.tx_jitter_up,
1029cab9fdeSChristos Margiolis 		       info.rx_device_name,
1039cab9fdeSChristos Margiolis 		       info.tx_device_name);
1049cab9fdeSChristos Margiolis 	} else {
1059cab9fdeSChristos Margiolis 		/* execute options */
1069cab9fdeSChristos Margiolis 		if (ioctl(fd, VIRTUAL_OSS_ADD_OPTIONS, options) < 0)
1079cab9fdeSChristos Margiolis 			errx(EX_SOFTWARE, "One or more invalid options");
1089cab9fdeSChristos Margiolis 		/* show error, if any */
1099cab9fdeSChristos Margiolis 		if (options[0] != '\0')
1109cab9fdeSChristos Margiolis 			errx(EX_SOFTWARE, "%s", options);
1119cab9fdeSChristos Margiolis 	}
1129cab9fdeSChristos Margiolis 
1139cab9fdeSChristos Margiolis 	close(fd);
1149cab9fdeSChristos Margiolis 	return (0);
1159cab9fdeSChristos Margiolis }
116