diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-15 14:13:27 +0000 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-15 14:13:27 +0000 | 
| commit | 931bfd25641a14b82c6c82db20eeb97bc57fafe6 (patch) | |
| tree | e5f2598294463bb59c52f9b1a8fcce1d70bf8ff5 | |
| parent | 74e5259eb027bd0eaef50004ffe62de28d77e77b (diff) | |
Implement support for incoming suspend commands
| -rw-r--r-- | audio/avdtp.c | 62 | 
1 files changed, 59 insertions, 3 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c index f35ff5ff..bc9081a4 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -131,6 +131,12 @@ struct start_req {  	struct seid other_seids[0];  } __attribute__ ((packed)); +struct suspend_req { +	struct avdtp_header header; +	struct seid first_seid; +	struct seid other_seids[0]; +} __attribute__ ((packed)); +  struct seid_req {  	struct avdtp_header header;  	uint8_t rfa0:2; @@ -1013,10 +1019,60 @@ failed:  	return avdtp_send(session, &rej, sizeof(rej));  } -static gboolean avdtp_suspend_cmd(struct avdtp *session, struct seid_req *req, -				int size) +static gboolean avdtp_suspend_cmd(struct avdtp *session, +					struct suspend_req *req, int size)  { -	return avdtp_unknown_cmd(session, (void *) req, size); +	struct avdtp_local_sep *sep; +	struct avdtp_stream *stream; +	struct gen_resp *rsp = (struct gen_resp *) session->buf; +	struct stream_rej rej; +	struct seid *seid; +	uint8_t err, failed_seid; +	int seid_count, i; + +	if (size < sizeof(struct suspend_req)) { +		error("Too short suspend request"); +		return FALSE; +	} +	 +	seid_count = 1 + (sizeof(struct suspend_req) - size); + +	seid = &req->first_seid; + +	for (i = 0; i < seid_count; i++, seid++) { +		failed_seid = seid->seid; + +		sep = find_local_sep_by_seid(req->first_seid.seid); +		if (!sep || !sep->stream) { +			err = AVDTP_BAD_ACP_SEID; +			goto failed; +		} + +		stream = sep->stream; + +		if (sep->state != AVDTP_STATE_STREAMING) { +			err = AVDTP_BAD_STATE; +			goto failed; +		} + +		if (sep->ind && sep->ind->suspend) { +			if (!sep->ind->suspend(session, sep, stream, &err)) +				goto failed; +		} + +		avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN); +	} + +	init_response(&rsp->header, &req->header, TRUE); + +	return avdtp_send(session, rsp, sizeof(struct gen_resp)); + +failed: +	memset(&rej, 0, sizeof(rej)); +	init_response(&rej.header, &req->header, FALSE); +	rej.acp_seid = failed_seid; +	rej.error = err; +	return avdtp_send(session, &rej, sizeof(rej));  }  static gboolean avdtp_abort_cmd(struct avdtp *session, struct seid_req *req,  | 
