diff options
| -rw-r--r-- | audio/ipc.c | 49 | ||||
| -rw-r--r-- | audio/ipc.h | 190 | ||||
| -rw-r--r-- | audio/unix.c | 361 | 
3 files changed, 345 insertions, 255 deletions
| diff --git a/audio/ipc.c b/audio/ipc.c index a4561f47..67785309 100644 --- a/audio/ipc.c +++ b/audio/ipc.c @@ -22,22 +22,26 @@  #include "ipc.h" -/* This table contains the string representation for messages */ -static const char *strmsg[] = { -	"BT_GETCAPABILITIES_REQ", -	"BT_GETCAPABILITIES_RSP", -	"BT_SETCONFIGURATION_REQ", -	"BT_SETCONFIGURATION_RSP", -	"BT_STREAMSTART_REQ", -	"BT_STREAMSTART_RSP", -	"BT_STREAMSTOP_REQ", -	"BT_STREAMSTOP_RSP", -	"BT_STREAMSUSPEND_IND", -	"BT_STREAMRESUME_IND", -	"BT_CONTROL_REQ", -	"BT_CONTROL_RSP", -	"BT_CONTROL_IND", -	"BT_STREAMFD_IND", +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +/* This table contains the string representation for messages types */ +static const char *strtypes[] = { +	"BT_REQUEST", +	"BT_RESPONSE", +	"BT_INDICATION", +	"BT_ERROR", +}; + +/* This table contains the string representation for messages names */ +static const char *strnames[] = { +	"BT_GET_CAPABILITIES", +	"BT_SET_CONFIGURATION", +	"BT_NEW_STREAM", +	"BT_START_STREAM", +	"BT_STOP_STREAM", +	"BT_SUSPEND_STREAM", +	"BT_RESUME_STREAM", +	"BT_CONTROL",  };  int bt_audio_service_open(void) @@ -109,11 +113,18 @@ int bt_audio_service_get_data_fd(int sk)  	return -1;  } -const char *bt_audio_strmsg(int type) +const char *bt_audio_strtype(uint8_t type)  { -	if (type < 0 || type > (sizeof(strmsg) / sizeof(strmsg[0]))) +	if (type >= ARRAY_SIZE(strtypes))  		return NULL; -	return strmsg[type]; +	return strtypes[type];  } +const char *bt_audio_strname(uint8_t name) +{ +	if (name >= ARRAY_SIZE(strnames)) +		return NULL; + +	return strnames[name]; +} diff --git a/audio/ipc.h b/audio/ipc.h index ae85e727..0e985c3a 100644 --- a/audio/ipc.h +++ b/audio/ipc.h @@ -23,36 +23,36 @@  /*    Message sequence chart of streaming sequence for A2DP transport -  Audio daemon                       User -                             on snd_pcm_open -                 <--BT_GETCAPABILITIES_REQ +  Audio daemon			User +				on snd_pcm_open +				<--BT_GET_CAPABILITIES_REQ -  BT_GETCAPABILITIES_RSP--> +  BT_GET_CAPABILITIES_RSP--> -                        on snd_pcm_hw_params -                <--BT_SETCONFIGURATION_REQ +				on snd_pcm_hw_params +				<--BT_SETCONFIGURATION_REQ -  BT_SETCONFIGURATION_RSP--> +  BT_SET_CONFIGURATION_RSP--> -			on snd_pcm_prepare -                <--BT_STREAMSTART_REQ +				on snd_pcm_prepare +				<--BT_START_STREAM_REQ    <Moves to streaming state> -  BT_STREAMSTART_RSP--> +  BT_START_STREAM_RSP--> -  BT_STREAMFD_IND --> +  BT_NEW_STREAM_IND --> -                          <  streams data > -                             .......... +				<  streams data > +				.......... -               on snd_pcm_drop/snd_pcm_drain +				on snd_pcm_drop/snd_pcm_drain -                <--BT_STREAMSTOP_REQ +				<--BT_STOP_STREAM_REQ    <Moves to open state> -  BT_STREAMSTOP_RSP--> +  BT_STOP_STREAM_RSP--> -			on IPC close or appl crash +				on IPC close or appl crash    <Moves to idle>   */ @@ -71,43 +71,36 @@ extern "C" {  #include <sys/un.h>  #include <errno.h> -#define BT_AUDIO_IPC_PACKET_SIZE   128 +#define BT_SUGGESTED_BUFFER_SIZE   128  #define BT_IPC_SOCKET_NAME "\0/org/bluez/audio" -/* Generic message header definition, except for RSP messages */ +/* Generic message header definition, except for RESPONSE messages */  typedef struct { -	uint8_t msg_type; +	uint8_t type; +	uint8_t name; +	uint16_t length;  } __attribute__ ((packed)) bt_audio_msg_header_t; -/* Generic message header definition, for all RSP messages */  typedef struct { -	bt_audio_msg_header_t	msg_h; -	uint8_t			posix_errno; -} __attribute__ ((packed)) bt_audio_rsp_msg_header_t; - -/* Messages list */ -#define BT_GETCAPABILITIES_REQ		0 -#define BT_GETCAPABILITIES_RSP		1 - -#define BT_SETCONFIGURATION_REQ		2 -#define BT_SETCONFIGURATION_RSP		3 - -#define BT_STREAMSTART_REQ		4 -#define BT_STREAMSTART_RSP		5 - -#define BT_STREAMSTOP_REQ		6 -#define BT_STREAMSTOP_RSP		7 - -#define BT_STREAMSUSPEND_IND		8 -#define BT_STREAMRESUME_IND		9 - -#define BT_CONTROL_REQ		       10 -#define BT_CONTROL_RSP		       11 -#define BT_CONTROL_IND		       12 - -#define BT_STREAMFD_IND		       13 - -/* BT_GETCAPABILITIES_REQ */ +	bt_audio_msg_header_t h; +	uint8_t posix_errno; +} __attribute__ ((packed)) bt_audio_error_t; + +/* Message types */ +#define BT_REQUEST			0 +#define BT_RESPONSE			1 +#define BT_INDICATION			2 +#define BT_ERROR			3 + +/* Messages names */ +#define BT_GET_CAPABILITIES		0 +#define BT_SET_CONFIGURATION		1 +#define BT_NEW_STREAM			2 +#define BT_START_STREAM			3 +#define BT_STOP_STREAM			4 +#define BT_SUSPEND_STREAM		5 +#define BT_RESUME_STREAM		6 +#define BT_CONTROL			7  #define BT_CAPABILITIES_TRANSPORT_A2DP	0  #define BT_CAPABILITIES_TRANSPORT_SCO	1 @@ -119,19 +112,22 @@ typedef struct {  #define BT_FLAG_AUTOCONNECT	1 -struct bt_getcapabilities_req { +struct bt_get_capabilities_req {  	bt_audio_msg_header_t	h;  	char			device[18];	/* Address of the remote Device */  	uint8_t			transport;	/* Requested transport */  	uint8_t			flags;		/* Requested flags */  } __attribute__ ((packed)); -/* BT_GETCAPABILITIES_RSP */ -  /**   * SBC Codec parameters as per A2DP profile 1.0 ยง 4.3   */ +#define BT_A2DP_CODEC_SBC			0x00 +#define BT_A2DP_CODEC_MPEG12			0x01 +#define BT_A2DP_CODEC_MPEG24			0x02 +#define BT_A2DP_CODEC_ATRAC			0x03 +  #define BT_SBC_SAMPLING_FREQ_16000		(1 << 3)  #define BT_SBC_SAMPLING_FREQ_32000		(1 << 2)  #define BT_SBC_SAMPLING_FREQ_44100		(1 << 1) @@ -164,7 +160,19 @@ struct bt_getcapabilities_req {  #define BT_MPEG_LAYER_2				(1 << 1)  #define BT_MPEG_LAYER_3				1 +#define BT_HFP_CODEC_PCM			0x00 + +#define BT_PCM_FLAG_NREC			1 + +typedef struct { +	uint8_t transport; +	uint8_t type; +	uint8_t length; +	uint8_t data[0]; +} __attribute__ ((packed)) codec_capabilities_t; +  typedef struct { +	codec_capabilities_t capability;  	uint8_t channel_mode;  	uint8_t frequency;  	uint8_t allocation_method; @@ -175,6 +183,7 @@ typedef struct {  } __attribute__ ((packed)) sbc_capabilities_t;  typedef struct { +	codec_capabilities_t capability;  	uint8_t channel_mode;  	uint8_t crc;  	uint8_t layer; @@ -183,75 +192,65 @@ typedef struct {  	uint16_t bitrate;  } __attribute__ ((packed)) mpeg_capabilities_t; -struct bt_getcapabilities_rsp { -	bt_audio_rsp_msg_header_t	rsp_h; -	uint8_t				transport;	   /* Granted transport */ -	sbc_capabilities_t		sbc_capabilities;  /* A2DP only */ -	mpeg_capabilities_t		mpeg_capabilities; /* A2DP only */ -	uint16_t			sampling_rate;	   /* SCO only */ +typedef struct { +	codec_capabilities_t capability; +	uint8_t flags; +	uint16_t sampling_rate; +} __attribute__ ((packed)) pcm_capabilities_t; + + +struct bt_get_capabilities_rsp { +	bt_audio_msg_header_t	h; +	uint8_t			data[0];	/* First codec_capabilities_t */  } __attribute__ ((packed)); -/* BT_SETCONFIGURATION_REQ */ -struct bt_setconfiguration_req { +struct bt_set_configuration_req {  	bt_audio_msg_header_t	h; -	char			device[18];		/* Address of the remote Device */ -	uint8_t			transport;		/* Requested transport */ -	uint8_t			access_mode;		/* Requested access mode */ -	sbc_capabilities_t	sbc_capabilities;	/* A2DP only - only one of this field -							and next one must be filled */ -	mpeg_capabilities_t	mpeg_capabilities;	/* A2DP only */ +	char			device[18];	/* Address of the remote Device */ +	uint8_t			access_mode;	/* Requested access mode */ +	codec_capabilities_t	codec;		/* Requested codec */  } __attribute__ ((packed)); -/* BT_SETCONFIGURATION_RSP */ -struct bt_setconfiguration_rsp { -	bt_audio_rsp_msg_header_t	rsp_h; -	uint8_t				transport;	/* Granted transport */ -	uint8_t				access_mode;	/* Granted access mode */ -	uint16_t			link_mtu;	/* Max length that transport supports */ +struct bt_set_configuration_rsp { +	bt_audio_msg_header_t	h; +	uint8_t			transport;	/* Granted transport */ +	uint8_t			access_mode;	/* Granted access mode */ +	uint16_t		link_mtu;	/* Max length that transport supports */  } __attribute__ ((packed)); -/* BT_STREAMSTART_REQ */  #define BT_STREAM_ACCESS_READ		0  #define BT_STREAM_ACCESS_WRITE		1  #define BT_STREAM_ACCESS_READWRITE	2 -struct bt_streamstart_req { +struct bt_start_stream_req {  	bt_audio_msg_header_t	h;  } __attribute__ ((packed)); -/* BT_STREAMSTART_RSP */ -struct bt_streamstart_rsp { -	bt_audio_rsp_msg_header_t	rsp_h; +struct bt_start_stream_rsp { +	bt_audio_msg_header_t	h;  } __attribute__ ((packed)); -/* BT_STREAMFD_IND */  /* This message is followed by one byte of data containing the stream data fd     as ancilliary data */ -struct bt_streamfd_ind { +struct bt_new_stream_ind {  	bt_audio_msg_header_t	h;  } __attribute__ ((packed)); -/* BT_STREAMSTOP_REQ */ -struct bt_streamstop_req { +struct bt_stop_stream_req {  	bt_audio_msg_header_t	h;  } __attribute__ ((packed)); -/* BT_STREAMSTOP_RSP */ -struct bt_streamstop_rsp { -	bt_audio_rsp_msg_header_t	rsp_h; +struct bt_stop_stream_rsp { +	bt_audio_msg_header_t	h;  } __attribute__ ((packed)); -/* BT_STREAMSUSPEND_IND */ -struct bt_streamsuspend_ind { +struct bt_suspend_stream_ind {  	bt_audio_msg_header_t	h;  } __attribute__ ((packed)); -/* BT_STREAMRESUME_IND */ -struct bt_streamresume_ind { +struct bt_resume_stream_ind {  	bt_audio_msg_header_t	h;  } __attribute__ ((packed)); -/* BT_CONTROL_REQ */ -  #define BT_CONTROL_KEY_POWER			0x40  #define BT_CONTROL_KEY_VOL_UP			0x41  #define BT_CONTROL_KEY_VOL_DOWN			0x42 @@ -272,14 +271,12 @@ struct bt_control_req {  	uint8_t			key;		/* Control Key */  } __attribute__ ((packed)); -/* BT_CONTROL_RSP */  struct bt_control_rsp { -	bt_audio_rsp_msg_header_t	rsp_h; -	uint8_t				mode;	/* Control Mode */ -	uint8_t				key;	/* Control Key */ +	bt_audio_msg_header_t	h; +	uint8_t			mode;		/* Control Mode */ +	uint8_t			key;		/* Control Key */  } __attribute__ ((packed)); -/* BT_CONTROL_IND */  struct bt_control_ind {  	bt_audio_msg_header_t	h;  	uint8_t			mode;		/* Control Mode */ @@ -299,7 +296,10 @@ BT_STREAMFD_IND message is returned */  int bt_audio_service_get_data_fd(int sk);  /* Human readable message type string */ -const char *bt_audio_strmsg(int type); +const char *bt_audio_strtype(uint8_t type); + +/* Human readable message name string */ +const char *bt_audio_strname(uint8_t name);  #ifdef __cplusplus  } diff --git a/audio/unix.c b/audio/unix.c index 921e15ef..bf0dad47 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -152,25 +152,31 @@ static int unix_sendmsg_fd(int sock, int fd)  static void unix_ipc_sendmsg(struct unix_client *client,  					const bt_audio_msg_header_t *msg)  { -	debug("Audio API: sending %s", bt_audio_strmsg(msg->msg_type)); +	const char *type = bt_audio_strtype(msg->type); +	const char *name = bt_audio_strname(msg->name); -	if (send(client->sock, msg, BT_AUDIO_IPC_PACKET_SIZE, 0) < 0) +	debug("Audio API: %s -> %s", type, name); + +	if (send(client->sock, msg, msg->length, 0) < 0)  		error("Error %s(%d)", strerror(errno), errno);  } -static void unix_ipc_error(struct unix_client *client, int type, int err) +static void unix_ipc_error(struct unix_client *client, uint8_t name, int err)  { -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	bt_audio_rsp_msg_header_t *rsp_hdr = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	bt_audio_error_t *rsp = (void *) buf;  	if (!g_slist_find(clients, client))  		return;  	memset(buf, 0, sizeof(buf)); -	rsp_hdr->msg_h.msg_type = type; -	rsp_hdr->posix_errno = err; +	rsp->h.type = BT_ERROR; +	rsp->h.name = name; +	rsp->h.length = sizeof(*rsp); + +	rsp->posix_errno = err; -	unix_ipc_sendmsg(client, &rsp_hdr->msg_h); +	unix_ipc_sendmsg(client, &rsp->h);  }  static service_type_t select_service(struct audio_device *dev, const char *interface) @@ -223,8 +229,10 @@ static void stream_state_changed(struct avdtp_stream *stream,  static void headset_discovery_complete(struct audio_device *dev, void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_getcapabilities_rsp *rsp = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_get_capabilities_rsp *rsp = (void *) buf; +	codec_capabilities_t *codec; +	pcm_capabilities_t *pcm;  	client->req_id = 0; @@ -233,24 +241,34 @@ static void headset_discovery_complete(struct audio_device *dev, void *user_data  	memset(buf, 0, sizeof(buf)); -	rsp->rsp_h.msg_h.msg_type = BT_GETCAPABILITIES_RSP; -	rsp->transport  = BT_CAPABILITIES_TRANSPORT_SCO; -	rsp->sampling_rate = 8000; +	codec = (void *) rsp->data; +	codec->transport = BT_CAPABILITIES_TRANSPORT_SCO; +	codec->type = BT_HFP_CODEC_PCM; +	codec->length = sizeof(*pcm); + +	pcm = (void *) codec; +	pcm->sampling_rate = 8000; +	if (headset_get_nrec(dev)) +		pcm->flags |= BT_PCM_FLAG_NREC; + +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_GET_CAPABILITIES; +	rsp->h.length = sizeof(*rsp) + codec->length; -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	unix_ipc_sendmsg(client, &rsp->h);  	return;  failed:  	error("discovery failed"); -	unix_ipc_error(client, BT_SETCONFIGURATION_RSP, EIO); +	unix_ipc_error(client, BT_SET_CONFIGURATION, EIO);  }  static void headset_setup_complete(struct audio_device *dev, void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_setconfiguration_rsp *rsp = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_set_configuration_rsp *rsp = (void *) buf;  	client->req_id = 0; @@ -259,28 +277,31 @@ static void headset_setup_complete(struct audio_device *dev, void *user_data)  	memset(buf, 0, sizeof(buf)); -	rsp->rsp_h.msg_h.msg_type = BT_SETCONFIGURATION_RSP; +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_SET_CONFIGURATION; +	rsp->h.length = sizeof(*rsp); +  	rsp->transport  = BT_CAPABILITIES_TRANSPORT_SCO;  	rsp->access_mode = client->access_mode;  	rsp->link_mtu = 48;  	client->data_fd = headset_get_sco_fd(dev); -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	unix_ipc_sendmsg(client, &rsp->h);  	return;  failed:  	error("config failed"); -	unix_ipc_error(client, BT_SETCONFIGURATION_RSP, EIO); +	unix_ipc_error(client, BT_SET_CONFIGURATION, EIO);  }  static void headset_resume_complete(struct audio_device *dev, void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_streamstart_rsp *rsp = (void *) buf; -	struct bt_streamfd_ind *ind = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_start_stream_rsp *rsp = (void *) buf; +	struct bt_new_stream_ind *ind = (void *) buf;  	struct headset_data *hs = &client->d.hs;  	client->req_id = 0; @@ -294,13 +315,17 @@ static void headset_resume_complete(struct audio_device *dev, void *user_data)  	}  	memset(buf, 0, sizeof(buf)); +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_START_STREAM; +	rsp->h.length = sizeof(*rsp); -	rsp->rsp_h.msg_h.msg_type = BT_STREAMSTART_RSP; - -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	unix_ipc_sendmsg(client, &rsp->h);  	memset(buf, 0, sizeof(buf)); -	ind->h.msg_type = BT_STREAMFD_IND; +	ind->h.type = BT_INDICATION; +	ind->h.name = BT_NEW_STREAM; +	ind->h.length = sizeof(*ind); +  	unix_ipc_sendmsg(client, &ind->h);  	client->data_fd = headset_get_sco_fd(dev); @@ -315,41 +340,105 @@ static void headset_resume_complete(struct audio_device *dev, void *user_data)  failed:  	error("headset_resume_complete: resume failed"); -	unix_ipc_error(client, BT_STREAMSTART_RSP, EIO); +	unix_ipc_error(client, BT_START_STREAM, EIO);  }  static void headset_suspend_complete(struct audio_device *dev, void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_streamstart_rsp *rsp = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_start_stream_rsp *rsp = (void *) buf;  	if (!dev)  		goto failed;  	memset(buf, 0, sizeof(buf)); -	rsp->rsp_h.msg_h.msg_type = BT_STREAMSTOP_RSP; -	rsp->rsp_h.posix_errno = 0; -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_STOP_STREAM; +	rsp->h.length = sizeof(*rsp); + +	unix_ipc_sendmsg(client, &rsp->h);  	return;  failed:  	error("suspend failed"); -	unix_ipc_error(client, BT_STREAMSTOP_RSP, EIO); +	unix_ipc_error(client, BT_STOP_STREAM, EIO);  	client->dev = NULL;  } +static int a2dp_append_codec(struct bt_get_capabilities_rsp *rsp, +				struct avdtp_service_capability *cap) +{ +	struct avdtp_media_codec_capability *codec_cap = (void *) cap->data; +	codec_capabilities_t *codec = (void *) rsp + rsp->h.length; +	int space_left = BT_SUGGESTED_BUFFER_SIZE - rsp->h.length; + +	if (space_left <= 0) +		return -ENOMEM; + +	/* endianess prevent direct cast */ +	if (codec_cap->media_codec_type == A2DP_CODEC_SBC) { +		struct sbc_codec_cap *sbc_cap = (void *) codec_cap; +		sbc_capabilities_t *sbc = (void *) codec; + +		if (space_left - sizeof(sbc_capabilities_t) < 0) +			return -ENOMEM; + +		codec->length = sizeof(sbc_capabilities_t); + +		sbc->channel_mode = sbc_cap->channel_mode; +		sbc->frequency = sbc_cap->frequency; +		sbc->allocation_method = sbc_cap->allocation_method; +		sbc->subbands = sbc_cap->subbands; +		sbc->block_length = sbc_cap->block_length; +		sbc->min_bitpool = sbc_cap->min_bitpool; +		sbc->max_bitpool = sbc_cap->max_bitpool; +	} else if (codec_cap->media_codec_type == A2DP_CODEC_MPEG12) { +		struct mpeg_codec_cap *mpeg_cap = (void *) codec_cap; +		mpeg_capabilities_t *mpeg = (void *) codec; + +		if (space_left - sizeof(mpeg_capabilities_t) < 0) +			return -ENOMEM; + +		codec->length = sizeof(mpeg_capabilities_t); + +		mpeg->channel_mode = mpeg_cap->channel_mode; +		mpeg->crc = mpeg_cap->crc; +		mpeg->layer = mpeg_cap->layer; +		mpeg->frequency = mpeg_cap->frequency; +		mpeg->mpf = mpeg_cap->mpf; +		mpeg->bitrate = mpeg_cap->bitrate; +	} else { +		int codec_length; + +		codec_length = cap->length - (sizeof(struct avdtp_service_capability) +				+ sizeof(struct avdtp_media_codec_capability)); + +		if (space_left - (codec_length + sizeof(codec_capabilities_t)) < 0) +			return -ENOMEM; + +		codec->length = codec_length + sizeof(codec_capabilities_t); +		memcpy(codec->data, codec_cap->data, codec_length); +	} + +	codec->type = codec_cap->media_codec_type; +	rsp->h.length += codec->length; + +	debug("Append codec %d - length %d - total %d", codec->type, +			codec->length, rsp->h.length); + +	return 0; +} +  static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,  					struct avdtp_error *err,  					void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_getcapabilities_rsp *rsp = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_get_capabilities_rsp *rsp = (void *) buf;  	struct a2dp_data *a2dp = &client->d.a2dp; -	struct sbc_codec_cap *sbc_cap = NULL; -	struct mpeg_codec_cap *mpeg_cap = NULL;  	GSList *l;  	if (!g_slist_find(clients, client)) { @@ -363,55 +452,29 @@ static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,  	memset(buf, 0, sizeof(buf));  	client->req_id = 0; -	rsp->rsp_h.msg_h.msg_type = BT_GETCAPABILITIES_RSP; -	rsp->transport = BT_CAPABILITIES_TRANSPORT_A2DP; +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_GET_CAPABILITIES; +	rsp->h.length = sizeof(*rsp);  	for (l = seps; l; l = g_slist_next(l)) {  		struct avdtp_remote_sep *rsep = l->data;  		struct avdtp_service_capability *cap; -		struct avdtp_media_codec_capability *codec_cap;  		cap = avdtp_get_codec(rsep);  		if (cap->category != AVDTP_MEDIA_CODEC)  			continue; -		codec_cap = (void *) cap->data; - -		if (codec_cap->media_codec_type == A2DP_CODEC_SBC && !sbc_cap) -			sbc_cap = (void *) codec_cap; - -		if (codec_cap->media_codec_type == A2DP_CODEC_MPEG12 && !mpeg_cap) -			mpeg_cap = (void *) codec_cap; +		a2dp_append_codec(rsp, cap);  	} -	/* endianess prevent direct cast */ -	if (sbc_cap) { -		rsp->sbc_capabilities.channel_mode = sbc_cap->channel_mode; -		rsp->sbc_capabilities.frequency = sbc_cap->frequency; -		rsp->sbc_capabilities.allocation_method = sbc_cap->allocation_method; -		rsp->sbc_capabilities.subbands = sbc_cap->subbands; -		rsp->sbc_capabilities.block_length = sbc_cap->block_length; -		rsp->sbc_capabilities.min_bitpool = sbc_cap->min_bitpool; -		rsp->sbc_capabilities.max_bitpool = sbc_cap->max_bitpool; -	} - -	if (mpeg_cap) { -		rsp->mpeg_capabilities.channel_mode = mpeg_cap->channel_mode; -		rsp->mpeg_capabilities.crc = mpeg_cap->crc; -		rsp->mpeg_capabilities.layer = mpeg_cap->layer; -		rsp->mpeg_capabilities.frequency = mpeg_cap->frequency; -		rsp->mpeg_capabilities.mpf = mpeg_cap->mpf; -		rsp->mpeg_capabilities.bitrate = mpeg_cap->bitrate; -	} - -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	unix_ipc_sendmsg(client, &rsp->h);  	return;  failed:  	error("discovery failed"); -	unix_ipc_error(client, BT_GETCAPABILITIES_RSP, EIO); +	unix_ipc_error(client, BT_GET_CAPABILITIES, EIO);  	avdtp_unref(a2dp->session); @@ -425,8 +488,8 @@ static void a2dp_config_complete(struct avdtp *session, struct a2dp_sep *sep,  					void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_setconfiguration_rsp *rsp = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_set_configuration_rsp *rsp = (void *) buf;  	struct a2dp_data *a2dp = &client->d.a2dp;  	uint16_t imtu, omtu;  	GSList *caps; @@ -454,14 +517,17 @@ static void a2dp_config_complete(struct avdtp *session, struct a2dp_sep *sep,  		goto failed;  	} -	rsp->rsp_h.msg_h.msg_type = BT_SETCONFIGURATION_RSP; +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_SET_CONFIGURATION; +	rsp->h.length = sizeof(*rsp); +  	rsp->transport = BT_CAPABILITIES_TRANSPORT_A2DP;  	client->access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE;  	rsp->access_mode = client->access_mode;  	/* FIXME: Use imtu when fd_opt is CFG_FD_OPT_READ */  	rsp->link_mtu = omtu; -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	unix_ipc_sendmsg(client, &rsp->h);  	client->cb_id = avdtp_stream_add_cb(session, stream,  						stream_state_changed, client); @@ -475,7 +541,7 @@ failed:  		a2dp_sep_unlock(a2dp->sep, a2dp->session);  		a2dp->sep = NULL;  	} -	unix_ipc_error(client, BT_SETCONFIGURATION_RSP, EIO); +	unix_ipc_error(client, BT_SET_CONFIGURATION, EIO);  	avdtp_unref(a2dp->session); @@ -487,21 +553,26 @@ static void a2dp_resume_complete(struct avdtp *session,  				struct avdtp_error *err, void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_streamstart_rsp *rsp = (void *) buf; -	struct bt_streamfd_ind *ind = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_start_stream_rsp *rsp = (void *) buf; +	struct bt_new_stream_ind *ind = (void *) buf;  	struct a2dp_data *a2dp = &client->d.a2dp;  	if (err)  		goto failed;  	memset(buf, 0, sizeof(buf)); -	rsp->rsp_h.msg_h.msg_type = BT_STREAMSTART_RSP; -	rsp->rsp_h.posix_errno = 0; -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_START_STREAM; +	rsp->h.length = sizeof(*rsp); + +	unix_ipc_sendmsg(client, &rsp->h);  	memset(buf, 0, sizeof(buf)); -	ind->h.msg_type = BT_STREAMFD_IND; +	ind->h.type = BT_RESPONSE; +	ind->h.name = BT_NEW_STREAM; +	rsp->h.length = sizeof(*ind); +  	unix_ipc_sendmsg(client, &ind->h);  	if (unix_sendmsg_fd(client->sock, client->data_fd) < 0) { @@ -518,7 +589,7 @@ failed:  		a2dp_sep_unlock(a2dp->sep, a2dp->session);  		a2dp->sep = NULL;  	} -	unix_ipc_error(client, BT_STREAMSTART_RSP, EIO); +	unix_ipc_error(client, BT_START_STREAM, EIO);  	if (client->cb_id > 0) {  		avdtp_stream_remove_cb(a2dp->session, a2dp->stream, @@ -536,17 +607,19 @@ static void a2dp_suspend_complete(struct avdtp *session,  				struct avdtp_error *err, void *user_data)  {  	struct unix_client *client = user_data; -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_streamstart_rsp *rsp = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_start_stream_rsp *rsp = (void *) buf;  	struct a2dp_data *a2dp = &client->d.a2dp;  	if (err)  		goto failed;  	memset(buf, 0, sizeof(buf)); -	rsp->rsp_h.msg_h.msg_type = BT_STREAMSTOP_RSP; -	rsp->rsp_h.posix_errno = 0; -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_STOP_STREAM; +	rsp->h.length = sizeof(*rsp); + +	unix_ipc_sendmsg(client, &rsp->h);  	return; @@ -557,7 +630,7 @@ failed:  		a2dp_sep_unlock(a2dp->sep, a2dp->session);  		a2dp->sep = NULL;  	} -	unix_ipc_error(client, BT_STREAMSTOP_RSP, EIO); +	unix_ipc_error(client, BT_STOP_STREAM, EIO);  	avdtp_unref(a2dp->session); @@ -604,7 +677,7 @@ static void start_discovery(struct audio_device *dev, struct unix_client *client  	return;  failed: -	unix_ipc_error(client, BT_GETCAPABILITIES_RSP, err ? : EIO); +	unix_ipc_error(client, BT_GET_CAPABILITIES, err ? : EIO);  }  static void start_config(struct audio_device *dev, struct unix_client *client) @@ -671,7 +744,7 @@ static void start_config(struct audio_device *dev, struct unix_client *client)  	return;  failed: -	unix_ipc_error(client, BT_SETCONFIGURATION_RSP, EIO); +	unix_ipc_error(client, BT_SET_CONFIGURATION, EIO);  }  static void start_resume(struct audio_device *dev, struct unix_client *client) @@ -726,7 +799,7 @@ static void start_resume(struct audio_device *dev, struct unix_client *client)  	return;  failed: -	unix_ipc_error(client, BT_STREAMSTART_RSP, EIO); +	unix_ipc_error(client, BT_START_STREAM, EIO);  }  static void start_suspend(struct audio_device *dev, struct unix_client *client) @@ -780,11 +853,11 @@ static void start_suspend(struct audio_device *dev, struct unix_client *client)  	return;  failed: -	unix_ipc_error(client, BT_STREAMSTOP_RSP, EIO); +	unix_ipc_error(client, BT_STOP_STREAM, EIO);  }  static void handle_getcapabilities_req(struct unix_client *client, -					struct bt_getcapabilities_req *req) +					struct bt_get_capabilities_req *req)  {  	struct audio_device *dev;  	bdaddr_t bdaddr; @@ -820,11 +893,11 @@ static void handle_getcapabilities_req(struct unix_client *client,  	return;  failed: -	unix_ipc_error(client, BT_GETCAPABILITIES_RSP, EIO); +	unix_ipc_error(client, BT_GET_CAPABILITIES, EIO);  }  static int handle_sco_transport(struct unix_client *client, -				struct bt_setconfiguration_req *req) +				struct bt_set_configuration_req *req)  {  	client->interface = g_strdup(AUDIO_HEADSET_INTERFACE); @@ -835,7 +908,7 @@ static int handle_sco_transport(struct unix_client *client,  }  static int handle_a2dp_transport(struct unix_client *client, -				struct bt_setconfiguration_req *req) +				struct bt_set_configuration_req *req)  {  	struct avdtp_service_capability *media_transport, *media_codec;  	struct sbc_codec_cap sbc_cap; @@ -856,18 +929,19 @@ static int handle_a2dp_transport(struct unix_client *client,  	debug("config a2dp - device = %s access_mode = %u", req->device,  			req->access_mode); -	if (req->mpeg_capabilities.frequency) { +	if (req->codec.type == BT_A2DP_CODEC_MPEG12) { +		mpeg_capabilities_t *mpeg = (void *) &req->codec;  		memset(&mpeg_cap, 0, sizeof(mpeg_cap));  		mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;  		mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12; -		mpeg_cap.channel_mode = req->mpeg_capabilities.channel_mode; -		mpeg_cap.crc = req->mpeg_capabilities.crc; -		mpeg_cap.layer = req->mpeg_capabilities.layer; -		mpeg_cap.frequency = req->mpeg_capabilities.frequency; -		mpeg_cap.mpf = req->mpeg_capabilities.mpf; -		mpeg_cap.bitrate = req->mpeg_capabilities.bitrate; +		mpeg_cap.channel_mode = mpeg->channel_mode; +		mpeg_cap.crc = mpeg->crc; +		mpeg_cap.layer = mpeg->layer; +		mpeg_cap.frequency = mpeg->frequency; +		mpeg_cap.mpf = mpeg->mpf; +		mpeg_cap.bitrate = mpeg->bitrate;  		media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap,  							sizeof(mpeg_cap)); @@ -877,18 +951,20 @@ static int handle_a2dp_transport(struct unix_client *client,  			mpeg_cap.frequency, mpeg_cap.channel_mode,  			mpeg_cap.layer, mpeg_cap.crc, mpeg_cap.mpf,  			mpeg_cap.bitrate); -	} else if (req->sbc_capabilities.frequency) { +	} else if (req->codec.type == BT_A2DP_CODEC_SBC) { +		sbc_capabilities_t *sbc = (void *) &req->codec; +  		memset(&sbc_cap, 0, sizeof(sbc_cap));  		sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;  		sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC; -		sbc_cap.channel_mode = req->sbc_capabilities.channel_mode; -		sbc_cap.frequency = req->sbc_capabilities.frequency; -		sbc_cap.allocation_method = req->sbc_capabilities.allocation_method; -		sbc_cap.subbands = req->sbc_capabilities.subbands; -		sbc_cap.block_length = req->sbc_capabilities.block_length; -		sbc_cap.min_bitpool = req->sbc_capabilities.min_bitpool; -		sbc_cap.max_bitpool = req->sbc_capabilities.max_bitpool; +		sbc_cap.channel_mode = sbc->channel_mode; +		sbc_cap.frequency = sbc->frequency; +		sbc_cap.allocation_method = sbc->allocation_method; +		sbc_cap.subbands = sbc->subbands; +		sbc_cap.block_length = sbc->block_length; +		sbc_cap.min_bitpool = sbc->min_bitpool; +		sbc_cap.max_bitpool = sbc->max_bitpool;  		media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,  							sizeof(sbc_cap)); @@ -908,7 +984,7 @@ static int handle_a2dp_transport(struct unix_client *client,  }  static void handle_setconfiguration_req(struct unix_client *client, -					struct bt_setconfiguration_req *req) +					struct bt_set_configuration_req *req)  {  	struct audio_device *dev;  	bdaddr_t bdaddr; @@ -926,13 +1002,13 @@ static void handle_setconfiguration_req(struct unix_client *client,  		client->interface = NULL;  	} -	if (req->transport == BT_CAPABILITIES_TRANSPORT_SCO) { +	if (req->codec.transport == BT_CAPABILITIES_TRANSPORT_SCO) {  		err = handle_sco_transport(client, req);  		if (err < 0) {  			err = -err;  			goto failed;  		} -	} else if (req->transport == BT_CAPABILITIES_TRANSPORT_A2DP) { +	} else if (req->codec.transport == BT_CAPABILITIES_TRANSPORT_A2DP) {  		err = handle_a2dp_transport(client, req);  		if (err < 0) {  			err = -err; @@ -957,11 +1033,11 @@ static void handle_setconfiguration_req(struct unix_client *client,  	return;  failed: -	unix_ipc_error(client, BT_SETCONFIGURATION_RSP, err ? : EIO); +	unix_ipc_error(client, BT_SET_CONFIGURATION, err ? : EIO);  }  static void handle_streamstart_req(struct unix_client *client, -					struct bt_streamstart_req *req) +					struct bt_start_stream_req *req)  {  	if (!client->dev)  		goto failed; @@ -971,11 +1047,11 @@ static void handle_streamstart_req(struct unix_client *client,  	return;  failed: -	unix_ipc_error(client, BT_STREAMSTART_REQ, EIO); +	unix_ipc_error(client, BT_START_STREAM, EIO);  }  static void handle_streamstop_req(struct unix_client *client, -					struct bt_streamstop_req *req) +					struct bt_stop_stream_req *req)  {  	if (!client->dev)  		goto failed; @@ -985,32 +1061,33 @@ static void handle_streamstop_req(struct unix_client *client,  	return;  failed: -	unix_ipc_error(client, BT_STREAMSTOP_REQ, EIO); +	unix_ipc_error(client, BT_STOP_STREAM, EIO);  }  static void handle_control_req(struct unix_client *client,  					struct bt_control_req *req)  {  	/* FIXME: really implement that */ -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; -	struct bt_setconfiguration_rsp *rsp = (void *) buf; +	char buf[BT_SUGGESTED_BUFFER_SIZE]; +	struct bt_set_configuration_rsp *rsp = (void *) buf;  	memset(buf, 0, sizeof(buf)); -	rsp->rsp_h.msg_h.msg_type = BT_CONTROL_RSP; -	rsp->rsp_h.posix_errno = 0; +	rsp->h.type = BT_RESPONSE; +	rsp->h.name = BT_CONTROL; +	rsp->h.length = sizeof(*rsp); -	unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h); +	unix_ipc_sendmsg(client, &rsp->h);  }  static gboolean client_cb(GIOChannel *chan, GIOCondition cond, gpointer data)  { -	char buf[BT_AUDIO_IPC_PACKET_SIZE]; +	char buf[BT_SUGGESTED_BUFFER_SIZE];  	bt_audio_msg_header_t *msghdr = (void *) buf;  	struct unix_client *client = data;  	int len;  	struct a2dp_data *a2dp = &client->d.a2dp;  	struct headset_data *hs = &client->d.hs; -	const char *type; +	const char *type, *name;  	if (cond & G_IO_NVAL)  		return FALSE; @@ -1046,33 +1123,35 @@ static gboolean client_cb(GIOChannel *chan, GIOCondition cond, gpointer data)  		goto failed;  	} -	if ((type = bt_audio_strmsg(msghdr->msg_type))) -		debug("Audio API: received %s", type); +	type = bt_audio_strtype(msghdr->type); +	name = bt_audio_strname(msghdr->name); + +	debug("Audio API: %s <- %s", type, name); -	switch (msghdr->msg_type) { -	case BT_GETCAPABILITIES_REQ: +	switch (msghdr->name) { +	case BT_GET_CAPABILITIES:  		handle_getcapabilities_req(client, -				(struct bt_getcapabilities_req *) msghdr); +				(struct bt_get_capabilities_req *) msghdr);  		break; -	case BT_SETCONFIGURATION_REQ: +	case BT_SET_CONFIGURATION:  		handle_setconfiguration_req(client, -				(struct bt_setconfiguration_req *) msghdr); +				(struct bt_set_configuration_req *) msghdr);  		break; -	case BT_STREAMSTART_REQ: +	case BT_START_STREAM:  		handle_streamstart_req(client, -				(struct bt_streamstart_req *) msghdr); +				(struct bt_start_stream_req *) msghdr);  		break; -	case BT_STREAMSTOP_REQ: +	case BT_STOP_STREAM:  		handle_streamstop_req(client, -				(struct bt_streamstop_req *) msghdr); +				(struct bt_stop_stream_req *) msghdr);  		break; -	case BT_CONTROL_REQ: +	case BT_CONTROL:  		handle_control_req(client,  				(struct bt_control_req *) msghdr);  		break;  	default: -		error("Audio API: received unexpected packet type %d", -				msghdr->msg_type); +		error("Audio API: received unexpected message name %d", +				msghdr->name);  	}  	return TRUE; | 
