blob: ada71aef7db0dbba7716c33a6c0d03fffe6bd7fa [file] [log] [blame]
/*
* 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 "chpp/platform/chpp_init.h"
#include "chpp/app.h"
#include "chpp/platform/chpp_uart_link_manager.h"
#include "chpp/transport.h"
#include "chre/util/fixed_size_vector.h"
#include "chre/util/nested_data_ptr.h"
#include "core_monitor.h"
#include "environment.h"
#include "uart_map.h"
#include "task.h"
// Forward declaration
constexpr uint8_t chpp::UartLinkManager::kWifiWakeOutGpioPinNumber;
constexpr uint8_t chpp::UartLinkManager::kWifiWakeInGpiNumber;
constexpr uint8_t chpp::UartLinkManager::kGnssWakeOutGpioPinNumber;
constexpr uint8_t chpp::UartLinkManager::kGnssWakeInGpiNumber;
constexpr uint8_t chpp::UartLinkManager::kWwanWakeOutGpioPinNumber;
constexpr uint8_t chpp::UartLinkManager::kWwanWakeInGpiNumber;
using chre::FixedSizeVector;
using chre::NestedDataPtr;
namespace chpp {
namespace {
constexpr configSTACK_DEPTH_TYPE kChppTaskStackDepthWords = 0x400;
// Choose an appripriate priority to avoid initializing things too late.
// TODO: Configure priority in relation to CHRE based on end to end testing.
constexpr UBaseType_t kChppTaskPriority = tskIDLE_PRIORITY + 2;
// Structures to hold CHPP task related variables
constexpr size_t kChppLinkTotal = ChppLinkType::CHPP_LINK_TYPE_TOTAL;
TaskHandle_t gChppTaskHandleList[kChppLinkTotal];
ChppTransportState gChppTransportStateList[kChppLinkTotal];
ChppAppState gChppAppStateList[kChppLinkTotal];
FixedSizeVector<chpp::UartLinkManager, kChppLinkTotal> gManagerList;
struct ChppClientServiceSet getClientServiceSet(ChppLinkType type) {
struct ChppClientServiceSet set = {};
switch (type) {
case ChppLinkType::CHPP_LINK_TYPE_WIFI:
set.wifiClient = 1;
break;
case ChppLinkType::CHPP_LINK_TYPE_GNSS:
set.gnssClient = 1;
break;
case ChppLinkType::CHPP_LINK_TYPE_WWAN:
set.wwanClient = 1;
break;
default:
LOGE("Invalid type %d to get client/service set", type);
CHRE_ASSERT(false);
}
return set;
}
// Initializes the CHPP instance and runs the work thread.
void chppThreadEntry(void *context) {
ChppLinkType type = NestedDataPtr<ChppLinkType>(context);
struct ChppTransportState *transportState = &gChppTransportStateList[type];
struct ChppAppState *appState = &gChppAppStateList[type];
chppTransportInit(transportState, appState);
chppAppInitWithClientServiceSet(appState, transportState,
getClientServiceSet(type));
chppWorkThreadStart(transportState);
chppAppDeinit(appState);
chppTransportDeinit(transportState);
vTaskDelete(nullptr);
gChppTaskHandleList[type] = nullptr;
}
BaseType_t startChppWorkThread(ChppLinkType type, const char *taskName) {
struct ChppTransportState *transportState = &gChppTransportStateList[type];
transportState->linkParams.uartLinkManager = &gManagerList[type];
return xTaskCreate(chppThreadEntry, taskName, kChppTaskStackDepthWords,
NestedDataPtr<ChppLinkType>(type) /* args */,
kChppTaskPriority, &gChppTaskHandleList[type]);
}
void stopChppWorkThread(ChppLinkType type) {
if (gChppTaskHandleList[type] != nullptr) {
chppWorkThreadStop(&gChppTransportStateList[type]);
}
}
} // namespace
void init() {
gManagerList.emplace_back(
&gChppTransportStateList[ChppLinkType::CHPP_LINK_TYPE_WIFI],
Environment::Instance()->UART(UART_MAP::UART_MAP_WIFI),
chpp::UartLinkManager::kWifiWakeOutGpioPinNumber,
chpp::UartLinkManager::kWifiWakeInGpiNumber,
PREVENT_MONITOR_MODE_MASK_UART_2);
gManagerList.emplace_back(
&gChppTransportStateList[ChppLinkType::CHPP_LINK_TYPE_GNSS],
Environment::Instance()->UART(UART_MAP::UART_MAP_GNSS),
chpp::UartLinkManager::kGnssWakeOutGpioPinNumber,
chpp::UartLinkManager::kGnssWakeInGpiNumber,
PREVENT_MONITOR_MODE_MASK_UART_1, true /* wakeHandshake */);
gManagerList.emplace_back(
&gChppTransportStateList[ChppLinkType::CHPP_LINK_TYPE_WWAN],
Environment::Instance()->UART(UART_MAP::UART_MAP_MODEM),
chpp::UartLinkManager::kWwanWakeOutGpioPinNumber,
chpp::UartLinkManager::kWwanWakeInGpiNumber,
PREVENT_MONITOR_MODE_MASK_UART_3, true /* wakeHandshake */);
BaseType_t rc =
startChppWorkThread(ChppLinkType::CHPP_LINK_TYPE_WIFI, "CHPP WIFI");
CHRE_ASSERT(rc == pdPASS);
rc = startChppWorkThread(ChppLinkType::CHPP_LINK_TYPE_GNSS, "CHPP GNSS");
CHRE_ASSERT(rc == pdPASS);
rc = startChppWorkThread(ChppLinkType::CHPP_LINK_TYPE_WWAN, "CHPP WWAN");
CHRE_ASSERT(rc == pdPASS);
}
void deinit() {
stopChppWorkThread(ChppLinkType::CHPP_LINK_TYPE_WIFI);
stopChppWorkThread(ChppLinkType::CHPP_LINK_TYPE_GNSS);
stopChppWorkThread(ChppLinkType::CHPP_LINK_TYPE_WWAN);
}
ChppAppState *getChppAppState(ChppLinkType linkType) {
CHRE_ASSERT(linkType < ChppLinkType::CHPP_LINK_TYPE_TOTAL);
return (linkType < ChppLinkType::CHPP_LINK_TYPE_TOTAL)
? &gChppAppStateList[linkType]
: nullptr;
}
} // namespace chpp