/* 
 | 
 * 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; 
 | 
} 
 |