Skip to content

Commit

Permalink
Merge pull request #40 from project-chip/master
Browse files Browse the repository at this point in the history
update from master
  • Loading branch information
hnnajh authored Sep 7, 2021
2 parents e3cd973 + 9b976c0 commit 43fc79c
Show file tree
Hide file tree
Showing 165 changed files with 7,028 additions and 24,049 deletions.
3 changes: 2 additions & 1 deletion .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,8 @@
"BRD4164A",
"BRD4166A",
"BRD4170A",
"BRD4180A"
"BRD4186A",
"BRD4187A"
],
"default": "BRD4166A"
},
Expand Down
1 change: 1 addition & 0 deletions config/nrfconnect/app/sample-defaults.conf
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ CONFIG_STD_CPP14=y

CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=y
CONFIG_PRINTK_SYNC=y
CONFIG_ASSERT=y
CONFIG_HW_STACK_PROTECTION=y
CONFIG_SHELL=y
Expand Down
5 changes: 3 additions & 2 deletions config/telink/app/zephyr.conf
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ CONFIG_OPENTHREAD_MTD_NETDIAG=y
CONFIG_OPENTHREAD_ENABLE_SERVICE=y
CONFIG_OPENTHREAD_MANUAL_START=y
CONFIG_OPENTHREAD_THREAD_STACK_SIZE=6144
CONFIG_OPENTHREAD_MBEDTLS=y

# mbedTLS tweaks
CONFIG_MBEDTLS_DEBUG=y
Expand All @@ -91,4 +90,6 @@ CONFIG_MBEDTLS_USER_CONFIG_ENABLE=y
CONFIG_MBEDTLS_USER_CONFIG_FILE="telink-mbedtls-config.h"

# TBD: Something wrong with this heap. Need to be investigated. Cirrently just set minimal size
CONFIG_MBEDTLS_HEAP_SIZE=4
CONFIG_MBEDTLS_HEAP_SIZE=0

CONFIG_OPENTHREAD_EXTERNAL_HEAP=y
2 changes: 1 addition & 1 deletion config/telink/chip-module/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ if (CONFIG_POSIX_API)
)
endif()

zephyr_include_directories(${ZEPHYR_BASE}/../modules/crypto/mbedtls/include)
zephyr_include_directories(${ZEPHYR_BASE}/../modules/crypto/mbedtls/mbedtls/include)
zephyr_include_directories(${CHIP_ROOT}/src/platform/telink/)

zephyr_get_compile_flags(CHIP_CFLAGS_C C)
Expand Down
142 changes: 142 additions & 0 deletions docs/discussion/lwip_ipv6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# LwIP changes for Matter

LwIP is one of the network layers used in the Matter platform. Although it has
some good IPv6 support, there are areas that are lacking that we should
implement for Matter. The recommendations here are listed roughly from most to
least important.

## Route Information Options (RIO)

The specification requires devices to store route options from Route Information
Options (RIO) sent in router advertisements. This functionality is not currently
present in upstream LwIP. The patch to add this is relatively small, but we may
need to upstream this in order to require its use in Matter. Platforms would
need to incorporate this into their own middleware

### Recommendation:

- write a RIO patch, upstream to lwip
- Ensure patch is RFC compliant (especially re: expiry)

## Address Scopes

Link local addresses are less common on IPv4, which normally rely on NAT at the
router to do address translation. Matter mandates the use of IPv6 link local
addresses for communication to nodes on the same network (wifi or thread). When
there is more than one netif in the system (ex. loopback, softAP, STA), the link
local address needs more information to determine which link the address is
local to. This is normally added as the link local scope and can be seen on
addresses ex. FE80::xxxx:xxxx:xxxx:xxxx%<scope>, where the <scope> identifies
the netif (something like %wlan0 or %eno1 etc.).

Without this indicator, the link local address can only be resolved if there is
one netif. LwIP will also allow a direct address match to the netif source
address, but this does not scale well at all and is VERY racy. LwIP also
supports output to a specific netif, but this is not brought up to the socket
layer.

Upstream LwIP has support for IPv6 address scopes, but only as an option.
However, the code to support this is not present in the CHIP LwIP codebase.
Other platform versions assume this option is not present (ex. M5 has an
assertion on ip address sizes that disallow the use of a scope tag).

### Recommendation:

- Ensure Matter SDK code works with scopes on our various platforms OR
alternate: bring netif sendto up through the api / sockets layers
- Audit Matter code to ensure LL addresses are properly scoped to their netif
in all areas (DNS returned addresses especially)

## Duplicate address detection

The DAD in LwIP is actually implemented correctly right now, but there are
routers that incorrectly implement multicast for IPv6 and send packets back to
the sender. This triggers the LwIP DAD because it doesn’t check the source. This
can be fixed in the wifi layer as a filter, but it’s easy enough to add the fix
into the LwIP layer. This would help implementers so they don’t all have to
debug the same issues. Recommendation:

