Re: [PATCHv2 1/3] monitor: Add save to file SCO audio

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



ping

On Tue, Jul 29, 2014 at 05:18:22PM +0300, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@xxxxxxxxx>
> 
> Add new option which makes possible to save audio SCO trace to file. The
> file can be played with sox using command line:
> btmon -a <cap> -S<audio-file>
> $ play -c 1 -t s16 -r 8000 <audio-file>
> ---
>  monitor/analyze.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
>  monitor/analyze.h |  2 ++
>  monitor/main.c    | 17 ++++++++++++++---
>  monitor/packet.h  |  1 +
>  4 files changed, 59 insertions(+), 5 deletions(-)
> 
> diff --git a/monitor/analyze.c b/monitor/analyze.c
> index 5288cf3..7aa98b0 100644
> --- a/monitor/analyze.c
> +++ b/monitor/analyze.c
> @@ -28,15 +28,22 @@
>  
>  #include <stdio.h>
>  #include <string.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <sys/stat.h>
>  
>  #include "src/shared/util.h"
>  #include "src/shared/queue.h"
>  #include "src/shared/btsnoop.h"
>  #include "monitor/bt.h"
> +#include "monitor/packet.h"
>  #include "analyze.h"
>  
>  #define MAX_PACKET_SIZE		(1486 + 4)
>  
> +static int sco_fd = -1;
> +static unsigned long filter_mask = 0;
> +
>  struct hci_dev {
>  	uint16_t index;
>  	uint8_t type;
> @@ -237,12 +244,22 @@ static void acl_pkt(struct timeval *tv, uint16_t index,
>  	dev->num_acl++;
>  }
>  
> -static void sco_pkt(struct timeval *tv, uint16_t index,
> +void analyze_set_filter(unsigned long filter)
> +{
> +	filter_mask = filter;
> +}
> +
> +static void sco_pkt(struct timeval *tv, uint16_t index, bool in,
>  					const void *data, uint16_t size)
>  {
>  	const struct bt_hci_sco_hdr *hdr = data;
>  	struct hci_dev *dev;
>  
> +	if (size < sizeof(*hdr)) {
> +		fprintf(stderr, "Malformed SCO packet of size %u", size);
> +		return;
> +	}
> +
>  	data += sizeof(*hdr);
>  	size -= sizeof(*hdr);
>  
> @@ -251,6 +268,15 @@ static void sco_pkt(struct timeval *tv, uint16_t index,
>  		return;
>  
>  	dev->num_sco++;
> +
> +	if (size != 48) {
> +		fprintf(stderr, "Drop malformed packet of size %u\n", size);
> +		return;
> +	}
> +
> +	if ((filter_mask & PACKET_FILTER_SAVE_SCO_DATA) && in)
> +		if (write(sco_fd, data, size) < 0)
> +			return;
>  }
>  
>  void analyze_trace(const char *path)
> @@ -308,8 +334,10 @@ void analyze_trace(const char *path)
>  			acl_pkt(&tv, index, buf, pktlen);
>  			break;
>  		case BTSNOOP_OPCODE_SCO_TX_PKT:
> +			sco_pkt(&tv, index, false, buf, pktlen);
> +			break;
>  		case BTSNOOP_OPCODE_SCO_RX_PKT:
> -			sco_pkt(&tv, index, buf, pktlen);
> +			sco_pkt(&tv, index, true, buf, pktlen);
>  			break;
>  		}
>  
> @@ -321,5 +349,17 @@ void analyze_trace(const char *path)
>  	queue_destroy(dev_list, dev_destroy);
>  
>  done:
> +	if (sco_fd >= 0)
> +		close(sco_fd);
>  	btsnoop_unref(btsnoop_file);
>  }
> +
> +bool open_sco_dump(const char *path)
> +{
> +	sco_fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC,
> +					S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
> +	if (sco_fd < 0)
> +		return false;
> +
> +	return true;
> +}
> diff --git a/monitor/analyze.h b/monitor/analyze.h
> index c643d35..50bbf07 100644
> --- a/monitor/analyze.h
> +++ b/monitor/analyze.h
> @@ -23,3 +23,5 @@
>   */
>  
>  void analyze_trace(const char *path);
> +void analyze_set_filter(unsigned long filter);
> +bool open_sco_dump(const char *path);
> diff --git a/monitor/main.c b/monitor/main.c
> index f0922eb..ac34262 100644
> --- a/monitor/main.c
> +++ b/monitor/main.c
> @@ -76,7 +76,7 @@ static const struct option main_options[] = {
>  	{ "index",   required_argument, NULL, 'i' },
>  	{ "time",    no_argument,       NULL, 't' },
>  	{ "date",    no_argument,       NULL, 'T' },
> -	{ "sco",     no_argument,	NULL, 'S' },
> +	{ "sco",     optional_argument,	NULL, 'S' },
>  	{ "ellisys", required_argument, NULL, 'E' },
>  	{ "todo",    no_argument,       NULL, '#' },
>  	{ "version", no_argument,       NULL, 'v' },
> @@ -91,6 +91,7 @@ int main(int argc, char *argv[])
>  	const char *writer_path = NULL;
>  	const char *analyze_path = NULL;
>  	const char *ellisys_server = NULL;
> +	const char *sco_path = NULL;
>  	unsigned short ellisys_port = 0;
>  	const char *str;
>  	int exit_status;
> @@ -103,7 +104,7 @@ int main(int argc, char *argv[])
>  	for (;;) {
>  		int opt;
>  
> -		opt = getopt_long(argc, argv, "r:w:a:s:i:tTSE:vh",
> +		opt = getopt_long(argc, argv, "r:w:a:s:i:tTS::E:vh",
>  						main_options, NULL);
>  		if (opt < 0)
>  			break;
> @@ -142,7 +143,11 @@ int main(int argc, char *argv[])
>  			filter_mask |= PACKET_FILTER_SHOW_DATE;
>  			break;
>  		case 'S':
> -			filter_mask |= PACKET_FILTER_SHOW_SCO_DATA;
> +			if (optarg) {
> +				filter_mask |= PACKET_FILTER_SAVE_SCO_DATA;
> +				sco_path = optarg;
> +			} else
> +				filter_mask |= PACKET_FILTER_SHOW_SCO_DATA;
>  			break;
>  		case 'E':
>  			ellisys_server = optarg;
> @@ -184,6 +189,12 @@ int main(int argc, char *argv[])
>  	keys_setup();
>  
>  	packet_set_filter(filter_mask);
> +	analyze_set_filter(filter_mask);
> +
> +	if (sco_path && !open_sco_dump(sco_path)) {
> +		printf("Failed to open '%s'\n", sco_path);
> +		return EXIT_FAILURE;
> +	}
>  
>  	if (analyze_path) {
>  		analyze_trace(analyze_path);
> diff --git a/monitor/packet.h b/monitor/packet.h
> index c39816b..d75b3ba 100644
> --- a/monitor/packet.h
> +++ b/monitor/packet.h
> @@ -32,6 +32,7 @@
>  #define PACKET_FILTER_SHOW_TIME_OFFSET	(1 << 3)
>  #define PACKET_FILTER_SHOW_ACL_DATA	(1 << 4)
>  #define PACKET_FILTER_SHOW_SCO_DATA	(1 << 5)
> +#define PACKET_FILTER_SAVE_SCO_DATA	(1 << 6)
>  
>  void packet_set_filter(unsigned long filter);
>  void packet_add_filter(unsigned long filter);
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux