Matter SDK Coverage Report
Current view: top level - transport/raw - PeerAddress.h (source / functions) Coverage Total Hit
Test: SHA:5853f10e345717417494f970a7d13b422d94af51 Lines: 54.2 % 83 45
Test Date: 2025-06-30 07:09:23 Functions: 57.1 % 28 16

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2020 Project CHIP Authors
       4              :  *
       5              :  *    Licensed under the Apache License, Version 2.0 (the "License");
       6              :  *    you may not use this file except in compliance with the License.
       7              :  *    You may obtain a copy of the License at
       8              :  *
       9              :  *        http://www.apache.org/licenses/LICENSE-2.0
      10              :  *
      11              :  *    Unless required by applicable law or agreed to in writing, software
      12              :  *    distributed under the License is distributed on an "AS IS" BASIS,
      13              :  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14              :  *    See the License for the specific language governing permissions and
      15              :  *    limitations under the License.
      16              :  */
      17              : 
      18              : /**
      19              :  * @brief
      20              :  *    File contains definitions on how a connection to a peer can be defined.
      21              :  *
      22              :  */
      23              : 
      24              : #pragma once
      25              : 
      26              : #include <inet/IPAddress.h>
      27              : #include <inet/InetInterface.h>
      28              : #include <lib/core/CHIPConfig.h>
      29              : #include <lib/core/DataModelTypes.h>
      30              : #include <lib/support/CHIPMemString.h>
      31              : 
      32              : namespace chip {
      33              : namespace Transport {
      34              : 
      35              : /**
      36              :  * Communication path defines how two peers communicate.
      37              :  *
      38              :  * When a peer contacts another peer, it defines how the peers communicate.
      39              :  *
      40              :  * Once communication between two peers is established, the same transport
      41              :  * path should be used: a peer contacting another peer over UDP will receive
      42              :  * messages back over UDP. A communication channel established over TCP
      43              :  * will keep the same TCP channel.
      44              :  *
      45              :  */
      46              : 
      47              : /**
      48              :  * Here we specified Type to be uint8_t, so the PeerAddress can be serialized easily.
      49              :  */
      50              : enum class Type : uint8_t
      51              : {
      52              :     kUndefined,
      53              :     kUdp,
      54              :     kBle,
      55              :     kTcp,
      56              :     kWiFiPAF,
      57              :     kNfc,
      58              :     kLast = kNfc, // This is not an actual transport type, it just refers to the last transport type
      59              : };
      60              : 
      61              : /**
      62              :  * Describes how a peer on a CHIP network can be addressed.
      63              :  */
      64              : class PeerAddress
      65              : {
      66              : public:
      67         3636 :     constexpr PeerAddress() : mTransportType(Type::kUndefined), mId{ .mRemoteId = kUndefinedNodeId } {}
      68            0 :     constexpr PeerAddress(const Inet::IPAddress & addr, Type type) :
      69            0 :         mIPAddress(addr), mTransportType(type), mId{ .mRemoteId = kUndefinedNodeId }
      70            0 :     {}
      71          112 :     constexpr PeerAddress(Type type) : mTransportType(type), mId{ .mRemoteId = kUndefinedNodeId } {}
      72            0 :     constexpr PeerAddress(Type type, NodeId remoteId) : mTransportType(type), mId{ .mRemoteId = remoteId } {}
      73              : 
      74              :     constexpr PeerAddress(PeerAddress &&)        = default;
      75            0 :     constexpr PeerAddress(const PeerAddress &)   = default;
      76         1894 :     PeerAddress & operator=(const PeerAddress &) = default;
      77           26 :     PeerAddress & operator=(PeerAddress &&)      = default;
      78              : 
      79        14925 :     const Inet::IPAddress & GetIPAddress() const { return mIPAddress; }
      80            0 :     PeerAddress & SetIPAddress(const Inet::IPAddress & addr)
      81              :     {
      82            0 :         mIPAddress = addr;
      83            0 :         return *this;
      84              :     }
      85              : 
      86            0 :     NodeId GetRemoteId() const { return mId.mRemoteId; }
      87              : 
      88              :     // NB: 0xFFFF is not allowed for NFC ShortId.
      89              :     uint16_t GetNFCShortId() const { return mId.mNFCShortId; }
      90              : 
      91         7164 :     Type GetTransportType() const { return mTransportType; }
      92            0 :     PeerAddress & SetTransportType(Type type)
      93              :     {
      94            0 :         mTransportType = type;
      95            0 :         return *this;
      96              :     }
      97              : 
      98           53 :     uint16_t GetPort() const { return mPort; }
      99            0 :     PeerAddress & SetPort(uint16_t port)
     100              :     {
     101            0 :         mPort = port;
     102            0 :         return *this;
     103              :     }
     104              : 
     105          128 :     Inet::InterfaceId GetInterface() const { return mInterface; }
     106        14950 :     PeerAddress & SetInterface(Inet::InterfaceId interface)
     107              :     {
     108        14950 :         mInterface = interface;
     109        14950 :         return *this;
     110              :     }
     111              : 
     112              :     bool IsInitialized() const { return mTransportType != Type::kUndefined; }
     113              : 
     114              :     bool IsMulticast() { return Type::kUdp == mTransportType && mIPAddress.IsIPv6Multicast(); }
     115              : 
     116              :     bool operator==(const PeerAddress & other) const;
     117        14812 :     bool operator!=(const PeerAddress & other) const { return !(*this == other); }
     118              : 
     119              :     /// Maximum size of the string outputes by ToString. Format is of the form:
     120              :     /// "UDP:<ip>:<port>"
     121              :     static constexpr size_t kMaxToStringSize = 3 // type: UDP/TCP/BLE
     122              :         + 1                                      // splitter :
     123              :         + 2                                      // brackets around address
     124              :         + Inet::IPAddress::kMaxStringLength      // address
     125              :         + 1                                      // splitter %
     126              :         + Inet::InterfaceId::kMaxIfNameLength    // interface
     127              :         + 1                                      // splitter :
     128              :         + 5                                      // port: 16 bit interger
     129              :         + 1;                                     // NullTerminator
     130              : 
     131              :     template <size_t N>
     132        15062 :     inline void ToString(char (&buf)[N]) const
     133              :     {
     134        15062 :         ToString(buf, N);
     135        15062 :     }
     136              : 
     137        15062 :     void ToString(char * buf, size_t bufSize) const
     138              :     {
     139              :         char ip_addr[Inet::IPAddress::kMaxStringLength];
     140              : 
     141        15062 :         char interface[Inet::InterfaceId::kMaxIfNameLength + 1] = {}; // +1 to prepend '%'
     142        15062 :         if (mInterface.IsPresent())
     143              :         {
     144            0 :             interface[0]   = '%';
     145            0 :             interface[1]   = 0;
     146            0 :             CHIP_ERROR err = mInterface.GetInterfaceName(interface + 1, sizeof(interface) - 1);
     147            0 :             if (err != CHIP_NO_ERROR)
     148              :             {
     149            0 :                 Platform::CopyString(interface, sizeof(interface), "%(err)");
     150              :             }
     151              :         }
     152              : 
     153        15062 :         switch (mTransportType)
     154              :         {
     155           47 :         case Type::kUndefined:
     156           47 :             snprintf(buf, bufSize, "UNDEFINED");
     157           47 :             break;
     158        14974 :         case Type::kUdp:
     159        14974 :             mIPAddress.ToString(ip_addr);
     160              : #if INET_CONFIG_ENABLE_IPV4
     161        14974 :             if (mIPAddress.IsIPv4())
     162            0 :                 snprintf(buf, bufSize, "UDP:%s%s:%d", ip_addr, interface, mPort);
     163              :             else
     164              : #endif
     165        14974 :                 snprintf(buf, bufSize, "UDP:[%s%s]:%d", ip_addr, interface, mPort);
     166        14974 :             break;
     167           41 :         case Type::kTcp:
     168           41 :             mIPAddress.ToString(ip_addr);
     169              : #if INET_CONFIG_ENABLE_IPV4
     170           41 :             if (mIPAddress.IsIPv4())
     171           15 :                 snprintf(buf, bufSize, "TCP:%s%s:%d", ip_addr, interface, mPort);
     172              :             else
     173              : #endif
     174           26 :                 snprintf(buf, bufSize, "TCP:[%s%s]:%d", ip_addr, interface, mPort);
     175           41 :             break;
     176            0 :         case Type::kWiFiPAF:
     177            0 :             snprintf(buf, bufSize, "Wi-Fi PAF");
     178            0 :             break;
     179            0 :         case Type::kBle:
     180              :             // Note that BLE does not currently use any specific address.
     181            0 :             snprintf(buf, bufSize, "BLE");
     182            0 :             break;
     183            0 :         case Type::kNfc:
     184            0 :             snprintf(buf, bufSize, "NFC:%d", mId.mNFCShortId);
     185            0 :             break;
     186            0 :         default:
     187            0 :             snprintf(buf, bufSize, "ERROR");
     188            0 :             break;
     189              :         }
     190        15062 :     }
     191              : 
     192              :     /****** Factory methods for convenience ******/
     193              : 
     194           28 :     static constexpr PeerAddress Uninitialized() { return PeerAddress(Type::kUndefined); }
     195              : 
     196            0 :     static constexpr PeerAddress BLE() { return PeerAddress(Type::kBle); }
     197              : 
     198              :     // NB: 0xFFFF is not allowed for NFC ShortId.
     199              :     static constexpr PeerAddress NFC() { return PeerAddress(kUndefinedNFCShortId()); }
     200              :     static constexpr PeerAddress NFC(const uint16_t shortId) { return PeerAddress(shortId); }
     201              : 
     202            0 :     static PeerAddress UDP(const Inet::IPAddress & addr) { return PeerAddress(addr, Type::kUdp); }
     203            0 :     static PeerAddress UDP(const Inet::IPAddress & addr, uint16_t port) { return UDP(addr).SetPort(port); }
     204              : 
     205              :     /**
     206              :      * Parses a PeerAddress from the given IP address string with UDP type. For example,
     207              :      * "192.168.1.4", "fe80::2", "fe80::1%wlan0". Notably this will also include the network scope
     208              :      * ID in either index or name form (e.g. %wlan0, %14).
     209              :      */
     210              :     static PeerAddress UDP(char * addrStr, uint16_t port) { return PeerAddress::FromString(addrStr, port, Type::kUdp); }
     211            2 :     static PeerAddress UDP(const Inet::IPAddress & addr, uint16_t port, Inet::InterfaceId interface)
     212              :     {
     213            2 :         return UDP(addr).SetPort(port).SetInterface(interface);
     214              :     }
     215            0 :     static PeerAddress TCP(const Inet::IPAddress & addr) { return PeerAddress(addr, Type::kTcp); }
     216              :     static PeerAddress TCP(const Inet::IPAddress & addr, uint16_t port) { return TCP(addr).SetPort(port); }
     217              : 
     218              :     /**
     219              :      * Parses a PeerAddress from the given IP address string with TCP type. For example,
     220              :      * "192.168.1.4", "fe80::2", "fe80::1%wlan0". Notably this will also include the network scope
     221              :      * ID in either index or name form (e.g. %wlan0, %14).
     222              :      */
     223              :     static PeerAddress TCP(char * addrStr, uint16_t port) { return PeerAddress::FromString(addrStr, port, Type::kTcp); }
     224           27 :     static PeerAddress TCP(const Inet::IPAddress & addr, uint16_t port, Inet::InterfaceId interface)
     225              :     {
     226           27 :         return TCP(addr).SetPort(port).SetInterface(interface);
     227              :     }
     228              : 
     229            0 :     static constexpr PeerAddress WiFiPAF(NodeId remoteId) { return PeerAddress(Type::kWiFiPAF, remoteId); }
     230              : 
     231            4 :     static PeerAddress Multicast(chip::FabricId fabric, chip::GroupId group)
     232              :     {
     233            4 :         constexpr uint8_t scope        = 0x05; // Site-Local
     234            4 :         constexpr uint8_t prefixLength = 0x40; // 64-bit long network prefix field
     235              :         // The network prefix portion of the Multicast Address is the 64-bit bitstring formed by concatenating:
     236              :         // * 0xFD to designate a locally assigned ULA prefix
     237              :         // * The upper 56-bits of the Fabric ID for the network in big-endian order
     238            4 :         const uint64_t prefix = 0xfd00000000000000 | ((fabric >> 8) & 0x00ffffffffffffff);
     239              :         // The 32-bit group identifier portion of the Multicast Address is the 32-bits formed by:
     240              :         // * The lower 8-bits of the Fabric ID
     241              :         // * 0x00
     242              :         // * The 16-bits Group Identifier in big-endian order
     243            4 :         uint32_t groupId = static_cast<uint32_t>((fabric << 24) & 0xff000000) | group;
     244            4 :         return UDP(Inet::IPAddress::MakeIPv6PrefixMulticast(scope, prefixLength, prefix, groupId));
     245              :     }
     246              : 
     247              : private:
     248              :     constexpr PeerAddress(uint16_t shortId) : mTransportType(Type::kNfc), mId{ .mNFCShortId = shortId } {}
     249              : 
     250              :     static PeerAddress FromString(char * addrStr, uint16_t port, Type type)
     251              :     {
     252              :         Inet::IPAddress addr;
     253              :         Inet::InterfaceId interfaceId;
     254              :         Inet::IPAddress::FromString(addrStr, addr, interfaceId);
     255              :         return PeerAddress(addr, type).SetPort(port).SetInterface(interfaceId);
     256              :     }
     257              : 
     258              :     static constexpr uint16_t kUndefinedNFCShortId() { return 0xFFFF; }
     259              : 
     260              :     Inet::IPAddress mIPAddress   = {};
     261              :     Type mTransportType          = Type::kUndefined;
     262              :     uint16_t mPort               = CHIP_PORT; ///< Relevant for UDP data sending.
     263              :     Inet::InterfaceId mInterface = Inet::InterfaceId::Null();
     264              : 
     265              :     union Id
     266              :     {
     267              :         NodeId mRemoteId;
     268              :         uint16_t mNFCShortId;
     269              :     } mId;
     270              : };
     271              : 
     272              : } // namespace Transport
     273              : } // namespace chip
        

Generated by: LCOV version 2.0-1