- Create an LwIP patch to check NS/NA packets for source and discard if they
originate from the same device. Upstream and offer patch to vendors.

## Timers, including TCP

lwIP uses on-demand timers for IGMP and MLD (see
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#esp-lwip-custom-modifications
for changes Espressif made to lwIP to help power usage on ESP32 and better
support IPv6), and also has several uncorrelated always-on timers for TCP. These
timers have caused power issues on some products.

### Recommendation:

- Make sure to take-in Espressif improvements to timers (not sure they are
upstreamed)
- Look into supporting aligned TCP timers to aggregate multiple timers within
a single wake

## pbuf management

Pool-based management has been a source of problems on several products, but
does have advantages over purely “heap” based allocation of pbufs as done in
ESP32 and many common lwIP stacks.

Overall, having the ability to instrument all PBUF allocations for usage (e.g.
Driver TX, Driver RX, Manual PacketBuffer allocation, internal TCP stack pbufs,
etc) would allow us to move towards a pool approach by allowing us to track the
following: Understanding of the overall memory usage of lwIP packet buffers over
time, helping debug issues related to out-of-pbuf or overly-long queuing. Keep
track of incoming packets dwelling and outgoing packets dwelling to start
dropping at ingress when running out of memory Overall, allow sizing of heap and
pools based on usage patterns.

### Recommendation:

- Upstream a portable version of pbuf alloc/free accounting, allowing
registration of instrumentation handlers.
- Add support to account for high watermark of pbuf memory used and concurrent
pbuf allocations.
- Add more pbuf allocation types to allow finer-grained recording of “reason”
for a pbuf alloc

## IPv6 Ping

Although ping is not required for Matter, it is very helpful for debugging
networking issues. Having a reliable ping would be beneficial for a lot of
developers.

LwIP will automatically respond to pings, but has no built-in way to send them.
The current ping implementation is a contrib app that only works for IPv4.
Extending the app is challenging for two reasons: 1) IPv6 checksum needs access
to the pbuf for calculation, which the app doesn’t have and 2) IPv6 has a lot
more ICMP traffic for SLAAC that the app would have to be updated to disregard.
Instead, it might be better to build this into the ICMP layer itself.

### Recommendation:

- Add an ASYNC send_icmp6_ping function and add a hook to check ping
responses. Upstream patch if possible. OR write an external ICMP6 ping util

## DNS

LwIP’s DNS handling isn’t great and breaks down when the router supports
IPv4/IPv6. There is a single list of DNS servers, DHCP, SLAAC and DHCPv6 all
update the list without locks. Basically, whatever wrote to the list last gets
to set the list. Although there is handling for IP type (requesting A or AAAA
records), there isn’t handling to specify an IPv6 or IPv4 server specifically,
which can be challenging since not all servers serve all record types.

The design of the weave connectivity manager moves the DNS selection to the
upper layers by stopping lwip from directly changing the DNS list and hooking to
the DNS selection. This means the DNS selection policy isn’t hard-coded into the
lwip layer. This seems like a good model for CHIP going forward.

Additionally, we should ensure that CHIP uses non-blocking DNS APIs.

### Recommendation:

- bug fix for DHCPv6 to avoid it setting bad addresses.
- note - fixed in
https://git.savannah.nongnu.org/cgit/lwip.git/commit/?id=941300c21c45a4dbf1c074b29a9ca3c88c9f6553,
but not yet released as a part of an official release.
- Create a patch to add hooks to the SetDns and GetDns functions so logic for
selecting the DNS server can be moved into the manager layer
11 changes: 11 additions & 0 deletions examples/chip-tool/commands/tests/TestCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,14 @@ void TestCommand::OnDeviceConnectionFailureFn(void * context, NodeId deviceId, C
VerifyOrReturn(command != nullptr, ChipLogError(chipTool, "Test command context is null"));
command->SetCommandExitStatus(error);
}

void TestCommand::OnWaitForMsFn(chip::System::Layer * systemLayer, void * context)
{
auto * command = static_cast<TestCommand *>(context);
command->NextTest();
}

CHIP_ERROR TestCommand::WaitForMs(uint32_t ms)
{
return chip::DeviceLayer::SystemLayer.StartTimer(ms, OnWaitForMsFn, this);
}
4 changes: 4 additions & 0 deletions examples/chip-tool/commands/tests/TestCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,15 @@ class TestCommand : public Command

virtual void NextTest() = 0;

/////////// GlobalCommands Interface /////////
CHIP_ERROR WaitForMs(uint32_t ms);

protected:
ChipDevice * mDevice;

static void OnDeviceConnectedFn(void * context, chip::Controller::Device * device);
static void OnDeviceConnectionFailureFn(void * context, NodeId deviceId, CHIP_ERROR error);
static void OnWaitForMsFn(chip::System::Layer * systemLayer, void * context);

