1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.bluetooth.cts;
18 
19 import android.bluetooth.BluetoothClass;
20 import android.bluetooth.BluetoothQualityReport;
21 import android.bluetooth.BluetoothQualityReport.BqrCommon;
22 import android.bluetooth.BluetoothQualityReport.BqrConnectFail;
23 import android.bluetooth.BluetoothQualityReport.BqrVsA2dpChoppy;
24 import android.bluetooth.BluetoothQualityReport.BqrVsLsto;
25 import android.bluetooth.BluetoothQualityReport.BqrVsScoChoppy;
26 import android.os.Parcel;
27 import android.util.Log;
28 
29 import androidx.test.ext.junit.runners.AndroidJUnit4;
30 
31 import org.junit.Assert;
32 import org.junit.Test;
33 import org.junit.runner.RunWith;
34 
35 import java.nio.ByteBuffer;
36 import java.nio.ByteOrder;
37 
38 @RunWith(AndroidJUnit4.class)
39 public final class BluetoothQualityReportTest {
40     private static final String TAG = "BluetoothQualityReportTest";
41 
42     private static String mRemoteAddress = "01:02:03:04:05:06";
43     private static String mDefaultAddress = "00:00:00:00:00:00";
44     private static String mRemoteName = "DeviceName";
45     private static String mDefaultName = "";
46     private static int mLmpVer = 0;
47     private static int mLmpSubVer = 1;
48     private static int mManufacturerId = 3;
49     private static int mRemoteCoD = 4;
50 
assertBqrCommon(BQRParameters bqrp, BluetoothQualityReport bqr)51     private void assertBqrCommon(BQRParameters bqrp, BluetoothQualityReport bqr) {
52         // BQR Common
53         BqrCommon bqrCommon = bqr.getBqrCommon();
54         Assert.assertNotNull(bqrCommon);
55         Assert.assertEquals(bqr.getQualityReportId(), bqrp.getQualityReportId());
56         Assert.assertEquals(bqrp.mPacketType, bqrCommon.getPacketType());
57         Assert.assertEquals("TYPE_NULL", BqrCommon.packetTypeToString(bqrCommon.getPacketType()));
58         Assert.assertEquals(bqrp.mConnectionHandle, bqrCommon.getConnectionHandle());
59         Assert.assertTrue(
60                 bqrp.mConnectionRoleCentral.equals(
61                         BqrCommon.connectionRoleToString(bqrCommon.getConnectionRole())));
62         Assert.assertEquals(bqrp.mConnectionRole, bqrCommon.getConnectionRole());
63         Assert.assertEquals(bqrp.mTxPowerLevel, bqrCommon.getTxPowerLevel());
64         Assert.assertEquals(bqrp.mRssi, bqrCommon.getRssi());
65         Assert.assertEquals(bqrp.mSnr, bqrCommon.getSnr());
66         Assert.assertEquals(bqrp.mUnusedAfhChannelCount, bqrCommon.getUnusedAfhChannelCount());
67         Assert.assertEquals(
68                 bqrp.mAfhSelectUnidealChannelCount, bqrCommon.getAfhSelectUnidealChannelCount());
69         Assert.assertEquals(bqrp.mLsto, bqrCommon.getLsto());
70         Assert.assertEquals(bqrp.mPiconetClock, bqrCommon.getPiconetClock());
71         Assert.assertEquals(bqrp.mRetransmissionCount, bqrCommon.getRetransmissionCount());
72         Assert.assertEquals(bqrp.mNoRxCount, bqrCommon.getNoRxCount());
73         Assert.assertEquals(bqrp.mNakCount, bqrCommon.getNakCount());
74         Assert.assertEquals(bqrp.mLastTxAckTimestamp, bqrCommon.getLastTxAckTimestamp());
75         Assert.assertEquals(bqrp.mFlowOffCount, bqrCommon.getFlowOffCount());
76         Assert.assertEquals(bqrp.mLastFlowOnTimestamp, bqrCommon.getLastFlowOnTimestamp());
77         Assert.assertEquals(bqrp.mOverflowCount, bqrCommon.getOverflowCount());
78         Assert.assertEquals(bqrp.mUnderflowCount, bqrCommon.getUnderflowCount());
79         Assert.assertEquals(bqrp.mCalFailedItemCount, bqrCommon.getCalFailedItemCount());
80     }
81 
assertBqrApproachLsto(BQRParameters bqrp, BluetoothQualityReport bqr)82     private void assertBqrApproachLsto(BQRParameters bqrp, BluetoothQualityReport bqr) {
83         // BQR VS LSTO
84         BqrVsLsto bqrVsLsto = (BqrVsLsto) bqr.getBqrEvent();
85         Assert.assertNotNull(bqrVsLsto);
86         Assert.assertEquals(
87                 "Approaching LSTO",
88                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
89         Assert.assertEquals(bqrp.mConnState & 0xFF, bqrVsLsto.getConnState());
90         Assert.assertEquals(
91                 "CONN_UNPARK_ACTIVE", BqrVsLsto.connStateToString(bqrVsLsto.getConnState()));
92         Assert.assertEquals(bqrp.mBasebandStats, bqrVsLsto.getBasebandStats());
93         Assert.assertEquals(bqrp.mSlotsUsed, bqrVsLsto.getSlotsUsed());
94         Assert.assertEquals(bqrp.mCxmDenials, bqrVsLsto.getCxmDenials());
95         Assert.assertEquals(bqrp.mTxSkipped, bqrVsLsto.getTxSkipped());
96         Assert.assertEquals(bqrp.mRfLoss, bqrVsLsto.getRfLoss());
97         Assert.assertEquals(bqrp.mNativeClock, bqrVsLsto.getNativeClock());
98         Assert.assertEquals(bqrp.mLastTxAckTimestampLsto, bqrVsLsto.getLastTxAckTimestamp());
99         Assert.assertEquals(0, bqrVsLsto.describeContents());
100     }
101 
assertBqrA2dpChoppy(BQRParameters bqrp, BluetoothQualityReport bqr)102     private void assertBqrA2dpChoppy(BQRParameters bqrp, BluetoothQualityReport bqr) {
103         // BQR VS A2DP Choppy
104         BqrVsA2dpChoppy bqrVsA2dpChoppy = (BqrVsA2dpChoppy) bqr.getBqrEvent();
105         Assert.assertNotNull(bqrVsA2dpChoppy);
106         Assert.assertEquals(
107                 "A2DP choppy",
108                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
109         Assert.assertEquals(bqrp.mArrivalTime, bqrVsA2dpChoppy.getArrivalTime());
110         Assert.assertEquals(bqrp.mScheduleTime, bqrVsA2dpChoppy.getScheduleTime());
111         Assert.assertEquals(bqrp.mGlitchCountA2dp, bqrVsA2dpChoppy.getGlitchCount());
112         Assert.assertEquals(bqrp.mTxCxmDenialsA2dp, bqrVsA2dpChoppy.getTxCxmDenials());
113         Assert.assertEquals(bqrp.mRxCxmDenialsA2dp, bqrVsA2dpChoppy.getRxCxmDenials());
114         Assert.assertEquals(bqrp.mAclTxQueueLength, bqrVsA2dpChoppy.getAclTxQueueLength());
115         Assert.assertEquals(bqrp.mLinkQuality, bqrVsA2dpChoppy.getLinkQuality());
116         Assert.assertEquals(
117                 "MEDIUM", BqrVsA2dpChoppy.linkQualityToString(bqrVsA2dpChoppy.getLinkQuality()));
118         Assert.assertEquals(0, bqrVsA2dpChoppy.describeContents());
119     }
120 
assertBqrScoChoppy(BQRParameters bqrp, BluetoothQualityReport bqr)121     private void assertBqrScoChoppy(BQRParameters bqrp, BluetoothQualityReport bqr) {
122         // BQR VS SCO Choppy
123         BqrVsScoChoppy bqrVsScoChoppy = (BqrVsScoChoppy) bqr.getBqrEvent();
124         Assert.assertNotNull(bqrVsScoChoppy);
125         Assert.assertEquals(
126                 "SCO choppy",
127                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
128         Assert.assertEquals(bqrp.mGlitchCountSco, bqrVsScoChoppy.getGlitchCount());
129         Assert.assertEquals(bqrp.mIntervalEsco, bqrVsScoChoppy.getIntervalEsco());
130         Assert.assertEquals(bqrp.mWindowEsco, bqrVsScoChoppy.getWindowEsco());
131         Assert.assertEquals(bqrp.mAirFormat, bqrVsScoChoppy.getAirFormat());
132         Assert.assertEquals(
133                 "CVSD", BqrVsScoChoppy.airFormatToString(bqrVsScoChoppy.getAirFormat()));
134         Assert.assertEquals(bqrp.mInstanceCount, bqrVsScoChoppy.getInstanceCount());
135         Assert.assertEquals(bqrp.mTxCxmDenialsSco, bqrVsScoChoppy.getTxCxmDenials());
136         Assert.assertEquals(bqrp.mRxCxmDenialsSco, bqrVsScoChoppy.getRxCxmDenials());
137         Assert.assertEquals(bqrp.mTxAbortCount, bqrVsScoChoppy.getTxAbortCount());
138         Assert.assertEquals(bqrp.mLateDispatch, bqrVsScoChoppy.getLateDispatch());
139         Assert.assertEquals(bqrp.mMicIntrMiss, bqrVsScoChoppy.getMicIntrMiss());
140         Assert.assertEquals(bqrp.mLpaIntrMiss, bqrVsScoChoppy.getLpaIntrMiss());
141         Assert.assertEquals(bqrp.mSprIntrMiss, bqrVsScoChoppy.getSprIntrMiss());
142         Assert.assertEquals(bqrp.mPlcFillCount, bqrVsScoChoppy.getPlcFillCount());
143         Assert.assertEquals(bqrp.mPlcDiscardCount, bqrVsScoChoppy.getPlcDiscardCount());
144         Assert.assertEquals(bqrp.mMissedInstanceCount, bqrVsScoChoppy.getMissedInstanceCount());
145         Assert.assertEquals(bqrp.mTxRetransmitSlotCount, bqrVsScoChoppy.getTxRetransmitSlotCount());
146         Assert.assertEquals(bqrp.mRxRetransmitSlotCount, bqrVsScoChoppy.getRxRetransmitSlotCount());
147         Assert.assertEquals(bqrp.mGoodRxFrameCount, bqrVsScoChoppy.getGoodRxFrameCount());
148         Assert.assertEquals(0, bqrVsScoChoppy.describeContents());
149     }
150 
assertBqrConnectFail(BQRParameters bqrp, BluetoothQualityReport bqr)151     private void assertBqrConnectFail(BQRParameters bqrp, BluetoothQualityReport bqr) {
152         // BQR VS Connect Fail
153         BqrConnectFail bqrConnectFail = (BqrConnectFail) bqr.getBqrEvent();
154         Assert.assertNotNull(bqrConnectFail);
155         Assert.assertEquals(
156                 "Connect fail",
157                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
158         Assert.assertEquals(bqrp.mFailReason, bqrConnectFail.getFailReason());
159         Assert.assertEquals(0, bqrConnectFail.describeContents());
160     }
161 
getBluetoothClassHelper(int remoteCoD)162     private static BluetoothClass getBluetoothClassHelper(int remoteCoD) {
163         Parcel p = Parcel.obtain();
164         p.writeInt(remoteCoD);
165         p.setDataPosition(0);
166         BluetoothClass bluetoothClass = BluetoothClass.CREATOR.createFromParcel(p);
167         p.recycle();
168         return bluetoothClass;
169     }
170 
initBqrCommon( BQRParameters bqrp, String remoteAddr, int lmpVer, int lmpSubVer, int manufacturerId, String remoteName, int remoteCoD)171     private BluetoothQualityReport initBqrCommon(
172             BQRParameters bqrp,
173             String remoteAddr,
174             int lmpVer,
175             int lmpSubVer,
176             int manufacturerId,
177             String remoteName,
178             int remoteCoD) {
179 
180         BluetoothClass bluetoothClass = getBluetoothClassHelper(remoteCoD);
181 
182         BluetoothQualityReport bqr =
183                 new BluetoothQualityReport.Builder(bqrp.getByteArray())
184                         .setRemoteAddress(remoteAddr)
185                         .setLmpVersion(lmpVer)
186                         .setLmpSubVersion(lmpSubVer)
187                         .setManufacturerId(manufacturerId)
188                         .setRemoteName(remoteName)
189                         .setBluetoothClass(bluetoothClass)
190                         .build();
191 
192         Log.i(TAG, bqr.toString());
193 
194         Assert.assertTrue(remoteAddr.equals(bqr.getRemoteAddress()));
195         Assert.assertEquals(lmpVer, bqr.getLmpVersion());
196         Assert.assertEquals(lmpSubVer, bqr.getLmpSubVersion());
197         Assert.assertEquals(manufacturerId, bqr.getManufacturerId());
198         Assert.assertTrue(remoteName.equals(bqr.getRemoteName()));
199         Assert.assertEquals(bluetoothClass, bqr.getBluetoothClass());
200 
201         assertBqrCommon(bqrp, bqr);
202 
203         return bqr;
204     }
205 
206     @Test
bqrMonitor()207     public void bqrMonitor() {
208         BQRParameters bqrp = BQRParameters.getInstance();
209         Assert.assertNotNull(bqrp);
210 
211         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
212         Assert.assertEquals(
213                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
214 
215         BluetoothQualityReport bqr =
216                 initBqrCommon(
217                         bqrp,
218                         mRemoteAddress,
219                         mLmpVer,
220                         mLmpSubVer,
221                         mManufacturerId,
222                         mRemoteName,
223                         mRemoteCoD);
224     }
225 
226     @Test
bqrApproachLsto()227     public void bqrApproachLsto() {
228         BQRParameters bqrp = BQRParameters.getInstance();
229         Assert.assertNotNull(bqrp);
230 
231         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
232         Assert.assertEquals(
233                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
234 
235         BluetoothQualityReport bqr =
236                 initBqrCommon(
237                         bqrp,
238                         mRemoteAddress,
239                         mLmpVer,
240                         mLmpSubVer,
241                         mManufacturerId,
242                         mRemoteName,
243                         mRemoteCoD);
244 
245         assertBqrApproachLsto(bqrp, bqr);
246     }
247 
248     @Test
bqrA2dpChoppy()249     public void bqrA2dpChoppy() {
250         BQRParameters bqrp = BQRParameters.getInstance();
251         Assert.assertNotNull(bqrp);
252 
253         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
254         Assert.assertEquals(
255                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
256 
257         BluetoothQualityReport bqr =
258                 initBqrCommon(
259                         bqrp,
260                         mRemoteAddress,
261                         mLmpVer,
262                         mLmpSubVer,
263                         mManufacturerId,
264                         mRemoteName,
265                         mRemoteCoD);
266 
267         assertBqrA2dpChoppy(bqrp, bqr);
268     }
269 
270     @Test
bqrScoChoppy()271     public void bqrScoChoppy() {
272         BQRParameters bqrp = BQRParameters.getInstance();
273         Assert.assertNotNull(bqrp);
274 
275         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY);
276         Assert.assertEquals(
277                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY);
278 
279         BluetoothQualityReport bqr =
280                 initBqrCommon(
281                         bqrp,
282                         mRemoteAddress,
283                         mLmpVer,
284                         mLmpSubVer,
285                         mManufacturerId,
286                         mRemoteName,
287                         mRemoteCoD);
288 
289         assertBqrScoChoppy(bqrp, bqr);
290     }
291 
292     @Test
bqrConnectFail()293     public void bqrConnectFail() {
294         BQRParameters bqrp = BQRParameters.getInstance();
295         Assert.assertNotNull(bqrp);
296 
297         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL);
298         Assert.assertEquals(
299                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL);
300 
301         BluetoothQualityReport bqr =
302                 initBqrCommon(
303                         bqrp,
304                         mRemoteAddress,
305                         mLmpVer,
306                         mLmpSubVer,
307                         mManufacturerId,
308                         mRemoteName,
309                         mRemoteCoD);
310 
311         assertBqrConnectFail(bqrp, bqr);
312 
313         BqrConnectFail bqrConnectFail = (BqrConnectFail) bqr.getBqrEvent();
314         Assert.assertNotNull(bqrConnectFail);
315 
316         Assert.assertEquals(
317                 "No error",
318                 BqrConnectFail.connectFailIdToString(BqrConnectFail.CONNECT_FAIL_ID_NO_ERROR));
319         Assert.assertEquals(
320                 "Page Timeout",
321                 BqrConnectFail.connectFailIdToString(BqrConnectFail.CONNECT_FAIL_ID_PAGE_TIMEOUT));
322         Assert.assertEquals(
323                 "Connection Timeout",
324                 BqrConnectFail.connectFailIdToString(
325                         BqrConnectFail.CONNECT_FAIL_ID_CONNECTION_TIMEOUT));
326         Assert.assertEquals(
327                 "ACL already exists",
328                 BqrConnectFail.connectFailIdToString(
329                         BqrConnectFail.CONNECT_FAIL_ID_ACL_ALREADY_EXIST));
330         Assert.assertEquals(
331                 "Controller busy",
332                 BqrConnectFail.connectFailIdToString(
333                         BqrConnectFail.CONNECT_FAIL_ID_CONTROLLER_BUSY));
334         Assert.assertEquals("INVALID", BqrConnectFail.connectFailIdToString(0xFF));
335     }
336 
337     @Test
defaultNameAddress()338     public void defaultNameAddress() {
339         BQRParameters bqrp = BQRParameters.getInstance();
340         Assert.assertNotNull(bqrp);
341 
342         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
343         Assert.assertEquals(
344                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
345 
346         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
347 
348         BluetoothQualityReport bqr =
349                 new BluetoothQualityReport.Builder(bqrp.getByteArray())
350                         .setRemoteAddress("123456123456")
351                         .setLmpVersion(mLmpVer)
352                         .setLmpSubVersion(mLmpSubVer)
353                         .setManufacturerId(mManufacturerId)
354                         .setBluetoothClass(bluetoothClass)
355                         .build();
356 
357         Assert.assertTrue(bqr.getRemoteAddress().equals(mDefaultAddress));
358         Assert.assertTrue(bqr.getRemoteName().equals(mDefaultName));
359     }
360 
361     @Test
invalidQualityReportId()362     public void invalidQualityReportId() {
363         BQRParameters bqrp = BQRParameters.getInstance();
364         Assert.assertNotNull(bqrp);
365 
366         bqrp.setQualityReportId((byte) 123);
367         Assert.assertEquals(bqrp.getQualityReportId(), 123);
368 
369         Assert.assertThrows(
370                 IllegalArgumentException.class,
371                 () ->
372                         initBqrCommon(
373                                 bqrp,
374                                 mRemoteAddress,
375                                 mLmpVer,
376                                 mLmpSubVer,
377                                 mManufacturerId,
378                                 mRemoteName,
379                                 mRemoteCoD));
380     }
381 
382     @Test
rawDataNull()383     public void rawDataNull() {
384         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
385 
386         Assert.assertThrows(
387                 NullPointerException.class,
388                 () ->
389                         new BluetoothQualityReport.Builder(null)
390                                 .setRemoteAddress(mRemoteAddress)
391                                 .setLmpVersion(mLmpVer)
392                                 .setLmpSubVersion(mLmpSubVer)
393                                 .setManufacturerId(mManufacturerId)
394                                 .setRemoteName(mRemoteName)
395                                 .setBluetoothClass(bluetoothClass)
396                                 .build());
397     }
398 
399     @Test
invalidRawData()400     public void invalidRawData() {
401         BQRParameters bqrp = BQRParameters.getInstance();
402         Assert.assertNotNull(bqrp);
403 
404         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
405 
406         for (int id : BQRParameters.QualityReportId) {
407             bqrp.setQualityReportId((byte) id);
408             Assert.assertEquals(bqrp.getQualityReportId(), id);
409 
410             byte[] rawData = {0};
411 
412             switch (id) {
413                 case BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR:
414                     rawData = ByteBuffer.allocate(BQRParameters.mBqrCommonSize - 1).array();
415                     break;
416                 case BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO:
417                     rawData =
418                             ByteBuffer.allocate(
419                                             BQRParameters.mBqrCommonSize
420                                                     + BQRParameters.mBqrVsLstoSize
421                                                     - 1)
422                                     .array();
423                     break;
424                 case BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY:
425                     rawData =
426                             ByteBuffer.allocate(
427                                             BQRParameters.mBqrCommonSize
428                                                     + BQRParameters.mBqrVsA2dpChoppySize
429                                                     - 1)
430                                     .array();
431                     break;
432                 case BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY:
433                     rawData =
434                             ByteBuffer.allocate(
435                                             BQRParameters.mBqrCommonSize
436                                                     + BQRParameters.mBqrVsScoChoppySize
437                                                     - 1)
438                                     .array();
439                     break;
440                 case BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL:
441                     rawData =
442                             ByteBuffer.allocate(
443                                             BQRParameters.mBqrCommonSize
444                                                     + BQRParameters.mBqrVsScoChoppySize
445                                                     - 1)
446                                     .array();
447                     break;
448             }
449 
450             final byte[] data = rawData;
451 
452             Assert.assertThrows(
453                     IllegalArgumentException.class,
454                     () ->
455                             new BluetoothQualityReport.Builder(data)
456                                     .setRemoteAddress(mRemoteAddress)
457                                     .setLmpVersion(mLmpVer)
458                                     .setLmpSubVersion(mLmpSubVer)
459                                     .setManufacturerId(mManufacturerId)
460                                     .setRemoteName(mRemoteName)
461                                     .setBluetoothClass(bluetoothClass)
462                                     .build());
463         }
464     }
465 
466     @Test
readWriteBqrParcel()467     public void readWriteBqrParcel() {
468         BQRParameters bqrp = BQRParameters.getInstance();
469         Assert.assertNotNull(bqrp);
470 
471         for (int id : BQRParameters.QualityReportId) {
472             bqrp.setQualityReportId((byte) id);
473             Assert.assertEquals(bqrp.getQualityReportId(), id);
474 
475             BluetoothQualityReport bqr =
476                     initBqrCommon(
477                             bqrp,
478                             mRemoteAddress,
479                             mLmpVer,
480                             mLmpSubVer,
481                             mManufacturerId,
482                             mRemoteName,
483                             mRemoteCoD);
484 
485             Parcel parcel = Parcel.obtain();
486             bqr.writeToParcel(parcel, 0);
487             parcel.setDataPosition(0);
488 
489             BluetoothQualityReport bqrFromParcel =
490                     BluetoothQualityReport.CREATOR.createFromParcel(parcel);
491 
492             assertBqrCommon(bqrp, bqrFromParcel);
493 
494             switch (id) {
495                 case BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR:
496                     break;
497                 case BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO:
498                     assertBqrApproachLsto(bqrp, bqr);
499                     break;
500                 case BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY:
501                     assertBqrA2dpChoppy(bqrp, bqr);
502                     break;
503                 case BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY:
504                     assertBqrScoChoppy(bqrp, bqr);
505                     break;
506                 case BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL:
507                     assertBqrConnectFail(bqrp, bqr);
508                     break;
509             }
510         }
511     }
512 
513     @Test
readWriteBqrCommonParcel()514     public void readWriteBqrCommonParcel() {
515         BQRParameters bqrp = BQRParameters.getInstance();
516         Assert.assertNotNull(bqrp);
517 
518         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
519         Assert.assertEquals(
520                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR);
521 
522         BluetoothQualityReport bqr =
523                 initBqrCommon(
524                         bqrp,
525                         mRemoteAddress,
526                         mLmpVer,
527                         mLmpSubVer,
528                         mManufacturerId,
529                         mRemoteName,
530                         mRemoteCoD);
531 
532         Assert.assertEquals(
533                 "Quality monitor",
534                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
535 
536         Parcel parcel = Parcel.obtain();
537         bqr.getBqrCommon().writeToParcel(parcel, 0);
538         parcel.setDataPosition(0);
539 
540         BqrCommon bqrCommonFromParcel = BqrCommon.CREATOR.createFromParcel(parcel);
541 
542         // BQR Common
543         Assert.assertNotNull(bqrCommonFromParcel);
544         Assert.assertEquals(bqrp.mPacketType, bqrCommonFromParcel.getPacketType());
545         Assert.assertEquals(
546                 "TYPE_NULL", BqrCommon.packetTypeToString(bqrCommonFromParcel.getPacketType()));
547         Assert.assertEquals(bqrp.mConnectionHandle, bqrCommonFromParcel.getConnectionHandle());
548         Assert.assertTrue(
549                 bqrp.mConnectionRoleCentral.equals(
550                         BqrCommon.connectionRoleToString(bqrCommonFromParcel.getConnectionRole())));
551         Assert.assertEquals(bqrp.mTxPowerLevel, bqrCommonFromParcel.getTxPowerLevel());
552         Assert.assertEquals(bqrp.mRssi, bqrCommonFromParcel.getRssi());
553         Assert.assertEquals(bqrp.mSnr, bqrCommonFromParcel.getSnr());
554         Assert.assertEquals(
555                 bqrp.mUnusedAfhChannelCount, bqrCommonFromParcel.getUnusedAfhChannelCount());
556         Assert.assertEquals(
557                 bqrp.mAfhSelectUnidealChannelCount,
558                 bqrCommonFromParcel.getAfhSelectUnidealChannelCount());
559         Assert.assertEquals(bqrp.mLsto, bqrCommonFromParcel.getLsto());
560         Assert.assertEquals(bqrp.mPiconetClock, bqrCommonFromParcel.getPiconetClock());
561         Assert.assertEquals(
562                 bqrp.mRetransmissionCount, bqrCommonFromParcel.getRetransmissionCount());
563         Assert.assertEquals(bqrp.mNoRxCount, bqrCommonFromParcel.getNoRxCount());
564         Assert.assertEquals(bqrp.mNakCount, bqrCommonFromParcel.getNakCount());
565         Assert.assertEquals(bqrp.mLastTxAckTimestamp, bqrCommonFromParcel.getLastTxAckTimestamp());
566         Assert.assertEquals(bqrp.mFlowOffCount, bqrCommonFromParcel.getFlowOffCount());
567         Assert.assertEquals(
568                 bqrp.mLastFlowOnTimestamp, bqrCommonFromParcel.getLastFlowOnTimestamp());
569         Assert.assertEquals(bqrp.mOverflowCount, bqrCommonFromParcel.getOverflowCount());
570         Assert.assertEquals(bqrp.mUnderflowCount, bqrCommonFromParcel.getUnderflowCount());
571     }
572 
573     @Test
readWriteBqrVsApproachLstoParcel()574     public void readWriteBqrVsApproachLstoParcel() {
575         BQRParameters bqrp = BQRParameters.getInstance();
576         Assert.assertNotNull(bqrp);
577 
578         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
579         Assert.assertEquals(
580                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO);
581 
582         BluetoothQualityReport bqr =
583                 initBqrCommon(
584                         bqrp,
585                         mRemoteAddress,
586                         mLmpVer,
587                         mLmpSubVer,
588                         mManufacturerId,
589                         mRemoteName,
590                         mRemoteCoD);
591 
592         Assert.assertEquals(
593                 "Approaching LSTO",
594                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
595 
596         BqrVsLsto bqrVsLsto = (BqrVsLsto) bqr.getBqrEvent();
597         Assert.assertNotNull(bqrVsLsto);
598         Parcel parcel = Parcel.obtain();
599         bqrVsLsto.writeToParcel(parcel, 0);
600         parcel.setDataPosition(0);
601 
602         BqrVsLsto bqrVsLstoFromParcel = BqrVsLsto.CREATOR.createFromParcel(parcel);
603 
604         // BQR VS LSTO
605         Assert.assertNotNull(bqrVsLstoFromParcel);
606         Assert.assertEquals(bqrp.mConnState & 0xFF, bqrVsLstoFromParcel.getConnState());
607         Assert.assertEquals(
608                 "CONN_UNPARK_ACTIVE",
609                 BqrVsLsto.connStateToString(bqrVsLstoFromParcel.getConnState()));
610         Assert.assertEquals(bqrp.mBasebandStats, bqrVsLstoFromParcel.getBasebandStats());
611         Assert.assertEquals(bqrp.mSlotsUsed, bqrVsLstoFromParcel.getSlotsUsed());
612         Assert.assertEquals(bqrp.mCxmDenials, bqrVsLstoFromParcel.getCxmDenials());
613         Assert.assertEquals(bqrp.mTxSkipped, bqrVsLstoFromParcel.getTxSkipped());
614         Assert.assertEquals(bqrp.mRfLoss, bqrVsLstoFromParcel.getRfLoss());
615         Assert.assertEquals(bqrp.mNativeClock, bqrVsLstoFromParcel.getNativeClock());
616         Assert.assertEquals(
617                 bqrp.mLastTxAckTimestampLsto, bqrVsLstoFromParcel.getLastTxAckTimestamp());
618         Assert.assertEquals(0, bqrVsLstoFromParcel.describeContents());
619     }
620 
621     @Test
readWriteBqrVsA2dpChoppyParcel()622     public void readWriteBqrVsA2dpChoppyParcel() {
623         BQRParameters bqrp = BQRParameters.getInstance();
624         Assert.assertNotNull(bqrp);
625 
626         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
627         Assert.assertEquals(
628                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY);
629 
630         BluetoothQualityReport bqr =
631                 initBqrCommon(
632                         bqrp,
633                         mRemoteAddress,
634                         mLmpVer,
635                         mLmpSubVer,
636                         mManufacturerId,
637                         mRemoteName,
638                         mRemoteCoD);
639 
640         Assert.assertEquals(
641                 "A2DP choppy",
642                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
643 
644         BqrVsA2dpChoppy bqrVsA2dpChoppy = (BqrVsA2dpChoppy) bqr.getBqrEvent();
645         Assert.assertNotNull(bqrVsA2dpChoppy);
646         Parcel parcel = Parcel.obtain();
647         bqrVsA2dpChoppy.writeToParcel(parcel, 0);
648         parcel.setDataPosition(0);
649 
650         BqrVsA2dpChoppy bqrVsA2dpChoppyFromParcel =
651                 BqrVsA2dpChoppy.CREATOR.createFromParcel(parcel);
652 
653         // BQR VS A2DP Choppy
654         Assert.assertNotNull(bqrVsA2dpChoppyFromParcel);
655         Assert.assertEquals(bqrp.mArrivalTime, bqrVsA2dpChoppyFromParcel.getArrivalTime());
656         Assert.assertEquals(bqrp.mScheduleTime, bqrVsA2dpChoppyFromParcel.getScheduleTime());
657         Assert.assertEquals(bqrp.mGlitchCountA2dp, bqrVsA2dpChoppyFromParcel.getGlitchCount());
658         Assert.assertEquals(bqrp.mTxCxmDenialsA2dp, bqrVsA2dpChoppyFromParcel.getTxCxmDenials());
659         Assert.assertEquals(bqrp.mRxCxmDenialsA2dp, bqrVsA2dpChoppyFromParcel.getRxCxmDenials());
660         Assert.assertEquals(
661                 bqrp.mAclTxQueueLength, bqrVsA2dpChoppyFromParcel.getAclTxQueueLength());
662         Assert.assertEquals(bqrp.mLinkQuality, bqrVsA2dpChoppyFromParcel.getLinkQuality());
663         Assert.assertEquals(
664                 "MEDIUM",
665                 BqrVsA2dpChoppy.linkQualityToString(bqrVsA2dpChoppyFromParcel.getLinkQuality()));
666         Assert.assertEquals(0, bqrVsA2dpChoppyFromParcel.describeContents());
667     }
668 
669     @Test
readWriteBqrVsScoChoppyParcel()670     public void readWriteBqrVsScoChoppyParcel() {
671         BQRParameters bqrp = BQRParameters.getInstance();
672         Assert.assertNotNull(bqrp);
673 
674         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY);
675         Assert.assertEquals(
676                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY);
677 
678         BluetoothQualityReport bqr =
679                 initBqrCommon(
680                         bqrp,
681                         mRemoteAddress,
682                         mLmpVer,
683                         mLmpSubVer,
684                         mManufacturerId,
685                         mRemoteName,
686                         mRemoteCoD);
687 
688         Assert.assertEquals(
689                 "SCO choppy",
690                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
691 
692         BqrVsScoChoppy bqrVsScoChoppy = (BqrVsScoChoppy) bqr.getBqrEvent();
693         Assert.assertNotNull(bqrVsScoChoppy);
694         Parcel parcel = Parcel.obtain();
695         bqrVsScoChoppy.writeToParcel(parcel, 0);
696         parcel.setDataPosition(0);
697 
698         BqrVsScoChoppy bqrVsScoChoppyFromParcel = BqrVsScoChoppy.CREATOR.createFromParcel(parcel);
699 
700         // BQR VS SCO Choppy
701         Assert.assertNotNull(bqrVsScoChoppyFromParcel);
702         Assert.assertEquals(bqrp.mGlitchCountSco, bqrVsScoChoppyFromParcel.getGlitchCount());
703         Assert.assertEquals(bqrp.mIntervalEsco, bqrVsScoChoppyFromParcel.getIntervalEsco());
704         Assert.assertEquals(bqrp.mWindowEsco, bqrVsScoChoppyFromParcel.getWindowEsco());
705         Assert.assertEquals(bqrp.mAirFormat, bqrVsScoChoppyFromParcel.getAirFormat());
706         Assert.assertEquals(
707                 "CVSD", BqrVsScoChoppy.airFormatToString(bqrVsScoChoppyFromParcel.getAirFormat()));
708         Assert.assertEquals(bqrp.mInstanceCount, bqrVsScoChoppyFromParcel.getInstanceCount());
709         Assert.assertEquals(bqrp.mTxCxmDenialsSco, bqrVsScoChoppyFromParcel.getTxCxmDenials());
710         Assert.assertEquals(bqrp.mRxCxmDenialsSco, bqrVsScoChoppyFromParcel.getRxCxmDenials());
711         Assert.assertEquals(bqrp.mTxAbortCount, bqrVsScoChoppyFromParcel.getTxAbortCount());
712         Assert.assertEquals(bqrp.mLateDispatch, bqrVsScoChoppyFromParcel.getLateDispatch());
713         Assert.assertEquals(bqrp.mMicIntrMiss, bqrVsScoChoppyFromParcel.getMicIntrMiss());
714         Assert.assertEquals(bqrp.mLpaIntrMiss, bqrVsScoChoppyFromParcel.getLpaIntrMiss());
715         Assert.assertEquals(bqrp.mSprIntrMiss, bqrVsScoChoppyFromParcel.getSprIntrMiss());
716         Assert.assertEquals(bqrp.mPlcFillCount, bqrVsScoChoppyFromParcel.getPlcFillCount());
717         Assert.assertEquals(bqrp.mPlcDiscardCount, bqrVsScoChoppyFromParcel.getPlcDiscardCount());
718 
719         Assert.assertEquals(
720                 bqrp.mMissedInstanceCount, bqrVsScoChoppyFromParcel.getMissedInstanceCount());
721         Assert.assertEquals(
722                 bqrp.mTxRetransmitSlotCount, bqrVsScoChoppyFromParcel.getTxRetransmitSlotCount());
723         Assert.assertEquals(
724                 bqrp.mRxRetransmitSlotCount, bqrVsScoChoppyFromParcel.getRxRetransmitSlotCount());
725         Assert.assertEquals(bqrp.mGoodRxFrameCount, bqrVsScoChoppyFromParcel.getGoodRxFrameCount());
726         Assert.assertEquals(0, bqrVsScoChoppyFromParcel.describeContents());
727     }
728 
729     @Test
readWriteBqrConnectFailParcel()730     public void readWriteBqrConnectFailParcel() {
731         BQRParameters bqrp = BQRParameters.getInstance();
732         Assert.assertNotNull(bqrp);
733 
734         bqrp.setQualityReportId((byte) BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL);
735         Assert.assertEquals(
736                 bqrp.getQualityReportId(), BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL);
737 
738         BluetoothQualityReport bqr =
739                 initBqrCommon(
740                         bqrp,
741                         mRemoteAddress,
742                         mLmpVer,
743                         mLmpSubVer,
744                         mManufacturerId,
745                         mRemoteName,
746                         mRemoteCoD);
747 
748         Assert.assertEquals(
749                 "Connect fail",
750                 BluetoothQualityReport.qualityReportIdToString(bqr.getQualityReportId()));
751 
752         BqrConnectFail bqrConnectFail = (BqrConnectFail) bqr.getBqrEvent();
753         Assert.assertNotNull(bqrConnectFail);
754         Parcel parcel = Parcel.obtain();
755         bqrConnectFail.writeToParcel(parcel, 0);
756         parcel.setDataPosition(0);
757 
758         BqrConnectFail bqrConnFailFromParcel = BqrConnectFail.CREATOR.createFromParcel(parcel);
759 
760         // BQR VS Connect Fail
761         Assert.assertNotNull(bqrConnFailFromParcel);
762         Assert.assertEquals(bqrp.mFailReason, bqrConnFailFromParcel.getFailReason());
763         Assert.assertEquals(0, bqrConnFailFromParcel.describeContents());
764     }
765 
766     /**
767      * Get the test object of BluetoothQualityReport based on given Quality Report Id.
768      *
769      * @param qualityReportId Quality Report Id
770      * @return Bluetooth Quality Report object
771      */
getBqr(int qualityReportId)772     public static BluetoothQualityReport getBqr(int qualityReportId) {
773         BQRParameters bqrp = BQRParameters.getInstance();
774         Assert.assertNotNull(bqrp);
775 
776         bqrp.setQualityReportId((byte) qualityReportId);
777         Assert.assertEquals(bqrp.getQualityReportId(), qualityReportId);
778         BluetoothClass bluetoothClass = getBluetoothClassHelper(mRemoteCoD);
779 
780         BluetoothQualityReport bqr =
781                 new BluetoothQualityReport.Builder(bqrp.getByteArray())
782                         .setRemoteAddress(mRemoteAddress)
783                         .setLmpVersion(mLmpVer)
784                         .setLmpSubVersion(mLmpSubVer)
785                         .setManufacturerId(mManufacturerId)
786                         .setRemoteName(mRemoteName)
787                         .setBluetoothClass(bluetoothClass)
788                         .build();
789         return bqr;
790     }
791 
792     private static final class BQRParameters {
793         private static BQRParameters INSTANCE;
794         private static String TAG = "BQRParameters";
795 
796         public static int mBqrCommonSize = 55;
797         public static int mBqrVsLstoSize = 23;
798         public static int mBqrVsA2dpChoppySize = 16;
799         public static int mBqrVsScoChoppySize = 33;
800         public static int mBqrConnectFailSize = 1;
801 
802         // BQR Common
803         public byte mQualityReportId = 1;
804         public byte mPacketType = 2;
805         public short mConnectionHandle = 3;
806         public byte mConnectionRole = 0; // Central
807         public String mConnectionRoleCentral = "Central";
808         public byte mTxPowerLevel = 5;
809         public byte mRssi = 6;
810         public byte mSnr = 7;
811         public byte mUnusedAfhChannelCount = 8;
812         public byte mAfhSelectUnidealChannelCount = 9;
813         public short mLsto = 10;
814         public int mPiconetClock = 11;
815         public int mRetransmissionCount = 12;
816         public int mNoRxCount = 13;
817         public int mNakCount = 14;
818         public int mLastTxAckTimestamp = 15;
819         public int mFlowOffCount = 16;
820         public int mLastFlowOnTimestamp = 17;
821         public int mOverflowCount = 18;
822         public int mUnderflowCount = 19;
823         public String mAddressStr = "01:02:03:04:05:06";
824         public byte[] mAddress = {6, 5, 4, 3, 2, 1};
825         public byte mCalFailedItemCount = 50;
826 
827         // BQR VS LSTO
828         public byte mConnState = (byte) 0x89;
829         public int mBasebandStats = 21;
830         public int mSlotsUsed = 22;
831         public short mCxmDenials = 23;
832         public short mTxSkipped = 24;
833         public short mRfLoss = 25;
834         public int mNativeClock = 26;
835         public int mLastTxAckTimestampLsto = 27;
836 
837         // BQR VS A2DP Choppy
838         public int mArrivalTime = 28;
839         public int mScheduleTime = 29;
840         public short mGlitchCountA2dp = 30;
841         public short mTxCxmDenialsA2dp = 31;
842         public short mRxCxmDenialsA2dp = 32;
843         public byte mAclTxQueueLength = 33;
844         public byte mLinkQuality = 3;
845 
846         // BQR VS SCO Choppy
847         public short mGlitchCountSco = 35;
848         public byte mIntervalEsco = 36;
849         public byte mWindowEsco = 37;
850         public byte mAirFormat = 2;
851         public short mInstanceCount = 39;
852         public short mTxCxmDenialsSco = 40;
853         public short mRxCxmDenialsSco = 41;
854         public short mTxAbortCount = 42;
855         public short mLateDispatch = 43;
856         public short mMicIntrMiss = 44;
857         public short mLpaIntrMiss = 45;
858         public short mSprIntrMiss = 46;
859         public short mPlcFillCount = 47;
860         public short mPlcDiscardCount = 51;
861         public short mMissedInstanceCount = 52;
862         public short mTxRetransmitSlotCount = 53;
863         public short mRxRetransmitSlotCount = 54;
864         public short mGoodRxFrameCount = 55;
865 
866         // BQR VS Connect Fail
867         public byte mFailReason = 0x3a;
868 
869         public static int[] QualityReportId = {
870             BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR,
871             BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO,
872             BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY,
873             BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY,
874             BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL,
875         };
876 
BQRParameters()877         private BQRParameters() {}
878 
getInstance()879         public static BQRParameters getInstance() {
880             if (INSTANCE == null) {
881                 INSTANCE = new BQRParameters();
882             }
883             return INSTANCE;
884         }
885 
setQualityReportId(byte id)886         public void setQualityReportId(byte id) {
887             mQualityReportId = id;
888         }
889 
getQualityReportId()890         public int getQualityReportId() {
891             return (int) mQualityReportId;
892         }
893 
getByteArray()894         public byte[] getByteArray() {
895             ByteBuffer ba;
896             ByteBuffer addrBuff = ByteBuffer.wrap(mAddress, 0, mAddress.length);
897 
898             switch ((int) mQualityReportId) {
899                 case BluetoothQualityReport.QUALITY_REPORT_ID_MONITOR:
900                     ba = ByteBuffer.allocate(mBqrCommonSize);
901                     break;
902                 case BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO:
903                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrVsLstoSize);
904                     break;
905                 case BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY:
906                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrVsA2dpChoppySize);
907                     break;
908                 case BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY:
909                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrVsScoChoppySize);
910                     break;
911                 case BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL:
912                     ba = ByteBuffer.allocate(mBqrCommonSize + mBqrConnectFailSize);
913                     break;
914                 default:
915                     ba = ByteBuffer.allocate(mBqrCommonSize);
916                     break;
917             }
918 
919             ba.order(ByteOrder.LITTLE_ENDIAN);
920 
921             ba.put(mQualityReportId);
922             ba.put(mPacketType);
923             ba.putShort(mConnectionHandle);
924             ba.put(mConnectionRole);
925             ba.put(mTxPowerLevel);
926             ba.put(mRssi);
927             ba.put(mSnr);
928             ba.put(mUnusedAfhChannelCount);
929             ba.put(mAfhSelectUnidealChannelCount);
930             ba.putShort(mLsto);
931             ba.putInt(mPiconetClock);
932             ba.putInt(mRetransmissionCount);
933             ba.putInt(mNoRxCount);
934             ba.putInt(mNakCount);
935             ba.putInt(mLastTxAckTimestamp);
936             ba.putInt(mFlowOffCount);
937             ba.putInt(mLastFlowOnTimestamp);
938             ba.putInt(mOverflowCount);
939             ba.putInt(mUnderflowCount);
940             ba.put(addrBuff);
941             ba.put(mCalFailedItemCount);
942 
943             if (mQualityReportId == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_APPROACH_LSTO) {
944                 ba.put(mConnState);
945                 ba.putInt(mBasebandStats);
946                 ba.putInt(mSlotsUsed);
947                 ba.putShort(mCxmDenials);
948                 ba.putShort(mTxSkipped);
949                 ba.putShort(mRfLoss);
950                 ba.putInt(mNativeClock);
951                 ba.putInt(mLastTxAckTimestampLsto);
952             } else if (mQualityReportId
953                     == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_A2DP_CHOPPY) {
954                 ba.putInt(mArrivalTime);
955                 ba.putInt(mScheduleTime);
956                 ba.putShort(mGlitchCountA2dp);
957                 ba.putShort(mTxCxmDenialsA2dp);
958                 ba.putShort(mRxCxmDenialsA2dp);
959                 ba.put(mAclTxQueueLength);
960                 ba.put(mLinkQuality);
961             } else if (mQualityReportId
962                     == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_SCO_CHOPPY) {
963                 ba.putShort(mGlitchCountSco);
964                 ba.put(mIntervalEsco);
965                 ba.put(mWindowEsco);
966                 ba.put(mAirFormat);
967                 ba.putShort(mInstanceCount);
968                 ba.putShort(mTxCxmDenialsSco);
969                 ba.putShort(mRxCxmDenialsSco);
970                 ba.putShort(mTxAbortCount);
971                 ba.putShort(mLateDispatch);
972                 ba.putShort(mMicIntrMiss);
973                 ba.putShort(mLpaIntrMiss);
974                 ba.putShort(mSprIntrMiss);
975                 ba.putShort(mPlcFillCount);
976                 ba.putShort(mPlcDiscardCount);
977                 ba.putShort(mMissedInstanceCount);
978                 ba.putShort(mTxRetransmitSlotCount);
979                 ba.putShort(mRxRetransmitSlotCount);
980                 ba.putShort(mGoodRxFrameCount);
981 
982             } else if (mQualityReportId
983                     == (byte) BluetoothQualityReport.QUALITY_REPORT_ID_CONN_FAIL) {
984                 ba.put(mFailReason);
985             }
986             return ba.array();
987         }
988     }
989 }
990