blob: 643cecc44d9fdb3f44da9acd61eb1d391b78b3d7 [file] [log] [blame]
/*
*
* Copyright (c) 2020 Project CHIP Authors
* Copyright (c) 2019 Nest Labs, Inc.
*
* 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.
*/
/* this file behaves like a config.h, comes first */
#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <platform/Infineon/CYW30739/DiagnosticDataProviderImpl.h>
#include <platform/PlatformManager.h>
#include <platform/internal/GenericPlatformManagerImpl.ipp>
#include <crypto/CHIPCryptoPAL.h>
#include <hal/wiced_memory.h>
#include <wiced_platform.h>
namespace chip {
namespace DeviceLayer {
PlatformManagerImpl PlatformManagerImpl::sInstance;
CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
{
CHIP_ERROR err = CHIP_NO_ERROR;
wiced_result_t result;
// Initialize the configuration system.
err = PersistedStorage::KeyValueStoreMgrImpl().Init();
SuccessOrExit(err);
/* Create the thread object. */
mThread = wiced_rtos_create_thread();
VerifyOrExit(mThread != nullptr, err = CHIP_ERROR_NO_MEMORY);
/* Initialize the event flags. */
ReturnErrorOnFailure(mEventFlags.Init());
/* Initialize the event queue. */
mEventQueue = wiced_rtos_create_queue();
VerifyOrExit(mEventQueue != nullptr, err = CHIP_ERROR_NO_MEMORY);
result = wiced_rtos_init_queue(mEventQueue, "EventQueue", sizeof(ChipDeviceEvent), CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE);
VerifyOrExit(result == WICED_SUCCESS, err = CHIP_ERROR_NO_MEMORY);
/* Initialize the timer. */
result = wiced_init_timer(&mTimer, TimerCallback, 0, WICED_MILLI_SECONDS_TIMER);
VerifyOrExit(result == WICED_SUCCESS, err = CHIP_ERROR_INTERNAL);
/* Initialize the mutex. */
mMutex = wiced_rtos_create_mutex();
VerifyOrExit(mMutex != nullptr, err = CHIP_ERROR_NO_MEMORY);
result = wiced_rtos_init_mutex(mMutex);
VerifyOrExit(result == WICED_SUCCESS, err = CHIP_ERROR_INTERNAL);
ReturnErrorOnFailure(chip::Crypto::add_entropy_source(GetEntropy, NULL, 16));
ReturnErrorOnFailure(GenericPlatformManagerImpl<ImplClass>::_InitChipStack());
exit:
return err;
}
void PlatformManagerImpl::_RunEventLoop(void)
{
ChipLogDetail(DeviceLayer, "Free RAM sizes: %lu\n", wiced_memory_get_free_bytes());
while (true)
{
uint32_t flags_set = 0;
if (mEventFlags.WaitAnyForever(flags_set) != CHIP_NO_ERROR)
{
continue;
}
if (flags_set & kTimerEventFlag)
{
HandleTimerEvent();
}
if (flags_set & kPostEventFlag)
{
HandlePostEvent();
}
}
}
CHIP_ERROR PlatformManagerImpl::_StartEventLoopTask(void)
{
CHIP_ERROR err = CHIP_NO_ERROR;
wiced_result_t result;
result = wiced_rtos_init_thread(mThread, CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY, CHIP_DEVICE_CONFIG_CHIP_TASK_NAME,
EventLoopTaskMain, CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE, this);
VerifyOrExit(result == WICED_SUCCESS, err = CHIP_ERROR_NO_MEMORY);
exit:
return err;
}
CHIP_ERROR PlatformManagerImpl::_StopEventLoopTask()
{
return CHIP_NO_ERROR;
}
void PlatformManagerImpl::_LockChipStack(void)
{
const wiced_result_t result = wiced_rtos_lock_mutex(mMutex);
VerifyOrReturn(result == WICED_SUCCESS, ChipLogError(DeviceLayer, "%s %x", __func__, result));
}
void PlatformManagerImpl::_UnlockChipStack(void)
{
const wiced_result_t result = wiced_rtos_unlock_mutex(mMutex);
VerifyOrReturn(result == WICED_SUCCESS || result == WICED_NOT_OWNED, ChipLogError(DeviceLayer, "%s %x", __func__, result));
}
CHIP_ERROR PlatformManagerImpl::_PostEvent(const ChipDeviceEvent * event)
{
const wiced_result_t result = wiced_rtos_push_to_queue(mEventQueue, const_cast<ChipDeviceEvent *>(event), WICED_NO_WAIT);
if (WICED_SUCCESS != result)
{
ChipLogError(DeviceLayer, "wiced_rtos_push_to_queue %u", result);
return CHIP_ERROR_INTERNAL;
}
mEventFlags.Set(kPostEventFlag);
return CHIP_NO_ERROR;
}
CHIP_ERROR PlatformManagerImpl::_StartChipTimer(System::Clock::Timeout durationMS)
{
if (durationMS.count() == 0)
{
TimerCallback(0);
}
else
{
const wiced_result_t result = wiced_start_timer(&mTimer, durationMS.count());
if (WICED_SUCCESS != result)
{
ChipLogError(DeviceLayer, "wiced_start_timer 0x%02x", result);
return CHIP_ERROR_INTERNAL;
}
}
return CHIP_NO_ERROR;
}
void PlatformManagerImpl::_Shutdown() {}
void PlatformManagerImpl::HandleTimerEvent(void)
{
const CHIP_ERROR err = static_cast<System::LayerImplFreeRTOS &>(DeviceLayer::SystemLayer()).HandlePlatformTimer();
if (err != CHIP_NO_ERROR)
{
ChipLogError(DeviceLayer, "HandlePlatformTimer %ld", err.AsInteger());
}
}
void PlatformManagerImpl::HandlePostEvent(void)
{
wiced_result_t result;
ChipDeviceEvent event;
/* Check the event queue. */
if (wiced_rtos_is_queue_empty(mEventQueue))
{
return;
}
/* Pop one event from the event queue. */
result = wiced_rtos_pop_from_queue(mEventQueue, &event, WICED_WAIT_FOREVER);
if (WICED_SUCCESS != result)
{
ChipLogError(DeviceLayer, "wiced_rtos_pop_from_queue %u", result);
return;
}
/* Process this event. */
DispatchEvent(&event);
/* Set another application thread event if the event queue is not empty. */
if (!wiced_rtos_is_queue_empty(mEventQueue))
{
mEventFlags.Set(kPostEventFlag);
}
}
void PlatformManagerImpl::EventLoopTaskMain(uint32_t arg)
{
ChipLogDetail(DeviceLayer, "CHIP task running");
reinterpret_cast<PlatformManagerImpl *>(arg)->RunEventLoop();
}
void PlatformManagerImpl::TimerCallback(WICED_TIMER_PARAM_TYPE params)
{
PlatformMgrImpl().mEventFlags.Set(kTimerEventFlag);
}
int PlatformManagerImpl::GetEntropy(void * data, unsigned char * output, size_t len, size_t * olen)
{
const wiced_result_t result = wiced_platform_entropy_get(output, static_cast<uint16_t>(len));
if (result != WICED_SUCCESS)
{
return -1;
}
*olen = len;
return 0;
}
} // namespace DeviceLayer
} // namespace chip