From: Brad Midgley <bmidgley@xmission.com>
To: bluez-devel@lists.sourceforge.net
Subject: Re: [Bluez-devel] A2DP sink code finally
Date: Sun, 24 Apr 2005 21:24:04 -0600 [thread overview]
Message-ID: <426C62D4.80009@xmission.com> (raw)
In-Reply-To: <20050424150930.71134.qmail@web8308.mail.in.yahoo.com>
Mayank,
Thanks for the submission. I corrected some warnings, disabled unused
functions, and added it to Makefile.am.
We definitely need to do a lot of cleanup (eg now that a2play and a2snk
have so much duplication), but first off we need to see why audio is
being distorted...
Brad
Mayank Batra wrote:
> Hi Brad,
>
> This is the code for the A2DP sink application.
>
> Compilation:
>
> gcc -o a2snk a2snk.c -lbluetooth
>
> Running the application:
>
> ./a2snk
>
> Right now the following bugs exist:
>
> 1) Poor sound quality.
>
> 2) Unclean disconnection.
>
> Help me improve the above areas.
>
> Please add this code to the CVS.
>
> Thanks and Regards,
>
> Mayank
>
> ________________________________________________________________________
> Yahoo! India Matrimony: Find your life partner online
> Go to: http://yahoo.shaadi.com/india-matrimony
>
>
> ------------------------------------------------------------------------
>
> /*
> * a2snk.c
> * This program functions as an A2DP sink
> * (Emulation of an A2DP headset)
> * Mayank Batra <mayankbatra@yahoo.co.in>
> * Abhinav Mathur <abhinavpmathur@yahoo.com>
> *
> * This program is free software; you can redistribute it and/or modify
> * it under the terms of the GNU General Public License as published by
> * the Free Software Foundation; either version 2 of the License, or
> * (at your option) any later version.
> *
> * This program is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> * GNU General Public License for more details.
> *
> * You should have received a copy of the GNU General Public License
> * along with this program; if not, write to the Free Software
> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> *
> */
>
> #ifdef HAVE_CONFIG_H
> #include <config.h>
> #endif
>
> #include <stdio.h>
> #include <errno.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <getopt.h>
> #include <signal.h>
> #include <string.h>
> #include <sys/socket.h>
> #include <sys/stat.h>
> #include <sys/soundcard.h> //To play the sound on the sound card
>
> #include "sbc/sbc.h"
>
> #include <bluetooth/bluetooth.h>
> #include <bluetooth/hci.h>
> #include <bluetooth/hci_lib.h>
> #include <bluetooth/l2cap.h>
> #include <bluetooth/sdp.h>
> #include <bluetooth/sdp_lib.h>
>
> #include <netinet/in.h>
>
> /* AVDTP structures */
>
> /* packet components */
>
> struct avdtp_header {
> //uint8_t packet_type:2;
> uint8_t message_type:2;
> uint8_t packet_type:2;
> uint8_t transaction_label:4;
> uint8_t signal_id:6;
> uint8_t rfa0:2;
> } __attribute__ ((packed));
>
> struct acp_seid_info {
> uint8_t rfa0:1;
> uint8_t inuse0:1;
> uint8_t acp_seid:6;
> uint8_t rfa2:3;
> uint8_t tsep:1;
> uint8_t media_type:4;
> } __attribute__ ((packed));
>
> struct sbc_codec_specific_elements {
> // a2dp p. 20
> uint8_t channel_mode:4;
> uint8_t frequency:4;
> uint8_t allocation_method:2;
> uint8_t subbands:2;
> uint8_t block_length:4;
> uint8_t min_bitpool;
> uint8_t max_bitpool;
> } __attribute__ ((packed));
>
> #define MAX_ADDITIONAL_CODEC 0 //Right now only SBC is supported
> #define MAX_ADDITIONAL_CODEC_OCTETS (MAX_ADDITIONAL_CODEC*sizeof(struct acp_seid_info))
>
> /* packets */
>
> struct sepd_req {
> struct avdtp_header header;
> } __attribute__ ((packed));
>
> struct sepd_resp {
> struct avdtp_header header;
> struct acp_seid_info infos[1 + MAX_ADDITIONAL_CODEC];
> } __attribute__ ((packed));
>
> struct getcap_req {
> struct avdtp_header header;
> uint8_t rfa1:2;
> uint8_t acp_seid:6;
> } __attribute__ ((packed));
>
> struct getcap_resp {
> struct avdtp_header header;
>
> uint8_t serv_cap;
> uint8_t serv_cap_len;
>
> uint8_t cap_type;
> uint8_t length;
> uint8_t media_type;
> uint8_t media_codec_type;
>
> struct sbc_codec_specific_elements sbc_elements;
>
> } __attribute__ ((packed));
>
> struct set_config {
> struct avdtp_header header;
>
> uint8_t rfa0:2;
> uint8_t acp_seid:6;
> uint8_t rfa1:2;
> uint8_t int_seid:6;
>
> uint8_t serv_cap;
> uint8_t serv_cap_len;
>
> uint8_t cap_type;
> uint8_t length;
> uint8_t media_type;
> uint8_t media_codec_type;
>
> struct sbc_codec_specific_elements sbc_elements;
>
> } __attribute__ ((packed));
>
> struct set_config_resp {
> struct avdtp_header header;
>
> // only present for an error
>
> uint8_t serv_cat;
> uint8_t error_code;
> } __attribute__ ((packed));
>
> struct open_stream_cmd {
> struct avdtp_header header;
> uint8_t rfa0:2;
> uint8_t acp_seid:6;
> } __attribute__ ((packed));
>
> struct open_stream_rsp {
> struct avdtp_header header;
>
> // only present for an error
>
> uint8_t error;
> } __attribute__ ((packed));
>
> struct start_stream_cmd {
> struct avdtp_header header;
> uint8_t rfa0:2;
> uint8_t acp_seid:6;
> } __attribute__ ((packed));
>
> struct start_stream_rsp {
> struct avdtp_header header;
>
> // only present for an error
>
> uint8_t rfa0:2;
> uint8_t acp_seid:6;
> uint8_t error;
> } __attribute__ ((packed));
>
> struct close_stream_cmd {
> struct avdtp_header header;
> uint8_t rfa0:2;
> uint8_t acp_seid:6;
> } __attribute__ ((packed));
>
> struct close_stream_rsp {
> struct avdtp_header header;
>
> // only present for an error
>
> uint8_t error;
> } __attribute__ ((packed));
>
> // this is an rtp, not bluetooth header, so values are big endian
> struct media_packet_header {
> uint8_t cc:4;
> uint8_t x:1;
> uint8_t p:1;
> uint8_t v:2;
>
> uint8_t pt:7;
> uint8_t m:1;
>
> uint16_t sequence_number;
> uint32_t timestamp;
> uint32_t ssrc;
> uint32_t csrc[0];
> } __attribute__ ((packed));
>
> struct media_payload_header {
> uint8_t frame_count:4;
> uint8_t rfa0:1;
> uint8_t is_last_fragment:1;
> uint8_t is_first_fragment:1;
> uint8_t is_fragmented:1;
> } __attribute__ ((packed));
>
> // SBC file format header
>
> struct sbc_frame_header {
> uint8_t syncword:8; /* Sync word */
> uint8_t subbands:1; /* Subbands */
> uint8_t allocation_method:1; /* Allocation method */
> uint8_t channel_mode:2; /* Channel mode */
> uint8_t blocks:2; /* Blocks */
> uint8_t sampling_frequency:2; /* Sampling frequency */
> uint8_t bitpool:8; /* Bitpool */
> uint8_t crc_check:8; /* CRC check */
> } __attribute__ ((packed));
>
> //A2DP signal types
> #define AVDTP_DISCOVER 1
> #define AVDTP_GET_CAPABILITIES 2
> #define AVDTP_SET_CONFIGURATION 3
> #define AVDTP_OPEN 6
> #define AVDTP_START 7
> #define AVDTP_CLOSE 8
>
> #define MEDIA_TRANSPORT_CATEGORY 1
> #define MEDIA_CODEC 7
>
> #define SBC_MEDIA_CODEC_TYPE 0
> #define MPEG12_MEDIA_CODEC_TYPE 1
> #define AUDIO_MEDIA_TYPE 0
>
> //Packet Types
> #define PACKET_TYPE_SINGLE 0
> #define PACKET_TYPE_START 4
> #define PACKET_TYPE_CONTINUE 8
> #define PACKET_TYPE_END 12
>
> //Message Types
> #define MESSAGE_TYPE_COMMAND 0
> #define MESSAGE_TYPE_ACCEPT 2
> #define MESSAGE_TYPE_REJECT 3
>
> #define BUFS 1024
>
> #define MEDIA_PACKET_HEADER_LENGTH 14
>
> #define NONSPECAUDIO 1
>
> static volatile int terminate = 0;
> static int cmdfd;
> static struct sbc_frame_header sbc_info;
> sbc_t sbc;
> int audio_fd;
> #define BUF_SIZE 4096
> unsigned char audio_buffer[BUF_SIZE];
> int speed, channels;
>
>
> static void sig_term(int sig)
> {
> terminate = 1;
> }
>
> static void usage()
> {
> fprintf(stderr, "use: ./a2snk\n");
> }
>
> int opensound()
> {
> int format=AFMT_S16_BE,len,i;
> char c;
>
> if((audio_fd=open("/dev/dsp",O_WRONLY,0))==-1) {
> perror("\nFile open error\n");
> exit(1);
> }
> if(ioctl(audio_fd,SNDCTL_DSP_SETFMT,&format)==-1) {
> perror("\nioctl no. 1\n");
> exit(1);
> }
>
> if(ioctl(audio_fd,SNDCTL_DSP_CHANNELS,&channels)==-1) {
> perror("\nioctl no. 2\n");
> exit(1);
> }
>
> if(ioctl(audio_fd,SNDCTL_DSP_SPEED,&speed)==-1) {
> perror("\nioctl no. 3\n");
> exit(1);
> }
>
> return 1;
> }
>
> int closesound()
> {
> if(close(audio_fd)<0) {
> perror("\nUnable to close the sound card");
> exit(1);
> }
> }
>
>
> static ssize_t __write(int fd,void *buf,size_t count)
> {
> ssize_t len,pos=0;
> while(count>0){
> len=write(fd,buf+pos,count);
> if(len<=0)
> return len;
> count -= len;
> pos += len;
> }
> return pos;
> }
>
> static void decode(char *stream,int streamlen)
> {
> int fd, id, pos, framelen;
> static int turn = 1;
> pos = 0;
>
> framelen = sbc_decode(&sbc, stream, streamlen);
>
> printf("%d Hz, %d channels\n", sbc.rate, sbc.channels);
> channels=sbc.channels;
> speed=sbc.rate;
> if(turn == 1) {
> /* Open the sound card only once during the streaming */
> opensound();
> turn = 0;
> }
>
> char c;
> while (framelen > 0) {
> //dump_packet(sbc.data,sbc.len);
> write(audio_fd,sbc.data,sbc.len);
>
> pos += framelen;
>
> framelen = sbc_decode(&sbc, stream + pos, streamlen - pos);
> }
>
> }
>
>
>
> int sk;
> static int do_listen(bdaddr_t *src, unsigned short psm, uint16_t *mtu)
> {
> struct sockaddr_l2 addr;
> struct l2cap_options opts;
>
> int opt;
> int nsk;
>
> sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
> if (sk < 0) {
> fprintf(stderr, "Can't create socket. %s(%d)\n",
> strerror(errno), errno);
> return -1;
> }
>
> memset(&addr, 0, sizeof(addr));
> addr.l2_family = AF_BLUETOOTH;
> bacpy(&addr.l2_bdaddr, src);
> addr.l2_psm=htobs(psm);
> if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
> fprintf(stderr, "Can't bind socket. %s(%d)\n",
> strerror(errno), errno);
> return -1;
> }
>
> /* Get default options */
> opt = sizeof(opts);
> if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) {
> fprintf(stderr, "Can't get default L2CAP options. %s(%d)\n",
> strerror(errno), errno);
> return -1;
> }
>
> /* Set new options */
> //opts.omtu = 48;
> //opts.imtu = imtu;
> if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, opt) < 0) {
> fprintf(stderr, "Can't set L2CAP options. %s(%d)\n",
> strerror(errno), errno);
> return -1;
> }
>
> if(listen(sk,5)<0) {
> fprintf(stderr,"\nCan't listen.%s(%d)\n",strerror(errno),errno);
> close(sk);
> return -1;
> }
>
> socklen_t addrlen;
>
> memset(&addr, 0, sizeof(addr));
> addrlen = sizeof(addr);
>
> if ((nsk = accept(sk, (struct sockaddr *) &addr, &addrlen)) < 0)
> return -1;
> else printf("\nConnected");
>
> opt = sizeof(opts);
> if (getsockopt(nsk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &opt) < 0) {
> fprintf(stderr, "Can't get L2CAP options. %s(%d)\n",
> strerror(errno), errno);
> close(nsk);
> return -1;
> }
>
> fprintf(stderr, "Connected [imtu %d, omtu %d, flush_to %d]\n",
> opts.imtu, opts.omtu, opts.flush_to);
>
> if (mtu)
> *mtu = opts.omtu;
>
> return nsk;
> }
>
> #if 0
> static void dump_packet(void *p, int size)
> {
> uint8_t *c = (uint8_t *) p;
> while (size-- > 0)
> printf(" %02x\n", *c++);
> printf("\n");
> }
> #endif
>
> static void init_request(struct avdtp_header * header, int request_id)
> {
> static int transaction = 0;
>
> header->packet_type = PACKET_TYPE_SINGLE;
> header->message_type = MESSAGE_TYPE_ACCEPT;
> header->transaction_label = transaction;
> header->signal_id = request_id;
>
> // clear rfa bits
> header->rfa0 = 0;
> if(header->signal_id!=AVDTP_OPEN)
> transaction = (transaction + 1) & 0xf;
> else transaction = (transaction + 2) & 0xf;
> }
>
>
> static int calc_frame_len(struct sbc_frame_header *hdr)
> {
> int tmp, nrof_subbands, nrof_blocks;
>
> nrof_subbands = (hdr->subbands + 1) * 4;
> nrof_blocks = (hdr->blocks + 1) * 4;
>
> switch (hdr->channel_mode) {
> case 0x00:
> nrof_subbands /= 2;
> tmp = nrof_blocks * hdr->bitpool;
> break;
> case 0x01:
> tmp = nrof_blocks * hdr->bitpool * 2;
> break;
> case 0x02:
> tmp = nrof_blocks * hdr->bitpool;
> break;
> case 0x03:
> tmp = nrof_blocks * hdr->bitpool + nrof_subbands;
> break;
> default:
> return 0;
> }
>
> return (nrof_subbands + ((tmp + 7) / 8));
> }
>
> static int read_header(int fd, struct sbc_frame_header *sbc_info) {
> if (read(fd, sbc_info, sizeof(*sbc_info)) < sizeof(*sbc_info)) {
> fprintf(stderr, "reached end of file?\n");
> return -1;
> }
>
> if (sbc_info->syncword != 0x9c) {
> printf("out of sync (0x%02x)\n", sbc_info->syncword);
> return -1;
> }
>
> return calc_frame_len(sbc_info);
> }
>
> int main(int argc, char *argv[])
> {
> struct sigaction sa;
> int streamfd;
>
> bdaddr_t src, dst;
> unsigned short psm_cmd, psm_stream;
> unsigned long flags;
> int frame_len;
> time_t timestamp;
> uint16_t mtu, seq_num;
> int fd;
>
> bacpy(&src, BDADDR_ANY);
>
> psm_cmd=25;
> cmdfd = do_listen(&src, psm_cmd, NULL);
> if (cmdfd < 0) {
> fprintf(stderr, "cannot open psm_cmd = %d\n", psm_cmd);
> exit(-1);
> }
> // avdtp discover request
>
> //Reading the discover request
> struct sepd_req get_resp;
> int size;
> size = read(cmdfd, &get_resp, sizeof(get_resp));
> if(get_resp.header.signal_id!=AVDTP_DISCOVER) {
> fprintf(stderr,"Couldn't get avdtp_discover\n");
> close(cmdfd);
> exit(-1);
> }
> else printf("\nGot Stream End Point Discovery Request");
>
>
> //Writing the discover response
>
> struct sepd_resp send_resp;
> //Fill in the values in send_resp
> memset(&send_resp,0,sizeof(send_resp));
> init_request(&send_resp.header,AVDTP_DISCOVER);
> send_resp.infos[0].rfa0=0;
> send_resp.infos[0].inuse0=0;
> send_resp.infos[0].acp_seid=1;
> send_resp.infos[0].rfa2=2;
> send_resp.infos[0].tsep=1;
> send_resp.infos[0].media_type=0;
>
> if(write(cmdfd,&send_resp,sizeof(send_resp))!=sizeof(send_resp)) {
> fprintf(stderr,"\nCould not send discover response\n");
> close(cmdfd);
> exit(-1);
> }
> else printf("\nSent Stream End Point Discovery Response\n");
>
>
> //Now read the get capablities request from the source
>
> struct getcap_req get_req;
> memset(&get_req,0,sizeof(get_req));
> if(read(cmdfd,&get_req,sizeof(get_req))!=sizeof(get_req) || (get_req.header.signal_id!=AVDTP_GET_CAPABILITIES)) {
> fprintf(stderr,"\nDidn't get a get cap req");
> }
> else printf("\nGot a get capabilities request\n");
>
> //Send a get cap resp
> struct getcap_resp cap_resp;
> memset(&cap_resp,0,sizeof(cap_resp));
> init_request(&cap_resp.header,AVDTP_GET_CAPABILITIES);
> //Fill in the values of the structure
> cap_resp.serv_cap=MEDIA_TRANSPORT_CATEGORY;
> cap_resp.serv_cap_len=0;
> cap_resp.cap_type=MEDIA_CODEC;
> cap_resp.media_type=AUDIO_MEDIA_TYPE;
> cap_resp.length=6;
> cap_resp.media_codec_type=SBC_MEDIA_CODEC_TYPE;
> cap_resp.sbc_elements.channel_mode=15;
> cap_resp.sbc_elements.frequency=15;
> cap_resp.sbc_elements.allocation_method=3;
> cap_resp.sbc_elements.subbands=3;
> cap_resp.sbc_elements.min_bitpool=2;
> cap_resp.sbc_elements.max_bitpool=250;
> cap_resp.sbc_elements.block_length=15;
>
> if(write(cmdfd,&cap_resp,sizeof(cap_resp))<sizeof(cap_resp)) {
> fprintf(stderr,"couldn't reply the caps\n");
> }
> else printf("\nSent the get capabilities response");
>
> //Now read the set config req
>
> struct set_config s_config;
>
> if(read(cmdfd,&s_config,sizeof(s_config))!=sizeof(s_config) || (s_config.header.signal_id!=AVDTP_SET_CONFIGURATION)) {
> fprintf(stderr,"couldn't get a set configurations request\n");
> }
> else printf("\nGot a set configurations request\n");
>
> //Now send the set config resp
>
> struct set_config_resp s_resp;
> //Fill in the values of the structure
> memset(&s_resp,0,sizeof(s_resp));
> init_request(&s_resp.header,AVDTP_SET_CONFIGURATION);
> s_resp.header.signal_id=AVDTP_SET_CONFIGURATION;
> s_resp.header.message_type=MESSAGE_TYPE_ACCEPT;
> if(write(cmdfd,&s_resp,sizeof(s_resp))!=sizeof(s_resp)) {
> fprintf(stderr,"couldn't send set config resp\n");
> }
> else printf("\nSent a Set configurations response\n");
>
>
> struct open_stream_cmd open_stream;
> memset(&open_stream, 0, sizeof(open_stream));
>
> if ((read(cmdfd, &open_stream, sizeof(open_stream)) != sizeof(open_stream)) || (open_stream.header.signal_id!=AVDTP_OPEN)){
> printf("\nDidn't receive an open stream command\n");
> return (-1);
> }
>
> printf("\nReceived an open stream command\n");
>
> struct open_stream_rsp open_resp;
> memset(&open_resp,0,sizeof(open_resp));
> init_request(&open_resp.header,AVDTP_OPEN);
> open_resp.header.signal_id=AVDTP_OPEN;
> open_resp.header.message_type=MESSAGE_TYPE_ACCEPT;
> if (write(cmdfd, &open_resp, sizeof(open_resp)) < sizeof(open_resp)) {
> fprintf(stderr, "couldn't send open stream response confirm for seid = %d\n", open_stream.acp_seid);
> return (-1);
> }
>
> printf("\nSent open stream confirm\n");
>
> // open the stream l2cap
>
> mtu = 48;
> socklen_t addrlen;
> struct sockaddr_l2 addr;
> memset(&addr, 0, sizeof(addr));
> addrlen = sizeof(addr);
>
> streamfd = accept(sk, (struct sockaddr *) &addr, &addrlen);
>
> if (streamfd < 0) {
> fprintf(stderr, "cannot open psm_stream = %d\n", psm_stream);
> exit(-1);
> }
> else printf("\nConnected on the streamfd channel");
>
> // start the stream
>
> struct start_stream_cmd start_stream;
> memset(&start_stream, 0, sizeof(start_stream));
>
> //Read the start stream command
> if (read(cmdfd, &start_stream, sizeof(start_stream)) != sizeof(start_stream) || (start_stream.header.signal_id!=AVDTP_START)) {
> fprintf(stderr, "\nDid not get a start stream command\n");
> close(streamfd);
> close(cmdfd);
> exit(-1);
> }
>
> else printf("\nGot a stream-start command\n");
>
> //Give the start stream response
> struct start_stream_rsp start_resp;
> //Fill in the values of the structure
> memset(&start_resp,0,sizeof(start_resp));
> init_request(&start_resp.header,AVDTP_START);
> if (write(cmdfd, &start_resp, sizeof(start_resp)) < sizeof(start_resp)) {
> fprintf(stderr, "Couldn't send start stream command confirm");
> close(streamfd);
> close(cmdfd);
> return (-1);
> }
>
> else printf("\nSent start stream confirm\n");
>
> char buf[BUFS];
> int psize;
>
> if (mtu > BUFS)
> mtu = BUFS;
>
> terminate = 0;
> seq_num = 1;
>
> sbc_init(&sbc,SBC_NULL);
> struct media_packet_header packet_header;
> struct media_payload_header payload_header;
> memset(&payload_header, 0, sizeof(payload_header));
> int packsize; //Size of the packet that is read
> timestamp = 0;
> packsize=read(streamfd,buf,1024);
> decode(buf+(sizeof(packet_header)+sizeof(payload_header)),(packsize-sizeof(packet_header)-sizeof(payload_header)));
>
> printf("Channels=%d,speed=%d",channels,speed);
> struct close_stream_cmd close_stream;
> memset(&close_stream,0,sizeof(close_stream));
> while (!terminate) {
>
> packsize=read(streamfd, buf,1024);
> if(packsize < 0)
> break;
> printf("\nRead:%d bytes",packsize);
>
> decode(buf+(sizeof(packet_header)+sizeof(payload_header)),(packsize-sizeof(packet_header)-sizeof(payload_header)));
>
> seq_num++;
> }
> sbc_finish(&sbc);
>
> printf("Received %d packets\n", seq_num);
>
> // signal the stream close
>
> if (read(cmdfd, &close_stream, sizeof(close_stream)) != sizeof(close_stream)) {
> fprintf(stderr, "couldn't get close_stream\n");
> close(streamfd);
> close(cmdfd);
> exit(-1);
> }
>
> if(close_stream.header.signal_id==AVDTP_CLOSE) {
> printf("Got stream-close\n");
> struct close_stream_rsp close_resp;
> init_request(&close_resp.header,AVDTP_CLOSE);
> if (write(cmdfd, &close_resp, sizeof(close_resp)) < sizeof(close_resp)) {
> fprintf(stderr, "Couldn't send close_resp confirm \n");
> close(streamfd);
> close(cmdfd);
> return (-1);
> }
> else printf("Sent close stream confirm\n");
> }
> else {
> printf("\nDidnt get a stream close as expected");
> close(streamfd);
> close(cmdfd);
> exit(-1);
> }
> closesound();
> close(streamfd);
> close(cmdfd);
>
> return 0;
> }
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
next prev parent reply other threads:[~2005-04-25 3:24 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-24 15:09 [Bluez-devel] A2DP sink code finally Mayank Batra
2005-04-25 3:24 ` Brad Midgley [this message]
2005-04-25 3:58 ` Brad Midgley
2005-04-25 6:08 ` Henryk Plötz
2005-04-25 14:40 ` Brad Midgley
2005-04-26 12:23 ` Mayank Batra
-- strict thread matches above, loose matches on Subject: below --
2005-04-26 12:29 Mayank Batra
2005-04-26 12:34 Mayank Batra
2005-04-27 16:27 ` Brad Midgley
2005-05-01 15:16 ` Henryk Plötz
2005-05-03 13:23 ` Mayank Batra
2005-04-26 12:35 Mayank Batra
2005-04-26 13:10 ` Brad Midgley
2005-04-26 15:50 ` Marcel Holtmann
2005-04-27 19:08 ` Brad Midgley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=426C62D4.80009@xmission.com \
--to=bmidgley@xmission.com \
--cc=bluez-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox