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

Commit 33277cdc authored by Chris Weir's avatar Chris Weir Committed by Android (Google) Code Review
Browse files

Merge "CAN Configurator Service" into rvc-dev

parents 8fd2a85b 01247f95
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@ cc_binary {
    header_libs: [
        "android.hardware.automotive.can@hidl-utils-lib",
    ],
    static_libs: [
        "android.hardware.automotive.can@libcanhaltools",
    ],
}

cc_binary {
@@ -42,6 +45,9 @@ cc_binary {
    header_libs: [
        "android.hardware.automotive.can@hidl-utils-lib",
    ],
    static_libs: [
        "android.hardware.automotive.can@libcanhaltools",
    ],
}

cc_binary {
@@ -54,4 +60,7 @@ cc_binary {
        "android.hardware.automotive.can@1.0",
        "libhidlbase",
    ],
    static_libs: [
        "android.hardware.automotive.can@libcanhaltools",
    ],
}
+4 −20
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <android/hardware/automotive/can/1.0/ICanController.h>
#include <android/hidl/manager/1.2/IServiceManager.h>
#include <hidl-utils/hidl-utils.h>
#include <libcanhaltools/libcanhaltools.h>

#include <iostream>
#include <string>
@@ -41,34 +42,17 @@ static void usage() {
    std::cerr << " bus name - name under which ICanBus will be published" << std::endl;
}

static hidl_vec<hidl_string> getControlServices() {
    auto manager = hidl::manager::V1_2::IServiceManager::getService();
    hidl_vec<hidl_string> services;
    manager->listManifestByInterface(ICanController::descriptor, hidl_utils::fill(&services));
    if (services.size() == 0) {
        std::cerr << "No ICanController services registered (missing privileges?)" << std::endl;
        exit(-1);
    }
    return services;
}

static bool isSupported(sp<ICanController> ctrl, ICanController::InterfaceType iftype) {
    hidl_vec<ICanController::InterfaceType> supported;
    if (!ctrl->getSupportedInterfaceTypes(hidl_utils::fill(&supported)).isOk()) return false;
    return supported.contains(iftype);
}

static int up(const std::string& busName, ICanController::InterfaceType type,
              const std::string& interface, uint32_t bitrate) {
    bool anySupported = false;
    for (auto&& service : getControlServices()) {
    for (auto&& service : libcanhaltools::getControlServices()) {
        auto ctrl = ICanController::getService(service);
        if (ctrl == nullptr) {
            std::cerr << "Couldn't open ICanController/" << service;
            continue;
        }

        if (!isSupported(ctrl, type)) continue;
        if (!libcanhaltools::isSupported(ctrl, type)) continue;
        anySupported = true;

        ICanController::BusConfig config = {};
@@ -111,7 +95,7 @@ static int up(const std::string& busName, ICanController::InterfaceType type,
}

static int down(const std::string& busName) {
    for (auto&& service : getControlServices()) {
    for (auto&& service : libcanhaltools::getControlServices()) {
        auto ctrl = ICanController::getService(service);
        if (ctrl == nullptr) continue;

+34 −0
Original line number Diff line number Diff line
//
// Copyright (C) 2020 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.
//

cc_binary {
    name: "canhalconfigurator",
    init_rc: ["canhalconfigurator.rc"],
    defaults: ["android.hardware.automotive.can@defaults"],
    srcs: [
        "canhalconfigurator.cpp",
        "canprototools.cpp",
    ],
    shared_libs: [
        "android.hardware.automotive.can@1.0",
        "libhidlbase",
        "libprotobuf-cpp-full",
    ],
    static_libs: [
        "android.hardware.automotive.can@1.x-config-format",
        "android.hardware.automotive.can@libcanhaltools",
    ],
}
+103 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 "canbus_config.pb.h"
#include "canprototools.h"

#include <android-base/logging.h>
#include <android/hardware/automotive/can/1.0/ICanController.h>
#include <libcanhaltools/libcanhaltools.h>

#include <chrono>
#include <thread>

namespace android::hardware::automotive::can {

using ICanController = V1_0::ICanController;

/**
 * Takes output from parsed protobuf config and uses it to configure the CAN HAL.
 *
 * \param pb_cfg is an instance of the autogenerated protobuf object for our configuration.
 * \return boolean status, true on success, false on failure.
 */
static bool processPbCfg(const config::CanBusConfig& pb_cfg) {
    for (auto const& bus : pb_cfg.buses()) {
        if (bus.name().empty()) {
            LOG(ERROR) << "Invalid config: Bus config must have a valid name field";
            return false;
        }

        LOG(INFO) << "Configure " << bus.name();
        auto bus_cfg = config::fromPbBus(bus);
        if (!bus_cfg.has_value()) {
            return false;
        }

        // TODO(149405589): remove this sleep and associated includes.
        std::this_thread::sleep_for(std::chrono::seconds(1));
        if (libcanhaltools::configureIface(*bus_cfg) != ICanController::Result::OK) {
            LOG(ERROR) << "No controller supports " << bus.name() << std::endl;
            // TODO(149405589): add retry logic in case a bus fails to come up.
            continue;
        }
        LOG(INFO) << bus.name() << " has been successfully configured!";
    }
    return true;
}

/**
 * This kicks off the CAN HAL configuration process. This starts the following:
 *     1. Reading the config file
 *     2. Setting up CAN buses
 *     3. Handling services
 * \param filepath is a string specifying the absolute path of the config file
 * \return boolean status, true on success, false on failure
 */
static bool configuratorStart(const std::string& filepath) {
    base::SetDefaultTag("CanConfigurator");

    auto pb_cfg = config::parseConfigFile(filepath);
    if (!pb_cfg.has_value()) {
        return false;
    }

    // process the rest of the config file data and configure the CAN buses.
    if (!processPbCfg(*pb_cfg)) {
        return false;
    }
    LOG(INFO) << "CAN HAL has been configured!";
    return true;
}

}  // namespace android::hardware::automotive::can

int main(int argc, char* argv[]) {
    std::string config_filepath = "/etc/canbus_config.pb";

    // allow for CLI specification of a config file.
    if (argc == 2) {
        config_filepath = argv[1];
    } else if (argc > 2) {
        std::cerr << "usage: " << argv[0] << " [optional config filepath]";
        return 1;
    }

    if (!::android::hardware::automotive::can::configuratorStart(config_filepath)) {
        return 1;
    }
    return 0;
}
+3 −0
Original line number Diff line number Diff line
service canhalconfigurator /system/bin/canhalconfigurator
  class core
  oneshot
Loading