chip::Callback::Callback<chip::Controller::OnDeviceConnected> mOnDeviceConnectedCallback;
chip::Callback::Callback<chip::Controller::OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
Expand Down
9 changes: 9 additions & 0 deletions examples/chip-tool/templates/partials/test_cluster.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ class {{filename}}: public TestCommand
//

{{#chip_tests_items}}
{{#if (isTestOnlyCluster cluster)}}
CHIP_ERROR TestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}()
{
ChipLogProgress(chipTool, "{{cluster}} - {{label}}");

return {{command}}({{#chip_tests_item_parameters}}{{#not_first}}, {{/not_first}}{{definedValue}}{{/chip_tests_item_parameters}});
}
{{else}}
// Test {{label}}
using SuccessCallback_{{index}} = void (*)(void * context{{#chip_tests_item_response_parameters}}, {{#if isList}}uint16_t count, {{/if}}{{chipType}} {{#if isList}}* {{/if}}{{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}});
chip::Callback::Callback<SuccessCallback_{{index}}> mOnSuccessCallback_{{index}} { OnTestSendCluster{{asUpperCamelCase cluster}}Command{{asUpperCamelCase command}}_{{index}}_SuccessResponse, this };
Expand Down Expand Up @@ -195,6 +203,7 @@ class {{filename}}: public TestCommand
runner->NextTest();
}

{{/if}}
{{/chip_tests_items}}
};

Expand Down
2 changes: 1 addition & 1 deletion examples/chip-tool/templates/tests-commands.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@

#include <commands/tests/TestCommand.h>

{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}}
{{>test_cluster tests="TV_TargetNavigatorCluster, TV_AudioOutputCluster, TV_ApplicationLauncherCluster, TV_KeypadInputCluster, TV_AccountLoginCluster, TV_WakeOnLanCluster, TV_ApplicationBasicCluster, TV_MediaPlaybackCluster, TV_TvChannelCluster, TV_LowPowerCluster, TV_MediaInputCluster, TestCluster, TestDelayCommands, Test_TC_OO_1_1, Test_TC_OO_2_1, Test_TC_OO_2_2, Test_TC_DM_1_1, Test_TC_DM_3_1, Test_TC_CC_3_4, Test_TC_CC_5, Test_TC_CC_6, Test_TC_CC_7, Test_TC_CC_8, Test_TC_WNCV_1_1, Test_TC_WNCV_2_1, Test_TC_BI_1_1, Test_TC_FLW_1_1, Test_TC_TM_1_1, Test_TC_OCC_1_1, OperationalCredentialsCluster"}}
10 changes: 3 additions & 7 deletions examples/lighting-app/efr32/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ declare_args() {

# PIN code for PASE session establishment.
setupPinCode = 73141520
setupDiscriminator = 3840

# Monitor & log memory usage at runtime.
enable_heap_monitoring = false
Expand All @@ -61,12 +62,12 @@ efr32_sdk("sdk") {
"${chip_root}/src/platform/EFR32",
"${efr32_project_dir}/include",
"${examples_plat_dir}",
"${examples_plat_dir}/${efr32_family}/${efr32_board}",
]

defines = [
"BOARD_ID=${efr32_board}",
"CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}",
"CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setupDiscriminator}",
]

if (chip_enable_pw_rpc) {
Expand All @@ -86,7 +87,6 @@ efr32_executable("lighting_app") {
"${examples_plat_dir}/init_efrPlatform.cpp",
"${examples_plat_dir}/uart.c",
"src/AppTask.cpp",
"src/ButtonHandler.cpp",
"src/LightingManager.cpp",
"src/ZclCallbacks.cpp",
"src/main.cpp",
Expand Down Expand Up @@ -149,11 +149,7 @@ efr32_executable("lighting_app") {
defines += [ "HEAP_MONITORING" ]
}

if (efr32_family == "efr32mg12") {
ldscript = "${examples_plat_dir}/ldscripts/efr32-MG12P.ld"
} else if (efr32_family == "efr32mg21") {
ldscript = "${examples_plat_dir}/ldscripts/efr32-MG21.ld"
}
ldscript = "${examples_plat_dir}/ldscripts/${efr32_family}.ld"

inputs = [ ldscript ]

Expand Down
67 changes: 29 additions & 38 deletions examples/lighting-app/efr32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,15 @@ Silicon Labs platform.
915MHz@19dBm
- BRD4304A / SLWSTK6000B / MGM12P Module / 2.4GHz@19dBm

MG21 boards:
MG21 boards: Currently not supported due to RAM limitation.

- BRD4180A / SLWSTK6006A / Wireless Starter Kit / 2.4GHz@20dBm

MG24 boards :

- BRD4186A / SLWSTK6006A / Wireless Starter Kit / 2.4GHz@10dBm
- BRD4187A / SLWSTK6006A / Wireless Starter Kit / 2.4GHz@20dBm

* Build the example application:

cd ~/connectedhomeip
Expand Down Expand Up @@ -171,10 +176,11 @@ combination with JLinkRTTClient as follows:
## Running the Complete Example

- It is assumed here that you already have an OpenThread border router
configured and running. If not, see the following guide
[OpenThread Border Router](https://openthread.io/guides/border-router) for
more information on how to setup a border router. Take note that the RCP
code is available directly through
configured and running. If not see the following guide
[Openthread_border_router](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/openthread_border_router_pi.md)
for more information on how to setup a border router on a raspberryPi.

Take note that the RCP code is available directly through
[Simplicity Studio 5](https://www.silabs.com/products/development-tools/software/simplicity-studio/simplicity-studio-5)
under File->New->Project Wizard->Examples->Thread : ot-rcp

Expand Down Expand Up @@ -224,43 +230,28 @@ combination with JLinkRTTClient as follows:

**Push Button 1** Toggles the light state On/Off

- Once the device is provisioned, it will join the Thread network is
established, look for the RTT log
* You can provision and control the Chip device using the python controller,
Chip tool standalone, Android or iOS app

[Python Controller](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md)

Here is an example with the Python controller:

```
    [DL] Device Role: CHILD
    [DL] Partition Id:0x6A7491B7
    [DL] \_OnPlatformEvent default: event->Type = 32778
    [DL] OpenThread State Changed (Flags: 0x00000001)
    [DL] Thread Unicast Addresses:
    [DL]    2001:DB8::E1A2:87F1:7D5D:FECA/64 valid preferred
    [DL]    FDDE:AD00:BEEF::FF:FE00:2402/64 valid preferred rloc
    [DL]    FDDE:AD00:BEEF:0:383F:5E81:A05A:B168/64 valid preferred
    [DL]    FE80::D8F2:592E:C109:CF00/64 valid preferred
    [DL] LwIP Thread interface addresses updated
    [DL] FE80::D8F2:592E:C109:CF00 IPv6 link-local address, preferred)
    [DL] FDDE:AD00:BEEF:0:383F:5E81:A05A:B168 Thread mesh-local address, preferred)
    [DL] 2001:DB8::E1A2:87F1:7D5D:FECA IPv6 global unicast address, preferred)
```
chip-device-ctrl
Keep The global unicast address; It is to be used to reach the Device with
the chip-tool. The device will be promoted to Router shortly after [DL]
Device Role: ROUTER
connect -ble 3840 73141520 1234
(you can verify that the device is on the thread network with the command
`router table` using a serial terminal (screen / minicom etc.) on the board
running the lighting-app example. You can also get the address list with the
command ipaddr again in the serial terminal )
zcl NetworkCommissioning AddThreadNetwork 1234 0 0 operationalDataset=hex:0e080000000000000000000300000b35060004001fffe00208dead00beef00cafe0708fddead00beef000005108e11d8ea8ffaa875713699f59e8807e0030a4f70656e5468726561640102c2980410edc641eb63b100b87e90a9980959befc0c0402a0fff8 breadcrumb=0 timeoutMs=1000
- Using chip-tool you can now control the light status with on/off command
such as `chip-tool onoff on 1`
zcl NetworkCommissioning EnableNetwork 1234 0 0 networkID=hex:dead00beef00cafe breadcrumb=0 timeoutMs=1000
\*\* Currently, chip-tool for Mac or Linux do not yet have the Thread
provisioning feature
`chip-tool bypass <Global ipv6 address of the node> 5540`
close-ble
You can provision the Chip device using Chip tool Android or iOS app or
through CLI commands on your OT BR
resolve 0 1234
zcl OnOff Toggle 1234 1 0
```
### Notes
Expand Down Expand Up @@ -304,9 +295,9 @@ via 2002::2
While most of the RAM usage in CHIP is static, allowing easier debugging and
optimization with symbols analysis, we still need some HEAP for the crypto and
OpenThread. Size of the HEAP can be modified by changing the value of the
`SL_STACK_SIZE` define inside of the BUILD.gn file of this example. Please take
note that a HEAP size smaller than 5k can and will cause a Mbedtls failure
during the BLE rendez-vous.
`configTOTAL_HEAP_SIZE` define inside of the FreeRTOSConfig.h file of this
example. Please take note that a HEAP size smaller than 13k can and will cause a
Mbedtls failure during the BLE rendez-vous or CASE session
To track memory usage you can set `enable_heap_monitoring = true` either in the
BUILD.gn file or pass it as a build argument to gn. This will print on the RTT
Expand Down
Loading

0 comments on commit 43fc79c

Please sign in to comment.