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

Commit 5899e8e9 authored by xshu's avatar xshu
Browse files

move ringbuffer interactions to wifi hal

Shallow copy of ringbuffer is stored inside the hal.
The maximum ringbuffer size is configured by the
framework.

overrides IBase::debug to:
1. write ringbuffers in memory to flash (wifi tombstones)
2. write wifi tombstones to lshal debug fd in archived format

Bug: 70171481
Test: compile, run on device
Test: run "lshal debug android.hardware.wifi@1.2::IWifi >>
archive.cpio" and compared archived files with originals using diff command
Change-Id: I33c30e37f245cfa36e005ba8cdc46e91f6de9237
parent f9b98e52
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ endif
LOCAL_SRC_FILES := \
    hidl_struct_util.cpp \
    hidl_sync_util.cpp \
    ringbuffer.cpp \
    wifi.cpp \
    wifi_ap_iface.cpp \
    wifi_chip.cpp \
@@ -97,6 +98,7 @@ LOCAL_SRC_FILES := \
    tests/mock_wifi_feature_flags.cpp \
    tests/mock_wifi_legacy_hal.cpp \
    tests/mock_wifi_mode_controller.cpp \
    tests/ringbuffer_unit_tests.cpp \
    tests/wifi_chip_unit_tests.cpp
LOCAL_STATIC_LIBRARIES := \
    libgmock \
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.
 */

#include "ringbuffer.h"

namespace android {
namespace hardware {
namespace wifi {
namespace V1_2 {
namespace implementation {

Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}

void Ringbuffer::append(const std::vector<uint8_t>& input) {
    if (input.size() == 0) {
        return;
    }
    data_.push_back(input);
    size_ += input.size() * sizeof(input[0]);
    while (size_ > maxSize_) {
        size_ -= data_.front().size() * sizeof(data_.front()[0]);
        data_.pop_front();
    }
}

const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const {
    return data_;
}

}  // namespace implementation
}  // namespace V1_2
}  // namespace wifi
}  // namespace hardware
}  // namespace android
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.
 */

#ifndef RINGBUFFER_H_
#define RINGBUFFER_H_

#include <list>
#include <vector>

namespace android {
namespace hardware {
namespace wifi {
namespace V1_2 {
namespace implementation {

/**
 * Ringbuffer object used to store debug data.
 */
class Ringbuffer {
   public:
    explicit Ringbuffer(size_t maxSize);

    // Appends the data buffer and deletes from the front until buffer is
    // within |maxSize_|.
    void append(const std::vector<uint8_t>& input);
    const std::list<std::vector<uint8_t>>& getData() const;

   private:
    std::list<std::vector<uint8_t>> data_;
    size_t size_;
    size_t maxSize_;
};

}  // namespace implementation
}  // namespace V1_2
}  // namespace wifi
}  // namespace hardware
}  // namespace android

#endif  // RINGBUFFER_H_
+88 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018, 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.
 */

#include <gmock/gmock.h>

#include "ringbuffer.h"

using testing::Return;
using testing::Test;

namespace android {
namespace hardware {
namespace wifi {
namespace V1_2 {
namespace implementation {

class RingbufferTest : public Test {
   public:
    const uint32_t maxBufferSize_ = 10;
    Ringbuffer buffer_{maxBufferSize_};
};

TEST_F(RingbufferTest, CreateEmptyBuffer) {
    ASSERT_TRUE(buffer_.getData().empty());
}

TEST_F(RingbufferTest, CanUseFullBufferCapacity) {
    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
    buffer_.append(input);
    buffer_.append(input2);
    ASSERT_EQ(2u, buffer_.getData().size());
    EXPECT_EQ(input, buffer_.getData().front());
    EXPECT_EQ(input2, buffer_.getData().back());
}

TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) {
    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
    const std::vector<uint8_t> input3 = {'G'};
    buffer_.append(input);
    buffer_.append(input2);
    buffer_.append(input3);
    ASSERT_EQ(2u, buffer_.getData().size());
    EXPECT_EQ(input2, buffer_.getData().front());
    EXPECT_EQ(input3, buffer_.getData().back());
}

TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) {
    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
    const std::vector<uint8_t> input3(maxBufferSize_, '2');
    buffer_.append(input);
    buffer_.append(input2);
    buffer_.append(input3);
    ASSERT_EQ(1u, buffer_.getData().size());
    EXPECT_EQ(input3, buffer_.getData().front());
}

TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) {
    const std::vector<uint8_t> input = {};
    buffer_.append(input);
    ASSERT_TRUE(buffer_.getData().empty());
}

TEST_F(RingbufferTest, OversizedAppendIsDropped) {
    const std::vector<uint8_t> input(maxBufferSize_ + 1, '0');
    buffer_.append(input);
    ASSERT_TRUE(buffer_.getData().empty());
}
}  // namespace implementation
}  // namespace V1_2
}  // namespace wifi
}  // namespace hardware
}  // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -77,6 +77,12 @@ Return<void> Wifi::getChip(ChipId chip_id, getChip_cb hidl_status_cb) {
                           &Wifi::getChipInternal, hidl_status_cb, chip_id);
}

Return<void> Wifi::debug(const hidl_handle& handle,
                         const hidl_vec<hidl_string>&) {
    LOG(INFO) << "-----------Debug is called----------------";
    return chip_->debug(handle, {});
}

WifiStatus Wifi::registerEventCallbackInternal(
    const sp<IWifiEventCallback>& event_callback) {
    if (!event_cb_handler_.addCallback(event_callback)) {
Loading