blob: 05e53f40bd044aac6c0afd1b4a250a093067c6d1 [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2020 Nest Labs, Inc.
* All rights reserved.
*
* 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.
*/
/**
* @file
* Provides an implementation of the PlatformManager object
* for K32W platforms using the NXP K32W SDK.
*/
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <crypto/CHIPCryptoPAL.h>
#include <openthread-system.h>
#include <platform/PlatformManager.h>
#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp>
#include <platform/nxp/k32w/k32w0/DiagnosticDataProviderImpl.h>
#include <platform/nxp/k32w/k32w0/KeyValueStoreManagerImpl.h>
#if CHIP_SYSTEM_CONFIG_USE_LWIP
#include <lwip/tcpip.h>
#endif
#if defined(MBEDTLS_USE_TINYCRYPT)
#include "ecc.h"
#endif
#include <openthread/platform/entropy.h>
#include "MemManager.h"
#include "PDM.h"
#include "RNG_Interface.h"
#include "SecLib.h"
#include "TimersManager.h"
#include "board.h"
#include "fsl_sha.h"
#include "k32w0-chip-mbedtls-config.h"
namespace chip {
namespace DeviceLayer {
PlatformManagerImpl PlatformManagerImpl::sInstance;
#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode)
extern "C" void InitLowPower();
#endif
#if defined(MBEDTLS_USE_TINYCRYPT)
osaMutexId_t PlatformManagerImpl::rngMutexHandle = NULL;
#endif
CHIP_ERROR PlatformManagerImpl::InitBoardFwk(void)
{
CHIP_ERROR err = CHIP_NO_ERROR;
char initString[] = "app";
char * argv[1] = { 0 };
argv[0] = &initString[0];
SHA_ClkInit(SHA_INSTANCE);
if (MEM_Init() != MEM_SUCCESS_c)
{
err = CHIP_ERROR_NO_MEMORY;
goto exit;
}
if (RNG_Init() != gRngSuccess_d)
{
err = CHIP_ERROR_RANDOM_DATA_UNAVAILABLE;
goto exit;
}
RNG_SetPseudoRandomNoSeed(NULL);
SecLib_Init();
TMR_Init();
/* Used for OT initializations */
otSysInit(1, argv);
#if gAdcUsed_d
BOARD_ADCWakeupInit();
#endif
#if defined(cPWR_UsePowerDownMode) && (cPWR_UsePowerDownMode)
/* Low Power Init */
InitLowPower();
#endif
exit:
return err;
}
static int app_entropy_source(void * data, unsigned char * output, size_t len, size_t * olen)
{
otError otErr = otPlatEntropyGet(output, (uint16_t) len);
if (otErr != OT_ERROR_NONE)
{
return -1;
}
*olen = len;
return 0;
}
#if defined(MBEDTLS_USE_TINYCRYPT)
int PlatformManagerImpl::uECC_RNG_Function(uint8_t * dest, unsigned int size)
{
int res;
OSA_MutexLock(rngMutexHandle, osaWaitForever_c);
res = (chip::Crypto::DRBG_get_bytes(dest, size) == CHIP_NO_ERROR) ? size : 0;
OSA_MutexUnlock(rngMutexHandle);
return res;
}
#endif
#if CHIP_DEVICE_LAYER_ENABLE_PDM_LOGS
static void PDM_SystemCallback(uint32_t number, PDM_eSystemEventCode code)
{
uint8_t capacity = PDM_u8GetSegmentCapacity();
uint8_t occupancy = PDM_u8GetSegmentOccupancy();
ChipLogProgress(DeviceLayer, "[PDM]Event (number, code): (%lu, %d)", number, code);
ChipLogProgress(DeviceLayer, "[PDM]Capacity: %hhu", capacity);
ChipLogProgress(DeviceLayer, "[PDM]Occupancy: %hhu", occupancy);
}
#endif
static CHIP_ERROR MapPdmInitStatusToChipError(int status)
{
return (status == 0) ? CHIP_NO_ERROR : CHIP_ERROR(ChipError::Range::kPlatform, status);
}
CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
{
uint32_t chipType;
CHIP_ERROR err = CHIP_NO_ERROR;
int status;
/* Initialise the Persistent Data Manager */
status = PDM_Init();
SuccessOrExit(err = MapPdmInitStatusToChipError(status));
#if CHIP_DEVICE_LAYER_ENABLE_PDM_LOGS
PDM_vRegisterSystemCallback(PDM_SystemCallback);
#endif
// Initialize the configuration system.
err = Internal::K32WConfig::Init();
SuccessOrExit(err);
err = PersistedStorage::KeyValueStoreManagerImpl::Init();
SuccessOrExit(err);
chipType = Chip_GetType();
if ((chipType != CHIP_K32W061) && (chipType != CHIP_K32W041) && (chipType != CHIP_K32W041A) && (chipType != CHIP_K32W041AM))
{
err = CHIP_ERROR_INTERNAL;
ChipLogError(DeviceLayer, "Invalid chip type, expected K32W061");
goto exit;
}
SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance());
mStartTime = System::SystemClock().GetMonotonicTimestamp();
#if CHIP_SYSTEM_CONFIG_USE_LWIP
// Initialize LwIP.
tcpip_init(NULL, NULL);
#endif
err = chip::Crypto::add_entropy_source(app_entropy_source, NULL, 16);
SuccessOrExit(err);
#if defined(MBEDTLS_USE_TINYCRYPT)
/* Set RNG function for tinycrypt operations. */
rngMutexHandle = OSA_MutexCreate();
VerifyOrExit((NULL != rngMutexHandle), err = CHIP_ERROR_NO_MEMORY);
uECC_set_rng(PlatformManagerImpl::uECC_RNG_Function);
#endif
// Call _InitChipStack() on the generic implementation base class
// to finish the initialization process.
err = Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_InitChipStack();
SuccessOrExit(err);
exit:
return err;
}
void PlatformManagerImpl::_Shutdown()
{
uint64_t upTime = 0;
if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR)
{
uint32_t totalOperationalHours = 0;
if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR)
{
ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast<uint32_t>(upTime / 3600));
}
else
{
ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node");
}
}
else
{
ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot");
}
Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_Shutdown();
}
} // namespace DeviceLayer
} // namespace chip