Skip to content

SiliconLabs/openweave-mfgn-examples

 
 

Repository files navigation

OpenWeave MFGN Examples

Example applications for MFGN partners showing the use of OpenWeave for a variety of device types and hardware platforms.

OpenWeave is the open source release of Nest's Weave technology, an application layer framework that provides a secure, reliable communications backbone for Nest's products.


Introduction

The OpenWeave example applications repo currently features two device types (lock and open/close sensor) on two hardware platforms (Nordic nRF52840 (nrf5) and Silicon Labs EFR32 MG12/MG21 (efr32)).

The example applications provide working demonstrations of connected devices built using OpenWeave, OpenThread, and the SDKs of various hardware platforms. They are intended to serve both as a means to explore the workings of OpenWeave and OpenThread, as well as a template for creating real products. It is important to note that these example applications are not "production-ready", but efforts are made in the code to bring attention to areas that developers must pay attention to for production readiness of their firmware.

The example applications build upon the OpenWeave and OpenThread projects, which are incorporated as submodules and built from source. A top-level Makefile orchestrates the entire build process, including building OpenWeave, OpenThread and files from the SDK of the selected hardware platform. The resultant image file can be flashed directly onto the development kit of the hardware platform.

Software architecture

Examples Architecture

[FIXME: Get a diagram that is application-agnostic]

The examples are built on the Weave application layer framework provided by openweave-core. At the heart of this are the Weave Core components. These components provide the essential functionality required to speak Weave. This includes code for encoding and decoding Weave messages, communicating Weave messages over various transports (TCP, UDP, BLE), tracking Weave conversations (exchanges) and negotiating secure communications.

The Weave Profiles sit atop the core components and provide support for specific types of Weave interactions. Central among these is the Weave Data Management profile (WDM), which provides a generalized protocol for communicating state, configuration settings, commands and events between Weave nodes. Other profiles support device provisioning (pairing), OTA software update, time synchronization, and device identification and control.

The Weave Device Layer serves to adapt the portable Weave Core and Profile components to run in the context of a particular device platform. For the current examples, device platforms supported are Nordic's nRF52840 and Silicon Labs EFR32 MG12/MG21. Additionally, the Device Layer also provides platform-neutral services (APIs) to the application for performing certain fundamental operations that are common to all Weave devices. These include managing a device's persistent configuration, managing its network connectivity, scheduling and orchestrating OTA software updates and others.

The examples make use of various components provided by the hardware platform SDKs, including BLE support libraries, persistent storage management, crypto services, logging and others. The platform's adaptation of FreeRTOS is used to support multi-threading and task synchronization.

OpenThread provides the core Thread stack implementation and manages persistent storage of Thread network configuration. The LwIP Lightweight IP stack provides IP services on top of Thread, including TCP, UDP and ICMPv6.

Directory structure

src/

All source code is contained in the src/ directory.

Each example application (device-type) has its own directory within the examples/ directory. It contains application-specific code with the following organization:

   src/examples/
       [app-1]/
           include/
           platforms/
               [platform-1]/
                 ldscripts/
               [platform-2]/
               ...
           schema/
           traits/
           DeviceController.cpp
           main.cpp
           README.md
           WDMFeature.cpp
           ...
       [app-2]
           ...

Directory common/ contains all code that can be shared among applications.

   src/common/
       include/
       platforms/
           [platform-1]/
               include/
               HardwarePlatform.cpp
               README.md
               ...
           [platform-2]/
               ...
           ...
       AltPrintf.c
       AppSoftwareUpdateManager.cpp
       AppTask.cpp
       Button.cpp
       ConnectivityState.cpp
       CXXExceptionStubs.cpp
       FreeRTOSNewlibLockSupport.c
       LED.cpp
       ...
third_party/

Third-party dependencies are incorporated as submodules and built from source.

    third_party/
        openthread/
        openweave-core/
        printf/

Application components

Here is a high level overview of the processing flow for the example applications.

Application Flow

Core classes

src/examples/[device-type]/main.cpp

main.cpp performs all the initializations for the application:

  1. Delegates to HardwarePlatform for all platform-specific initializations
  2. Performs initializations that are platform-independent
  3. Calls DeviceController for all application-specific initializations.

It then calls AppTask to setup and start the FreeRTOS application task. And finally, it starts the FreeRTOS scheduler.

src/common/include/HardwarePlatform.h
src/common/platforms/[platform]/HardwarePlatform.cpp

