linuxOS_AP05/external/bluez-alsa/utils/rfcomm.c
2025-06-02 13:59:07 +08:00

166 lines
3.3 KiB
C

/*
* BlueALSA - rfcomm.c
* Copyright (c) 2016-2018 Arkadiusz Bokowy
*
* This file is a part of bluez-alsa.
*
* This project is licensed under the terms of the MIT license.
*
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
#include "shared/ctl-client.h"
#include "shared/log.h"
static char *strtrim(char *str) {
while (isspace(*str))
str++;
if (*str == '\0')
return str;
char *end = &str[strlen(str) - 1];
while (end > str && isspace(*end))
end--;
end[1] = '\0';
return str;
}
static char *build_rfcomm_command(const char *cmd) {
static char command[512];
bool at;
command[0] = '\0';
if (!(at = strncmp(cmd, "AT", 2) == 0))
strcpy(command, "\r\n");
strcat(command, cmd);
strcat(command, "\r");
if (!at)
strcat(command, "\n");
return command;
}
int main(int argc, char *argv[]) {
int opt;
const char *opts = "hVi:";
const struct option longopts[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "hci", required_argument, NULL, 'i' },
{ 0, 0, 0, 0 },
};
const char *ba_interface = "hci0";
int status = EXIT_SUCCESS;
int ba_fd = -1;
bdaddr_t ba_addr;
log_open(argv[0], false, false);
while ((opt = getopt_long(argc, argv, opts, longopts, NULL)) != -1)
switch (opt) {
case 'h' /* --help */ :
usage:
printf("Usage:\n"
" %s [OPTION]... <BT-ADDR>\n"
"\nOptions:\n"
" -h, --help\t\tprint this help and exit\n"
" -V, --version\t\tprint version and exit\n"
" -i, --hci=hciX\tHCI device to use\n",
argv[0]);
return EXIT_SUCCESS;
case 'V' /* --version */ :
printf("%s\n", PACKAGE_VERSION);
return EXIT_SUCCESS;
case 'i' /* --hci */ :
ba_interface = optarg;
break;
default:
fprintf(stderr, "Try '%s --help' for more information.\n", argv[0]);
return EXIT_FAILURE;
}
if (optind + 1 != argc)
goto usage;
if (str2ba(argv[optind], &ba_addr) != 0) {
error("Invalid BT device address: %s", argv[optind]);
goto fail;
}
if ((ba_fd = bluealsa_open(ba_interface)) == -1) {
error("BlueALSA connection failed: %s", strerror(errno));
goto fail;
}
if (isatty(fileno(stdin))) {
char prompt[17 + 3];
char *line;
rl_bind_key('\t', rl_insert);
sprintf(prompt, "%s> ", argv[optind]);
while ((line = readline(prompt)) != NULL) {
char *tmp = strtrim(line);
if (strlen(tmp) > 0) {
if (bluealsa_send_rfcomm_command(ba_fd, ba_addr, build_rfcomm_command(tmp)) == -1)
warn("Couldn't send RFCOMM command: %s", strerror(errno));
add_history(tmp);
}
free(line);
}
fprintf(stdout, "\n");
}
else {
char line[256];
int duration;
while (fgets(line, sizeof(line), stdin) != NULL) {
char *tmp = strtrim(line);
if (strlen(tmp) > 0) {
if (sscanf(tmp, "%*[Ss]%*[Ll]%*2[Ee]%*[Pp] %d", &duration) == 1) {
sleep(duration);
continue;
}
if (bluealsa_send_rfcomm_command(ba_fd, ba_addr, build_rfcomm_command(tmp)) == -1)
warn("Couldn't send RFCOMM command: %s", strerror(errno));
}
}
}
goto success;
fail:
status = EXIT_FAILURE;
success:
if (ba_fd != -1)
close(ba_fd);
return status;
}