Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61ff31ae authored by Wei Wang's avatar Wei Wang Committed by Android Git Automerger
Browse files

am bf7a7500: am f18d8b5d: am bd086a90: am b43c6aad: Fix batch timestamp parsing error.

* commit 'bf7a7500':
  Fix batch timestamp parsing error.
parents 37185df1 bf7a7500
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import android.util.Log;
import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.bluetooth.btservice.ProfileService;
import com.android.bluetooth.util.NumberUtils;
import com.android.internal.annotations.VisibleForTesting;

import java.util.ArrayList;
import java.util.Arrays;
@@ -1029,27 +1031,26 @@ public class GattService extends ProfileService {
    private Set<ScanResult> parseTruncatedResults(int numRecords, byte[] batchRecord) {
        if (DBG) Log.d(TAG, "batch record " + Arrays.toString(batchRecord));
        Set<ScanResult> results = new HashSet<ScanResult>(numRecords);
        long now = SystemClock.elapsedRealtimeNanos();
        for (int i = 0; i < numRecords; ++i) {
            byte[] record = extractBytes(batchRecord, i * TRUNCATED_RESULT_SIZE,
                    TRUNCATED_RESULT_SIZE);
            byte[] address = extractBytes(record, 0, 6);
            // TODO: remove temp hack.
            reverse(address);
            BluetoothDevice device = mAdapter.getRemoteDevice(address);
            int rssi = record[8];
            // Timestamp is in every 50 ms.
            long timestampNanos = parseTimestampNanos(extractBytes(record, 9, 2));
            long timestampNanos = now - parseTimestampNanos(extractBytes(record, 9, 2));
            results.add(new ScanResult(device, ScanRecord.parseFromBytes(new byte[0]),
                    rssi, timestampNanos));
        }
        return results;
    }

    private long parseTimestampNanos(byte[] data) {
        long timestampUnit = data[1] & 0xFF << 8 + data[0];
        long timestampNanos = SystemClock.elapsedRealtimeNanos() -
                TimeUnit.MILLISECONDS.toNanos(timestampUnit * 50);
        return timestampNanos;
    @VisibleForTesting
    long parseTimestampNanos(byte[] data) {
        long timestampUnit = NumberUtils.littleEndianByteArrayToInt(data);
        // Timestamp is in every 50 ms.
        return TimeUnit.MILLISECONDS.toNanos(timestampUnit * 50);
    }

    private Set<ScanResult> parseFullResults(int numRecords, byte[] batchRecord) {
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

package com.android.bluetooth.util;

/**
 * Utility for parsing numbers in Bluetooth.
 */
public class NumberUtils {

    /**
     * Convert a byte to unsigned int.
     */
    public static int unsignedByteToInt(byte b) {
        return b & 0xFF;
    }

    /**
     * Convert a little endian byte array to integer.
     */
    public static int littleEndianByteArrayToInt(byte[] bytes) {
        int length = bytes.length;
        if (length == 0) {
            return 0;
        }
        int result = 0;
        for (int i = length - 1; i >= 0; i--) {
            int value = unsignedByteToInt(bytes[i]);
            result += (value << (i * 8));
        }
        return result;
    }
}
+22 −0
Original line number Diff line number Diff line

package com.android.bluetooth.gatt;

import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;

import com.android.bluetooth.gatt.GattService;

/**
 * Test cases for {@link GattService}.
 */
public class GattServiceTest extends AndroidTestCase {

    @SmallTest
    public void testParseBatchTimestamp() {
        GattService service = new GattService();
        long timestampNanos = service.parseTimestampNanos(new byte[] {
                -54, 7 });
        assertEquals(99700000000L, timestampNanos);
    }

}
+43 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * 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.
 */

package com.android.bluetooth.util;

import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;

/**
 * Tests for {@link NumberUtils}.
 */
public class NumberUtilsTest extends AndroidTestCase {

    @SmallTest
    public static void testUnsignedByteToInt() {
        assertEquals(0, NumberUtils.unsignedByteToInt((byte) 0));
        assertEquals(19, NumberUtils.unsignedByteToInt((byte) 19));
        assertEquals(154, NumberUtils.unsignedByteToInt((byte) 154));
    }

    @SmallTest
    public void testLittleEndianByteArrayToInt() {
        assertEquals(1, NumberUtils.littleEndianByteArrayToInt(new byte[] {
                1 }));
        assertEquals(513, NumberUtils.littleEndianByteArrayToInt(new byte[] {
                1, 2 }));
        assertEquals(197121, NumberUtils.littleEndianByteArrayToInt(new byte[] {
                1, 2, 3 }));
    }
}