HardwarePlatform.h defines the interface that encapsulates all platform-specific behavior. Its platform-specific implementation initializes all the LEDs and Buttons exposed by the development kit, and handles the proper dispatching of all button events triggered on that devkit.

src/common/include/AppTask.h
src/common/AppTask.cpp

AppTask sets up and starts the FreeRTOS task that runs the application's code. AppTask is initialized with a pointer to a function in the DeviceController that is called at each cycle of its event loop.

src/examples/[device-type]/include/DeviceController.h
src/examples/[device-type]/DeviceController.cpp

DeviceController is the object that controls the overall behavior of the device. The application task collaborates with the DeviceController by calling method EventLoopCycle() on every cycle of its event loop. This allows the DeviceController to do periodic tasks such as animating the LEDS, updating the state of a button long press, etc.

src/examples/[device-type]/include/WDMFeature.h
src/examples/[device-type]/WDMFeature.cpp

WDMFeature encapsulates everything that is related to Weave Data Model (WDM). [FIXME: Will need help from Jay here. I think we need a document just to cover what happens in that class.]

Support classes with platform dependencies

src/common/include/LED.h
src/common/include/PlatformLED.h
src/common/LED.cpp
src/common/platforms/[platform]/[platform]LED.cpp

The LED class encapsulates the generic behavior of a LED. Note that all LED objects are initialized in a platform-specific way in HardwarePlatform, and are accessible via method GetLEDs(). Platform-specific LED behavior is defined in interface PlatformLED. Each platform implements a subclass of PlatformLED (e.g. Nrf5LED). LED is initialized with an instance of PlatformLED to which it delegates all processing that is platform-specific.

[FIXME: I should be able to get rid of PlatformLED by simply having virtual functions in LED.h. However, previous attempt broke things (could not pair). Anyway, file an issue to fix that once everything is stable.]

src/common/include/Button.h
src/common/Button.cpp

The Button class encapsulates the generic behavior of a Button. All Button objects are initialized in a platform-specific way in HardwarePlatform, and are accessible via method GetButtons(). HardwarePlatform handles the proper dispatching of all button events triggered on the platform devkit, which is eventually handled by the event handler associated with the Button.

Support classes without platform dependencies

src/common/include/ConnectivityState.h
src/common/ConnectivityState.cpp

ConnectivityState monitors the provisioning/connectivity state of the device. It is initialized with a specific LED, and is called at every event loop cycle by the DeviceController to check on the current connectivity state. If the state changes, then it updates accordingly the lighting pattern of its associated LED.

src/common/include/AppSoftwareUpdateManager.h
src/common/AppSoftwareUpdateManager.cpp

The AppSoftwareUpdateManager class encapsulates behavior associated with Software Updates. Note that software updates are currently only partially supported.

WDM schema

src/examples/[device-type]/schema

The schema directory contains all the helper files for the traits defined in the device's resource definition. These helper files are generated via WDLC. Note that they are currently provided and not generated.

[FIXME: Need to prune our example applications so they only use publicly available traits, allowing us to: 1) include the resource definition in the source code, 2) generate the schema files via WDLC.]

Device traits: sinks and sources

src/examples/[device-type]/traits

The traits directory hosts all the "source" and "sink" classes for the device traits.

[FIXME: See FIXME for WDMFeature. This doc on WDM should include information about sinks and sources as well.]

NOTE: The DeviceController is the source of truth for the state of the device. It relays any state change to the appropriate TraitDataSource instance which is accessible via WDMFeature.get[trait]. Since the service proxies the device state, the service requests the information and eventually is synchronized with the device.

[FIXME: verify that and document that in the source code.]

Configuration

src/common/include/OpenThreadConfig.h

Overrides to default OpenThread configuration.

[FIXME: Split into common and app-specific.]

src/common/include/WeaveProjectConfig.h

Overrides the default OpenWeave configuration.

[FIXME: Split into common and app-specific.]

src/common/platforms/[platform]/include/[filename].h

Overrides the default platform configuration.

For nrf5: src/common/platforms/nrf5/include/app_config.h

For efr32: src/common/platforms/efr32/include/app_config.h

src/examples/[device-type]/platforms/[platform]/ldscripts/[filename].ld

[FIXME: Provide links to docs that describe the content of that file]

Hardware platforms documentation

Applications documentation

About

Example applications showing use of OpenWeave for MFGN Partners

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 78.1%
  • C 15.6%
  • Makefile 5.8%
  • Shell 0.5%