diff --git a/examples/lighting-app/ameba/.gitignore b/examples/lighting-app/ameba/.gitignore new file mode 100644 index 00000000000000..234526a082ad26 --- /dev/null +++ b/examples/lighting-app/ameba/.gitignore @@ -0,0 +1,5 @@ +*.vscode + +/build/ +/sdkconfig +/sdkconfig.old diff --git a/examples/lighting-app/ameba/chip_main.cmake b/examples/lighting-app/ameba/chip_main.cmake new file mode 100755 index 00000000000000..f692189a93d7c4 --- /dev/null +++ b/examples/lighting-app/ameba/chip_main.cmake @@ -0,0 +1,108 @@ +cmake_minimum_required(VERSION 3.6) + +project(chip_main) + +set(chip_dir "${ameba_matter_root}") +set(chip_dir_output "${matter_output_path}/chip") +set(dir "${sdk_root}/component/common/api") +set(chip_main chip_main) +set(list_chip_main_sources chip_main_sources) + +include(${prj_root}/GCC-RELEASE/project_hp/asdk/includepath.cmake) + +list( + APPEND ${list_chip_main_sources} + + #chip app + ${chip_dir}/src/app/Command.cpp + ${chip_dir}/src/app/CommandHandler.cpp + ${chip_dir}/src/app/InteractionModelEngine.cpp + ${chip_dir}/src/app/CommandSender.cpp + ${chip_dir}/src/app/decoder.cpp + ${chip_dir}/src/app/encoder-common.cpp + ${chip_dir}/src/app/EventManagement.cpp + ${chip_dir}/src/app/ReadClient.cpp + ${chip_dir}/src/app/ReadHandler.cpp + ${chip_dir}/src/app/WriteClient.cpp + ${chip_dir}/src/app/WriteHandler.cpp + ${chip_dir}/src/app/util/CHIPDeviceCallbacksMgr.cpp + ${chip_dir}/src/app/util/esi-management.cpp + ${chip_dir}/src/app/reporting/Engine.cpp + + ${chip_dir}/zzz_generated/lighting-app/zap-generated/attribute-size.cpp + ${chip_dir}/zzz_generated/lighting-app/zap-generated/CHIPClientCallbacks.cpp + ${chip_dir}/zzz_generated/lighting-app/zap-generated/callback-stub.cpp + ${chip_dir}/zzz_generated/lighting-app/zap-generated/IMClusterCommandHandler.cpp + ${chip_dir}/zzz_generated/lighting-app/zap-generated/CHIPClusters.cpp + + ${chip_dir}/examples/lighting-app/lighting-common/color_format/color_format.cpp + + ${chip_dir}/examples/lighting-app/ameba/main/chipinterface.cpp + ${chip_dir}/examples/lighting-app/ameba/main/DeviceCallbacks.cpp + ${chip_dir}/examples/lighting-app/ameba/main/CHIPDeviceManager.cpp + ${chip_dir}/examples/lighting-app/ameba/main/Globals.cpp + ${chip_dir}/examples/lighting-app/ameba/main/LEDWidget.cpp +) + +add_library( + ${chip_main} + STATIC + ${chip_main_sources} +) + +chip_configure_data_model(chip_main + INCLUDE_SERVER + ZAP_FILE ${matter_example_path}/../lighting-common/lighting-app.zap +) + +target_include_directories( + ${chip_main} + PUBLIC + ${inc_path} + ${chip_dir}/zzz_generated/lighting-app + ${chip_dir}/zzz_generated/lighting-app/zap-generated + ${chip_dir}/zzz_generated/app-common + ${chip_dir}/examples/lighting-app/lighting-common + ${chip_dir}/examples/lighting-app/lighting-common/color_format + ${chip_dir}/examples/lighting-app/ameba/main/include + ${chip_dir_output}/gen/include + ${chip_dir}/src/include/ + ${chip_dir}/src/lib/ + ${chip_dir}/src/ + ${chip_dir}/third_party/nlassert/repo/include/ + ${chip_dir}/src/app/ + ${chip_dir}/src/app/util/ + ${chip_dir}/src/app/server/ + ${chip_dir}/src/controller/data_model + ${chip_dir}/third_party/nlio/repo/include/ + ${chip_dir}/third_party/nlunit-test/repo/src +) + +list( + APPEND chip_main_flags + + -DINET_CONFIG_ENABLE_IPV4=1 + -DCHIP_PROJECT=1 + -DCHIP_DEVICE_LAYER_TARGET=Ameba + -DUSE_ZAP_CONFIG + -DCHIP_HAVE_CONFIG_H + -DMBEDTLS_CONFIG_FILE= +) + +list( + APPEND chip_main_cpp_flags + + -Wno-unused-parameter + -std=gnu++11 + -std=c++14 + -fno-rtti +) +target_compile_definitions(${chip_main} PRIVATE ${chip_main_flags} ) +target_compile_options(${chip_main} PRIVATE ${chip_main_cpp_flags}) + +# move static library post build command +add_custom_command( + TARGET ${chip_main} + POST_BUILD + COMMAND cp lib${chip_main}.a ${CMAKE_CURRENT_SOURCE_DIR}/lib/application +) diff --git a/examples/lighting-app/ameba/main/CHIPDeviceManager.cpp b/examples/lighting-app/ameba/main/CHIPDeviceManager.cpp new file mode 100755 index 00000000000000..d1276d014a8e77 --- /dev/null +++ b/examples/lighting-app/ameba/main/CHIPDeviceManager.cpp @@ -0,0 +1,173 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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 + * This file implements the CHIP Device Interface that is used by + * applications to interact with the CHIP stack + * + */ + +#include + +#include "CHIPDeviceManager.h" +#include +#include +#include +#include + +#include "Globals.h" +#include "LEDWidget.h" + +#include +#include +#include +#include +#include +#include +#include + +using namespace ::chip; + +namespace chip { + +namespace DeviceManager { + +using namespace ::chip::DeviceLayer; + +void CHIPDeviceManager::CommonDeviceEventHandler(const ChipDeviceEvent * event, intptr_t arg) +{ + CHIPDeviceManagerCallbacks * cb = reinterpret_cast(arg); + if (cb != nullptr) + { + cb->DeviceEventCallback(event, reinterpret_cast(cb)); + } +} + +CHIP_ERROR CHIPDeviceManager::Init(CHIPDeviceManagerCallbacks * cb) +{ + CHIP_ERROR err; + mCB = cb; + + err = PlatformMgr().InitChipStack(); + SuccessOrExit(err); + + if (CONFIG_NETWORK_LAYER_BLE) + { + ConnectivityMgr().SetBLEAdvertisingEnabled(true); + } + + err = Platform::MemoryInit(); + SuccessOrExit(err); + + PlatformMgr().AddEventHandler(CHIPDeviceManager::CommonDeviceEventHandler, reinterpret_cast(cb)); + + // // Start a task to run the CHIP Device event loop. + err = PlatformMgr().StartEventLoopTask(); + if (err != CHIP_NO_ERROR) + { + printf("StartEventLoopTask() - ERROR!\r\n"); + } + else + { + printf("StartEventLoopTask() - OK\r\n"); + } + +exit: + return err; +} +} // namespace DeviceManager +} // namespace chip + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type, + uint16_t size, uint8_t * value) +{ + chip::DeviceManager::CHIPDeviceManagerCallbacks * cb = + chip::DeviceManager::CHIPDeviceManager::GetInstance().GetCHIPDeviceManagerCallbacks(); + + EndpointId endpointId = attributePath.mEndpointId; + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + + if (clusterId == ZCL_ON_OFF_CLUSTER_ID) + { + if (attributeId != ZCL_ON_OFF_ATTRIBUTE_ID) + { + ChipLogProgress(Zcl, "Unknown attribute ID: %" PRIx32, attributeId); + return; + } + + statusLED1.Set(*value); + } + else if (clusterId == ZCL_LEVEL_CONTROL_CLUSTER_ID) + { + if (attributeId != ZCL_CURRENT_LEVEL_ATTRIBUTE_ID) + { + ChipLogProgress(Zcl, "Unknown attribute ID: %" PRIx32, attributeId); + return; + } + if (size == 1) + { + // ChipLogProgress(Zcl, "New level: %u ", *value); + } + else + { + ChipLogError(Zcl, "wrong length for level: %d\n", size); + } + } + else if (clusterId == ZCL_COLOR_CONTROL_CLUSTER_ID) + { + uint8_t hue, saturation; + + if ((attributeId != ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID) && + (attributeId != ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID)) + { + ChipLogProgress(Zcl, "Unknown attribute ID: %" PRIx32, attributeId); + return; + } + + if (attributeId == ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID) + { + hue = *value; + emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID, + &saturation, sizeof(uint8_t)); + } + if (attributeId == ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID) + { + saturation = *value; + emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, &hue, + sizeof(uint8_t)); + } + ChipLogProgress(Zcl, "New hue: %d, New saturation: %d ", hue, saturation); + } + else if (clusterId == ZCL_IDENTIFY_CLUSTER_ID) + { + if (attributeId == ZCL_IDENTIFY_TIME_ATTRIBUTE_ID) + { + if (cb != nullptr) + { + cb->PostAttributeChangeCallback(endpointId, clusterId, attributeId, mask, type, size, value); + } + ChipLogProgress(Zcl, "ZCL_IDENTIFY_TIME_ATTRIBUTE_ID value: %u ", *value); + } + } + else + { + // ChipLogProgress(Zcl, "Unknown cluster ID: %" PRIx32, clusterId); + return; + } +} diff --git a/examples/lighting-app/ameba/main/DeviceCallbacks.cpp b/examples/lighting-app/ameba/main/DeviceCallbacks.cpp new file mode 100755 index 00000000000000..c51bfb33670e18 --- /dev/null +++ b/examples/lighting-app/ameba/main/DeviceCallbacks.cpp @@ -0,0 +1,150 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * 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 DeviceCallbacks.cpp + * + * Implements all the callbacks to the application from the CHIP Stack + * + **/ +#include "DeviceCallbacks.h" + +#include "CHIPDeviceManager.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static const char * TAG = "app-devicecallbacks"; + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::DeviceLayer; +using namespace ::chip::DeviceManager; +using namespace ::chip::Logging; + +uint32_t identifyTimerCount; +constexpr uint32_t kIdentifyTimerDelayMS = 250; + +void DeviceCallbacks::DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) +{ + switch (event->Type) + { + case DeviceEventType::kInternetConnectivityChange: + OnInternetConnectivityChange(event); + break; + + case DeviceEventType::kSessionEstablished: + OnSessionEstablished(event); + break; + case DeviceEventType::kInterfaceIpAddressChanged: + if ((event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV4_Assigned) || + (event->InterfaceIpAddressChanged.Type == InterfaceIpChangeType::kIpV6_Assigned)) + { + // MDNS server restart on any ip assignment: if link local ipv6 is configured, that + // will not trigger a 'internet connectivity change' as there is no internet + // connectivity. MDNS still wants to refresh its listening interfaces to include the + // newly selected address. + chip::app::DnssdServer::Instance().StartServer(); + } + break; + } +} + +void DeviceCallbacks::OnInternetConnectivityChange(const ChipDeviceEvent * event) +{ + if (event->InternetConnectivityChange.IPv4 == kConnectivity_Established) + { + printf("Server ready at: %s:%d", event->InternetConnectivityChange.address, CHIP_PORT); + chip::app::DnssdServer::Instance().StartServer(); + } + else if (event->InternetConnectivityChange.IPv4 == kConnectivity_Lost) + { + printf("Lost IPv4 connectivity..."); + } + if (event->InternetConnectivityChange.IPv6 == kConnectivity_Established) + { + printf("IPv6 Server ready..."); + chip::app::DnssdServer::Instance().StartServer(); + } + else if (event->InternetConnectivityChange.IPv6 == kConnectivity_Lost) + { + printf("Lost IPv6 connectivity..."); + } +} + +void DeviceCallbacks::OnSessionEstablished(const ChipDeviceEvent * event) +{ + if (event->SessionEstablished.IsCommissioner) + { + printf("Commissioner detected!"); + } +} + +void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t mask, + uint8_t type, uint16_t size, uint8_t * value) +{ + switch (clusterId) + { + case ZCL_IDENTIFY_CLUSTER_ID: + OnIdentifyPostAttributeChangeCallback(endpointId, attributeId, value); + break; + + default: + ChipLogProgress(Zcl, "Unknown cluster ID: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + break; + } +} + +void IdentifyTimerHandler(Layer * systemLayer, void * appState) +{ + // statusLED1.Animate(); + + if (identifyTimerCount) + { + systemLayer->StartTimer(Clock::Milliseconds32(kIdentifyTimerDelayMS), IdentifyTimerHandler, appState); + // Decrement the timer count. + identifyTimerCount--; + } +} + +void DeviceCallbacks::OnIdentifyPostAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value) +{ + VerifyOrExit(attributeId == ZCL_IDENTIFY_TIME_ATTRIBUTE_ID, + ChipLogError(DeviceLayer, "[%s] Unhandled Attribute ID: '0x%04x", TAG, attributeId)); + VerifyOrExit(endpointId == 1, ChipLogError(DeviceLayer, "[%s] Unexpected EndPoint ID: `0x%02x'", TAG, endpointId)); + + // timerCount represents the number of callback executions before we stop the timer. + // value is expressed in seconds and the timer is fired every 250ms, so just multiply value by 4. + // Also, we want timerCount to be odd number, so the ligth state ends in the same state it starts. + identifyTimerCount = (*value) * 4; + + DeviceLayer::SystemLayer().CancelTimer(IdentifyTimerHandler, this); + DeviceLayer::SystemLayer().StartTimer(Clock::Milliseconds32(kIdentifyTimerDelayMS), IdentifyTimerHandler, this); + +exit: + return; +} diff --git a/examples/lighting-app/ameba/main/Globals.cpp b/examples/lighting-app/ameba/main/Globals.cpp new file mode 100755 index 00000000000000..4b70be23483d25 --- /dev/null +++ b/examples/lighting-app/ameba/main/Globals.cpp @@ -0,0 +1,20 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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 "Globals.h" + +LEDWidget statusLED1; diff --git a/examples/lighting-app/ameba/main/LEDWidget.cpp b/examples/lighting-app/ameba/main/LEDWidget.cpp new file mode 100755 index 00000000000000..a050f4a4d4f0f0 --- /dev/null +++ b/examples/lighting-app/ameba/main/LEDWidget.cpp @@ -0,0 +1,60 @@ +/* + * + * Copyright (c) 2018 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 LEDWidget.cpp + * + * Implements an LED Widget controller that is usually tied to a GPIO + * It also updates the display widget if it's enabled + */ + +#include "LEDWidget.h" + +gpio_t gpio_led; + +void LEDWidget::Init(PinName gpioNum) +{ + + mGPIONum = gpioNum; + mState = false; + + if (gpioNum != (PinName) NC) + { + // Init LED control pin + gpio_init(&gpio_led, gpioNum); + gpio_dir(&gpio_led, PIN_OUTPUT); // Direction: Output + gpio_mode(&gpio_led, PullNone); // No pull + gpio_write(&gpio_led, mState); + } +} + +void LEDWidget::Set(bool state) +{ + DoSet(state); +} + +void LEDWidget::DoSet(bool state) +{ + bool stateChange = (mState != state); + mState = state; + + if (stateChange) + { + gpio_write(&gpio_led, state); + } +} diff --git a/examples/lighting-app/ameba/main/chipinterface.cpp b/examples/lighting-app/ameba/main/chipinterface.cpp new file mode 100755 index 00000000000000..9300f960b487fb --- /dev/null +++ b/examples/lighting-app/ameba/main/chipinterface.cpp @@ -0,0 +1,260 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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 + +#include "CHIPDeviceManager.h" +#include "DeviceCallbacks.h" +#include "Globals.h" +#include "LEDWidget.h" +#include "Server.h" + +#include "chip_porting.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +extern "C" { +void * __dso_handle = 0; +} + +using namespace ::chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceManager; +using namespace ::chip::DeviceLayer; + +#define QRCODE_BASE_URL "https://dhrishi.github.io/connectedhomeip/qrcode.html" +#define EXAMPLE_VENDOR_TAG_IP 1 + +#ifdef CONFIG_PLATFORM_8721D +#define STATUS_LED_GPIO_NUM PB_5 +#elif defined(CONFIG_PLATFORM_8710C) +#define STATUS_LED_GPIO_NUM PA_20 +#else +#define STATUS_LED_GPIO_NUM NC +#endif + +static DeviceCallbacks EchoCallbacks; + +void GetGatewayIP(char * ip_buf, size_t ip_len) +{ + uint8_t * gateway = LwIP_GetGW(&xnetif[0]); + sprintf(ip_buf, "%d.%d.%d.%d", gateway[0], gateway[1], gateway[2], gateway[3]); + printf("Got gateway ip: %s\r\n", ip_buf); +} + +// need to check CONFIG_RENDEZVOUS_MODE +bool isRendezvousBLE() +{ + RendezvousInformationFlags flags = RendezvousInformationFlags(CONFIG_RENDEZVOUS_MODE); + return flags.Has(RendezvousInformationFlag::kBLE); +} + +std::string createSetupPayload() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + std::string result; + + uint16_t discriminator; + err = ConfigurationMgr().GetSetupDiscriminator(discriminator); + if (err != CHIP_NO_ERROR) + { + printf("Couldn't get discriminator: %s\r\n", ErrorStr(err)); + return result; + } + printf("Setup discriminator: %u (0x%x)\r\n", discriminator, discriminator); + + uint32_t setupPINCode; + err = ConfigurationMgr().GetSetupPinCode(setupPINCode); + if (err != CHIP_NO_ERROR) + { + printf("Couldn't get setupPINCode: %s\r\n", ErrorStr(err)); + return result; + } + printf("Setup PIN code: %u (0x%x)\r\n", setupPINCode, setupPINCode); + + uint16_t vendorId; + err = ConfigurationMgr().GetVendorId(vendorId); + if (err != CHIP_NO_ERROR) + { + printf("Couldn't get vendorId: %s\r\n", ErrorStr(err)); + return result; + } + + uint16_t productId; + err = ConfigurationMgr().GetProductId(productId); + if (err != CHIP_NO_ERROR) + { + printf("Couldn't get productId: %s\r\n", ErrorStr(err)); + return result; + } + + SetupPayload payload; + payload.version = 0; + payload.discriminator = discriminator; + payload.setUpPINCode = setupPINCode; + payload.rendezvousInformation = RendezvousInformationFlags(CONFIG_RENDEZVOUS_MODE); + payload.vendorID = vendorId; + payload.productID = productId; + + if (!isRendezvousBLE()) + { + char gw_ip[INET6_ADDRSTRLEN]; + GetGatewayIP(gw_ip, sizeof(gw_ip)); + payload.addOptionalVendorData(EXAMPLE_VENDOR_TAG_IP, gw_ip); + + QRCodeSetupPayloadGenerator generator(payload); + + size_t tlvDataLen = sizeof(gw_ip); + uint8_t tlvDataStart[tlvDataLen]; + err = generator.payloadBase38Representation(result, tlvDataStart, tlvDataLen); + } + else + { + QRCodeSetupPayloadGenerator generator(payload); + err = generator.payloadBase38Representation(result); + } + + { + ManualSetupPayloadGenerator generator(payload); + std::string outCode; + + if (generator.payloadDecimalStringRepresentation(outCode) == CHIP_NO_ERROR) + { + printf("Short Manual(decimal) setup code: %s\r\n", outCode.c_str()); + } + else + { + printf("Failed to get decimal setup code\r\n"); + } + + payload.commissioningFlow = CommissioningFlow::kCustom; + generator = ManualSetupPayloadGenerator(payload); + + if (generator.payloadDecimalStringRepresentation(outCode) == CHIP_NO_ERROR) + { + // intentional extra space here to align the log with the short code + printf("Long Manual(decimal) setup code: %s\r\n", outCode.c_str()); + } + else + { + printf("Failed to get decimal setup code\r\n"); + } + } + + if (err != CHIP_NO_ERROR) + { + printf("Couldn't get payload string %\r\n" CHIP_ERROR_FORMAT, err.Format()); + } + return result; +}; + +void OnIdentifyStart(Identify *) +{ + ChipLogProgress(Zcl, "OnIdentifyStart"); +} + +void OnIdentifyStop(Identify *) +{ + ChipLogProgress(Zcl, "OnIdentifyStop"); +} + +void OnTriggerEffect(Identify * identify) +{ + switch (identify->mCurrentEffectIdentifier) + { + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BLINK"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_BREATHE"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_OKAY"); + break; + case EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE: + ChipLogProgress(Zcl, "EMBER_ZCL_IDENTIFY_EFFECT_IDENTIFIER_CHANNEL_CHANGE"); + break; + default: + ChipLogProgress(Zcl, "No identifier effect"); + return; + } +} + +static Identify gIdentify1 = { + chip::EndpointId{ 1 }, OnIdentifyStart, OnIdentifyStop, EMBER_ZCL_IDENTIFY_IDENTIFY_TYPE_VISIBLE_LED, OnTriggerEffect, +}; + +extern "C" void ChipTest(void) +{ + printf("In ChipTest()\r\n"); + CHIP_ERROR err = CHIP_NO_ERROR; + + printf("initPrefr\n"); + initPref(); + + CHIPDeviceManager & deviceMgr = CHIPDeviceManager::GetInstance(); + err = deviceMgr.Init(&EchoCallbacks); + + if (err != CHIP_NO_ERROR) + { + printf("DeviceManagerInit() - ERROR!\r\n"); + } + else + { + printf("DeviceManagerInit() - OK\r\n"); + } + + chip::Server::GetInstance().Init(); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + + std::string qrCodeText = createSetupPayload(); + + printf("QR CODE Text: '%s'\r\n", qrCodeText.c_str()); + + { + std::vector qrCode(3 * qrCodeText.size() + 1); + err = EncodeQRCodeToUrl(qrCodeText.c_str(), qrCodeText.size(), qrCode.data(), qrCode.max_size()); + if (err == CHIP_NO_ERROR) + { + printf("Copy/paste the below URL in a browser to see the QR CODE:\n\t%s?data=%s", QRCODE_BASE_URL, qrCode.data()); + } + } + printf("\n\n"); + + statusLED1.Init(STATUS_LED_GPIO_NUM); + + while (true) + vTaskDelay(pdMS_TO_TICKS(50)); +} + +bool lowPowerClusterSleep() +{ + return true; +} diff --git a/examples/lighting-app/ameba/main/include/CHIPDeviceManager.h b/examples/lighting-app/ameba/main/include/CHIPDeviceManager.h new file mode 100644 index 00000000000000..d7b7d41f6513b6 --- /dev/null +++ b/examples/lighting-app/ameba/main/include/CHIPDeviceManager.h @@ -0,0 +1,124 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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 + * This file contains definitions for the CHIP DeviceManager Interface + * + * This object will co-ordinate multiple activities such as + * initialisation, rendezvous, session mgmt and other such + * activities within the CHIP stack. This is a singleton object. + */ + +#pragma once + +#include +#include +#include + +#include + +#include +#include + +#include + +namespace chip { +namespace DeviceManager { + +/** + * @brief + * This class provides a skeleton for all the callback functions. The functions will be + * called by other objects within the CHIP stack for specific events. + * Applications interested in receiving specific callbacks can specialize this class and handle + * these events in their implementation of this class. + */ +class CHIPDeviceManagerCallbacks +{ +public: + /** + * @brief + * Called when CHIP Device events (PublicEventTypes) are triggered. + * + * @param event ChipDeviceEvent that occurred + * @param arg arguments specific to the event, if any + */ + virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg) {} + + /** + * @brief + * Called after an attribute has been changed + * + * @param endpoint endpoint id + * @param clusterID cluster id + * @param attributeId attribute id that was changed + * @param mask mask of the attribute + * @param manufacturerCode manufacturer code + * @param type attribute type + * @param size size of the attribute + * @param value pointer to the new value + */ + virtual void PostAttributeChangeCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) + {} + virtual ~CHIPDeviceManagerCallbacks() {} +}; + +/** + * @brief + * A common class that drives other components of the CHIP stack + */ +class DLL_EXPORT CHIPDeviceManager +{ +public: + CHIPDeviceManager(const CHIPDeviceManager &) = delete; + CHIPDeviceManager(const CHIPDeviceManager &&) = delete; + CHIPDeviceManager & operator=(const CHIPDeviceManager &) = delete; + + static CHIPDeviceManager & GetInstance() + { + static CHIPDeviceManager instance; + return instance; + } + + /** + * @brief + * Initialise CHIPDeviceManager + * + * @param cb Application's instance of the CHIPDeviceManagerCallbacks for consuming events + */ + CHIP_ERROR Init(CHIPDeviceManagerCallbacks * cb); + + /** + * @brief + * Fetch a pointer to the registered CHIPDeviceManagerCallbacks object. + * + */ + CHIPDeviceManagerCallbacks * GetCHIPDeviceManagerCallbacks() { return mCB; } + + /** + * Use internally for registration of the ChipDeviceEvents + */ + static void CommonDeviceEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + +private: + CHIPDeviceManagerCallbacks * mCB = nullptr; + CHIPDeviceManager() {} +}; + +} // namespace DeviceManager +} // namespace chip diff --git a/examples/lighting-app/ameba/main/include/DeviceCallbacks.h b/examples/lighting-app/ameba/main/include/DeviceCallbacks.h new file mode 100755 index 00000000000000..f7a2c0b52b1624 --- /dev/null +++ b/examples/lighting-app/ameba/main/include/DeviceCallbacks.h @@ -0,0 +1,44 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * 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 DeviceCallbacks.h + * + * Implementations for the DeviceManager callbacks for this application + * + **/ + +#pragma once + +#include "CHIPDeviceManager.h" +#include +#include +#include + +class DeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallbacks +{ +public: + virtual void DeviceEventCallback(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) override; + +private: + void OnInternetConnectivityChange(const chip::DeviceLayer::ChipDeviceEvent * event); + void OnSessionEstablished(const chip::DeviceLayer::ChipDeviceEvent * event); + void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); +}; diff --git a/examples/lighting-app/ameba/main/include/Globals.h b/examples/lighting-app/ameba/main/include/Globals.h new file mode 100755 index 00000000000000..7582904f361803 --- /dev/null +++ b/examples/lighting-app/ameba/main/include/Globals.h @@ -0,0 +1,22 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * 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. + */ + +#pragma once + +#include "LEDWidget.h" + +extern LEDWidget statusLED1; diff --git a/examples/lighting-app/ameba/main/include/LEDWidget.h b/examples/lighting-app/ameba/main/include/LEDWidget.h new file mode 100755 index 00000000000000..b075b967399d1a --- /dev/null +++ b/examples/lighting-app/ameba/main/include/LEDWidget.h @@ -0,0 +1,159 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 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. + */ + +#pragma once + +#include + +#ifdef CONFIG_PLATFORM_8710C +#include "gpio_api.h" +#include "rtl8710c_pin_name.h" + +#else + +typedef enum +{ + PORT_A = 0, + PORT_B = 1, +} GPIO_PORT; + +typedef enum +{ + PIN_INPUT = 0, + PIN_OUTPUT +} PinDirection; + +typedef enum +{ + PullNone = 0, // IN HIGHZ + PullUp = 1, + PullDown = 2, + PullDefault = PullNone +} PinMode; + +/* (((port)<<5)|(pin)) */ +typedef enum +{ + PA_0 = (PORT_A << 5 | 0), + PA_1 = (PORT_A << 5 | 1), + PA_2 = (PORT_A << 5 | 2), + PA_3 = (PORT_A << 5 | 3), + PA_4 = (PORT_A << 5 | 4), + PA_5 = (PORT_A << 5 | 5), + PA_6 = (PORT_A << 5 | 6), + PA_7 = (PORT_A << 5 | 7), + PA_8 = (PORT_A << 5 | 8), + PA_9 = (PORT_A << 5 | 9), + PA_10 = (PORT_A << 5 | 10), + PA_11 = (PORT_A << 5 | 11), + PA_12 = (PORT_A << 5 | 12), + PA_13 = (PORT_A << 5 | 13), + PA_14 = (PORT_A << 5 | 14), + PA_15 = (PORT_A << 5 | 15), + PA_16 = (PORT_A << 5 | 16), + PA_17 = (PORT_A << 5 | 17), + PA_18 = (PORT_A << 5 | 18), + PA_19 = (PORT_A << 5 | 19), + PA_20 = (PORT_A << 5 | 20), + PA_21 = (PORT_A << 5 | 21), + PA_22 = (PORT_A << 5 | 22), + PA_23 = (PORT_A << 5 | 23), + PA_24 = (PORT_A << 5 | 24), + PA_25 = (PORT_A << 5 | 25), + PA_26 = (PORT_A << 5 | 26), + PA_27 = (PORT_A << 5 | 27), + PA_28 = (PORT_A << 5 | 28), + PA_29 = (PORT_A << 5 | 29), + PA_30 = (PORT_A << 5 | 30), + PA_31 = (PORT_A << 5 | 31), + + PB_0 = (PORT_B << 5 | 0), + PB_1 = (PORT_B << 5 | 1), + PB_2 = (PORT_B << 5 | 2), + PB_3 = (PORT_B << 5 | 3), + PB_4 = (PORT_B << 5 | 4), + PB_5 = (PORT_B << 5 | 5), + PB_6 = (PORT_B << 5 | 6), + PB_7 = (PORT_B << 5 | 7), + PB_8 = (PORT_B << 5 | 8), + PB_9 = (PORT_B << 5 | 9), + PB_10 = (PORT_B << 5 | 10), + PB_11 = (PORT_B << 5 | 11), + PB_12 = (PORT_B << 5 | 12), + PB_13 = (PORT_B << 5 | 13), + PB_14 = (PORT_B << 5 | 14), + PB_15 = (PORT_B << 5 | 15), + PB_16 = (PORT_B << 5 | 16), + PB_17 = (PORT_B << 5 | 17), + PB_18 = (PORT_B << 5 | 18), + PB_19 = (PORT_B << 5 | 19), + PB_20 = (PORT_B << 5 | 20), + PB_21 = (PORT_B << 5 | 21), + PB_22 = (PORT_B << 5 | 22), + PB_23 = (PORT_B << 5 | 23), + PB_24 = (PORT_B << 5 | 24), + PB_25 = (PORT_B << 5 | 25), + PB_26 = (PORT_B << 5 | 26), + PB_27 = (PORT_B << 5 | 27), + PB_28 = (PORT_B << 5 | 28), + PB_29 = (PORT_B << 5 | 29), + PB_30 = (PORT_B << 5 | 30), + PB_31 = (PORT_B << 5 | 31), + + VBAT_MEAS = (0x7 << 5 | 2), + AD_0 = PB_4, // CH0 + AD_1 = PB_5, // CH1 + AD_2 = PB_6, // CH2 + AD_3 = PB_7, // CH3 + AD_4 = PB_1, // CH4 + AD_5 = PB_2, // CH5 + AD_6 = PB_3, // CH6 + AD_7 = VBAT_MEAS, // CH7 + + // Not connected + NC = (uint32_t) 0xFFFFFFFF +} PinName; + +typedef struct gpio_s +{ + PinName pin; +} gpio_t; + +#endif + +typedef struct gpio_s gpio_t; + +extern "C" void gpio_init(gpio_t * obj, PinName pin); +extern "C" uint32_t gpio_set(PinName pin); +extern "C" void gpio_mode(gpio_t * obj, PinMode mode); +extern "C" void gpio_dir(gpio_t * obj, PinDirection direction); +extern "C" void gpio_write(gpio_t * obj, int value); +extern "C" int gpio_read(gpio_t * obj); + +class LEDWidget +{ +public: + void Init(PinName gpioNum); + void Set(bool state); + +private: + PinName mGPIONum; + bool mState; + void DoSet(bool state); +}; diff --git a/examples/lighting-app/ameba/third_party/connectedhomeip b/examples/lighting-app/ameba/third_party/connectedhomeip new file mode 120000 index 00000000000000..11a54ed360106c --- /dev/null +++ b/examples/lighting-app/ameba/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../ \ No newline at end of file