Skip to content

Commit 2526040

Browse files
rcasallas-silabspull[bot]
authored andcommitted
IPv6 multicast build method added to PeerAddress (#11368)
* PeerAddress: Added methods to construct the IPv6 Multicast Address. * PeerAddress: Code review comments applied.
1 parent 7c561e9 commit 2526040

File tree

3 files changed

+117
-1
lines changed

3 files changed

+117
-1
lines changed

src/transport/raw/PeerAddress.h

+18
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ class PeerAddress
101101

102102
bool IsInitialized() const { return mTransportType != Type::kUndefined; }
103103

104+
bool IsMulticast() { return Type::kUdp == mTransportType && mIPAddress.IsIPv6Multicast(); }
105+
104106
bool operator==(const PeerAddress & other) const
105107
{
106108
return (mTransportType == other.mTransportType) && (mIPAddress == other.mIPAddress) && (mPort == other.mPort) &&
@@ -201,6 +203,22 @@ class PeerAddress
201203
return TCP(addr).SetPort(port).SetInterface(interface);
202204
}
203205

206+
static PeerAddress Multicast(chip::FabricId fabric, chip::GroupId group)
207+
{
208+
constexpr uint8_t scope = 0x05; // Site-Local
209+
constexpr uint8_t prefixLength = 0x40; // 64-bit long network prefix field
210+
// The network prefix portion of the Multicast Address is the 64-bit bitstring formed by concatenating:
211+
// * 0xFD to designate a locally assigned ULA prefix
212+
// * The upper 56-bits of the Fabric ID for the network in big-endian order
213+
const uint64_t prefix = 0xfd00000000000000 | ((fabric >> 8) & 0x00ffffffffffffff);
214+
// The 32-bit group identifier portion of the Multicast Address is the 32-bits formed by:
215+
// * The lower 8-bits of the Fabric ID
216+
// * 0x00
217+
// * The 16-bits Group Identifier in big-endian order
218+
uint32_t groupId = static_cast<uint32_t>((fabric << 24) & 0xff000000) | group;
219+
return UDP(Inet::IPAddress::MakeIPv6PrefixMulticast(scope, prefixLength, prefix, groupId));
220+
}
221+
204222
private:
205223
Inet::IPAddress mIPAddress = {};
206224
Type mTransportType = Type::kUndefined;

src/transport/raw/tests/BUILD.gn

+4-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ static_library("helpers") {
3939
chip_test_suite("tests") {
4040
output_name = "libRawTransportTests"
4141

42-
test_sources = [ "TestMessageHeader.cpp" ]
42+
test_sources = [
43+
"TestMessageHeader.cpp",
44+
"TestPeerAddress.cpp",
45+
]
4346

4447
if (current_os != "mac") {
4548
test_sources += [ "TestTCP.cpp" ]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
*
3+
* Copyright (c) 2020 Project CHIP Authors
4+
* Copyright (c) 2016-2017 Nest Labs, Inc.
5+
* All rights reserved.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
20+
#ifndef __STDC_FORMAT_MACROS
21+
#define __STDC_FORMAT_MACROS
22+
#endif
23+
24+
#ifndef __STDC_LIMIT_MACROS
25+
#define __STDC_LIMIT_MACROS
26+
#endif
27+
28+
#include <inttypes.h>
29+
#include <stdint.h>
30+
#include <string.h>
31+
32+
#include <inet/IPAddress.h>
33+
#include <lib/core/DataModelTypes.h>
34+
#include <lib/core/PeerId.h>
35+
#include <lib/support/UnitTestRegistration.h>
36+
#include <transport/raw/PeerAddress.h>
37+
38+
#include <nlunit-test.h>
39+
40+
using namespace chip;
41+
42+
/**
43+
* Test correct identification of IPv6 multicast addresses.
44+
*/
45+
void TestPeerAddressMulticast(nlTestSuite * inSuite, void * inContext)
46+
{
47+
constexpr chip::FabricId fabric = 0xa1a2a4a8b1b2b4b8;
48+
constexpr chip::GroupId group = 0xe10f;
49+
chip::Transport::PeerAddress addr = chip::Transport::PeerAddress::Multicast(fabric, group);
50+
NL_TEST_ASSERT(inSuite, chip::Transport::Type::kUdp == addr.GetTransportType());
51+
NL_TEST_ASSERT(inSuite, addr.IsMulticast());
52+
53+
const Inet::IPAddress & ip = addr.GetIPAddress();
54+
NL_TEST_ASSERT(inSuite, ip.IsIPv6Multicast());
55+
NL_TEST_ASSERT(inSuite, chip::Inet::IPAddressType::kIPv6 == ip.Type());
56+
57+
constexpr uint8_t expected[NL_INET_IPV6_ADDR_LEN_IN_BYTES] = { 0xff, 0x35, 0x00, 0x40, 0xfd, 0xa1, 0xa2, 0xa4,
58+
0xa8, 0xb1, 0xb2, 0xb4, 0xb8, 0x00, 0xe1, 0x0f };
59+
uint8_t result[NL_INET_IPV6_ADDR_LEN_IN_BYTES];
60+
uint8_t * p = result;
61+
ip.WriteAddress(p);
62+
NL_TEST_ASSERT(inSuite, !memcmp(expected, result, NL_INET_IPV6_ADDR_LEN_IN_BYTES));
63+
}
64+
65+
/**
66+
* Test Suite. It lists all the test functions.
67+
*/
68+
69+
// clang-format off
70+
static const nlTest sTests[] =
71+
{
72+
NL_TEST_DEF("PeerAddress Multicast", TestPeerAddressMulticast),
73+
NL_TEST_SENTINEL()
74+
};
75+
// clang-format on
76+
77+
int TestPeerAddress(void)
78+
{
79+
// clang-format off
80+
nlTestSuite theSuite =
81+
{
82+
"PeerAddress",
83+
&sTests[0],
84+
nullptr,
85+
nullptr
86+
};
87+
// clang-format on
88+
89+
// Run test suit againt one context.
90+
nlTestRunner(&theSuite, nullptr);
91+
92+
return (nlTestRunnerStats(&theSuite));
93+
}
94+
95+
CHIP_REGISTER_TEST_SUITE(TestPeerAddress)

0 commit comments

Comments
 (0)