summaryrefslogtreecommitdiff
path: root/system/bta/le_audio/client_parser.h
blob: 159f4520b4d2205b3cd3551174163759677ea94f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*
 * Copyright 2019 HIMSA II K/S - www.himsa.com. Represented by EHIMA -
 * www.ehima.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This file contains the Audio Stream Control (LE_AUDIO) API function external
 * definitions.
 */

#pragma once

#include "le_audio_types.h"

namespace le_audio {
namespace client_parser {
namespace ascs {
/*
 * All structures and defines are described in Audio Stream Control Service
 * specification
 */

constexpr uint8_t kCtpResponseCodeSuccess = 0x00;
constexpr uint8_t kCtpResponseCodeUnsupportedOpcode = 0x01;
constexpr uint8_t kCtpResponseCodeInvalidLength = 0x02;
constexpr uint8_t kCtpResponseCodeInvalidAseId = 0x03;
constexpr uint8_t kCtpResponseCodeInvalidAseStateMachineTransition = 0x04;
constexpr uint8_t kCtpResponseCodeInvalidAseDirection = 0x05;
constexpr uint8_t kCtpResponseCodeUnsupportedAudioCapabilities = 0x06;
constexpr uint8_t kCtpResponseCodeUnsupportedConfigurationParameterValue = 0x07;
constexpr uint8_t kCtpResponseCodeRejectedConfigurationParameterValue = 0x08;
constexpr uint8_t kCtpResponseCodeInvalidConfigurationParameterValue = 0x09;
constexpr uint8_t kCtpResponseCodeUnsupportedMetadata = 0x0A;
constexpr uint8_t kCtpResponseCodeRejectedMetadata = 0x0B;
constexpr uint8_t kCtpResponseCodeInvalidMetadata = 0x0C;
constexpr uint8_t kCtpResponseCodeInsufficientResources = 0x0D;
constexpr uint8_t kCtpResponseCodeUnspecifiedError = 0x0E;

constexpr uint8_t kCtpResponseNoReason = 0x00;
constexpr uint8_t kCtpResponseCodecId = 0x01;
constexpr uint8_t kCtpResponseCodecSpecificConfiguration = 0x02;
constexpr uint8_t kCtpResponseSduInterval = 0x03;
constexpr uint8_t kCtpResponseFraming = 0x04;
constexpr uint8_t kCtpResponsePhy = 0x05;
constexpr uint8_t kCtpResponseMaximumSduSize = 0x06;
constexpr uint8_t kCtpResponseRetransmissionNumber = 0x07;
constexpr uint8_t kCtpResponseMaxTransportLatency = 0x08;
constexpr uint8_t kCtpResponsePresentationDelay = 0x09;
constexpr uint8_t kCtpResponseInvalidAseCisMapping = 0x0A;

constexpr uint8_t kLeAudioErrorCtpUnsupporterdOpcode = 0xFF;
constexpr uint8_t kLeAudioErrorCtpTruncatedOperation = 0xFE;
constexpr uint8_t kLeAudioErrorCtpCtpErr = 0xFD;

/* ASE states */
constexpr uint8_t kAseStateIdle = 0x00;
constexpr uint8_t kAseStateCodecConfigured = 0x01;
constexpr uint8_t kAseStateQosConfigured = 0x02;
constexpr uint8_t kAseStateEnabling = 0x03;
constexpr uint8_t kAseStateStreaming = 0x04;
constexpr uint8_t kAseStateDisabling = 0x05;
constexpr uint8_t kAseStateReleasing = 0x06;

/* Control point opcodes */
constexpr uint8_t kCtpOpcodeCodecConfiguration = 0x01;
constexpr uint8_t kCtpOpcodeQosConfiguration = 0x02;
constexpr uint8_t kCtpOpcodeEnable = 0x03;
constexpr uint8_t kCtpOpcodeReceiverStartReady = 0x04;
constexpr uint8_t kCtpOpcodeDisable = 0x05;
constexpr uint8_t kCtpOpcodeReceiverStopReady = 0x06;
constexpr uint8_t kCtpOpcodeUpdateMetadata = 0x07;
constexpr uint8_t kCtpOpcodeRelease = 0x08;

/* ASE status masks */
static constexpr uint32_t kAseRspHeaderMaskCtrlStatusFailureOpcode = 0x00FF0000;
static constexpr uint32_t kAseRspHeaderMaskCtrlStatusErrorCode = 0x0000FF00;
static constexpr uint32_t kAseRspHeaderMaskCtrlStatusErrorReason = 0x000000FF;

constexpr uint16_t kAseStatusCodecConfMinLen = 23;
struct ase_codec_configured_state_params {
  uint8_t framing;
  uint8_t preferred_phy;
  uint8_t preferred_retrans_nb;
  uint16_t max_transport_latency;
  uint32_t pres_delay_min;
  uint32_t pres_delay_max;
  uint32_t preferred_pres_delay_min;
  uint32_t preferred_pres_delay_max;
  types::LeAudioCodecId codec_id;
  std::vector<uint8_t> codec_spec_conf;
};

constexpr uint16_t kAseStatusCodecQosConfMinLen = 15;
struct ase_qos_configured_state_params {
  uint8_t cig_id;
  uint8_t cis_id;
  uint32_t sdu_interval;
  uint8_t framing;
  uint8_t phy;
  uint16_t max_sdu;
  uint8_t retrans_nb;
  uint16_t max_transport_latency;
  uint32_t pres_delay;
};

constexpr uint16_t kAseStatusTransMinLen = 3;
struct ase_transient_state_params {
  uint8_t cig_id;
  uint8_t cis_id;
  std::vector<uint8_t> metadata;
};

constexpr uint16_t kCtpAseEntryMinLen = 3;
struct ctp_ase_entry {
  uint8_t ase_id;
  uint8_t response_code;
  uint8_t reason;
};

constexpr uint16_t kCtpNtfMinLen = 2;
struct ctp_ntf {
  uint8_t op;
  std::vector<struct ctp_ase_entry> entries;
};

constexpr uint16_t kAseRspHdrMinLen = 2;
struct ase_rsp_hdr {
  uint8_t id;
  uint8_t state;
};

constexpr uint8_t kCtpOpSize = 1;
constexpr uint8_t kAseNumSize = 1;
constexpr uint8_t kAseIdSize = 1;

constexpr uint16_t kCtpCodecConfMinLen = 9;
struct ctp_codec_conf {
  uint8_t ase_id;
  uint8_t target_latency;
  uint8_t target_phy;
  types::LeAudioCodecId codec_id;
  types::LeAudioLc3Config codec_config;
};

constexpr uint16_t kCtpQosConfMinLen = 16;
struct ctp_qos_conf {
  uint8_t ase_id;
  uint8_t cig;
  uint8_t cis;
  uint32_t sdu_interval;
  uint8_t framing;
  uint8_t phy;
  uint16_t max_sdu;
  uint8_t retrans_nb;
  uint16_t max_transport_latency;
  uint32_t pres_delay;
};

constexpr uint16_t kCtpEnableMinLen = 2;
struct ctp_enable {
  uint8_t ase_id;
  std::vector<uint8_t> metadata;
};

constexpr uint16_t kCtpUpdateMetadataMinLen = 2;
struct ctp_update_metadata {
  uint8_t ase_id;
  std::vector<uint8_t> metadata;
};

/* Device control and common functions */
bool ParseAseStatusHeader(ase_rsp_hdr& rsp, uint16_t len, const uint8_t* value);
bool ParseAseStatusCodecConfiguredStateParams(
    struct ase_codec_configured_state_params& rsp, uint16_t len,
    const uint8_t* value);
bool ParseAseStatusQosConfiguredStateParams(
    struct ase_qos_configured_state_params& rsp, uint16_t len,
    const uint8_t* value);
bool ParseAseStatusTransientStateParams(struct ase_transient_state_params& rsp,
                                        uint16_t len, const uint8_t* value);
bool ParseAseCtpNotification(struct ctp_ntf& ntf, uint16_t len,
                             const uint8_t* value);
bool PrepareAseCtpCodecConfig(const std::vector<struct ctp_codec_conf>& confs,
                              std::vector<uint8_t>& value);
bool PrepareAseCtpConfigQos(const std::vector<struct ctp_qos_conf>& confs,
                            std::vector<uint8_t>& value);
bool PrepareAseCtpEnable(const std::vector<struct ctp_enable>& confs,
                         std::vector<uint8_t>& value);
bool PrepareAseCtpAudioReceiverStartReady(const std::vector<uint8_t>& ids,
                                          std::vector<uint8_t>& value);
bool PrepareAseCtpDisable(const std::vector<uint8_t>& ids,
                          std::vector<uint8_t>& value);
bool PrepareAseCtpAudioReceiverStopReady(const std::vector<uint8_t>& ids,
                                         std::vector<uint8_t>& value);
bool PrepareAseCtpUpdateMetadata(
    const std::vector<struct ctp_update_metadata>& confs,
    std::vector<uint8_t>& value);
bool PrepareAseCtpRelease(const std::vector<uint8_t>& ids,
                          std::vector<uint8_t>& value);
}  // namespace ascs

namespace pacs {

constexpr uint16_t kAcsPacRecordMinLen = 7;
constexpr uint8_t kAcsPacMetadataLenLen = 1;
constexpr uint16_t kAcsPacDiscoverRspMinLen = 1;

constexpr uint16_t kAudioLocationsRspMinLen = 4;

constexpr uint16_t kAseAudioAvailRspMinLen = 4;
struct acs_available_audio_contexts {
  std::bitset<16> snk_avail_cont;
  std::bitset<16> src_avail_cont;
};

constexpr uint16_t kAseAudioSuppContRspMinLen = 4;
struct acs_supported_audio_contexts {
  std::bitset<16> snk_supp_cont;
  std::bitset<16> src_supp_cont;
};

bool ParsePac(std::vector<struct types::acs_ac_record>& pac_recs, uint16_t len,
              const uint8_t* value);
bool ParseAudioLocations(types::AudioLocations& audio_locations, uint16_t len,
                         const uint8_t* value);
bool ParseAvailableAudioContexts(struct acs_available_audio_contexts& rsp,
                                 uint16_t len, const uint8_t* value);
bool ParseSupportedAudioContexts(struct acs_supported_audio_contexts& rsp,
                                 uint16_t len, const uint8_t* value);
}  // namespace pacs
}  // namespace client_parser
}  // namespace le_audio