Matter SDK Coverage Report
Current view: top level - transport/raw - PeerAddress.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 61.5 % 78 48
Test Date: 2025-01-17 19:00:11 Functions: 65.4 % 26 17

            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              :     kLast = kWiFiPAF, // This is not an actual transport type, it just refers to the last transport type
      58              : };
      59              : 
      60              : /**
      61              :  * Describes how a peer on a CHIP network can be addressed.
      62              :  */
      63              : class PeerAddress
      64              : {
      65              : public:
      66          149 :     PeerAddress() : mIPAddress(Inet::IPAddress::Any), mTransportType(Type::kUndefined) {}
      67            4 :     PeerAddress(const Inet::IPAddress & addr, Type type) : mIPAddress(addr), mTransportType(type) {}
      68            0 :     PeerAddress(Type type) : mTransportType(type) {}
      69              :     PeerAddress(Type type, NodeId remoteId) : mTransportType(type), mRemoteId(remoteId) {}
      70              : 
      71              :     PeerAddress(PeerAddress &&)                  = default;
      72            0 :     PeerAddress(const PeerAddress &)             = default;
      73         1792 :     PeerAddress & operator=(const PeerAddress &) = default;
      74           22 :     PeerAddress & operator=(PeerAddress &&)      = default;
      75              : 
      76         9736 :     const Inet::IPAddress & GetIPAddress() const { return mIPAddress; }
      77            0 :     PeerAddress & SetIPAddress(const Inet::IPAddress & addr)
      78              :     {
      79            0 :         mIPAddress = addr;
      80            0 :         return *this;
      81              :     }
      82              : 
      83              :     NodeId GetRemoteId() const { return mRemoteId; }
      84              : 
      85         6974 :     Type GetTransportType() const { return mTransportType; }
      86            0 :     PeerAddress & SetTransportType(Type type)
      87              :     {
      88            0 :         mTransportType = type;
      89            0 :         return *this;
      90              :     }
      91              : 
      92           51 :     uint16_t GetPort() const { return mPort; }
      93            0 :     PeerAddress & SetPort(uint16_t port)
      94              :     {
      95            0 :         mPort = port;
      96            0 :         return *this;
      97              :     }
      98              : 
      99          111 :     Inet::InterfaceId GetInterface() const { return mInterface; }
     100         9758 :     PeerAddress & SetInterface(Inet::InterfaceId interface)
     101              :     {
     102         9758 :         mInterface = interface;
     103         9758 :         return *this;
     104              :     }
     105              : 
     106              :     bool IsInitialized() const { return mTransportType != Type::kUndefined; }
     107              : 
     108              :     bool IsMulticast() { return Type::kUdp == mTransportType && mIPAddress.IsIPv6Multicast(); }
     109              : 
     110         8004 :     bool operator==(const PeerAddress & other) const
     111              :     {
     112        16003 :         return (mTransportType == other.mTransportType) && (mIPAddress == other.mIPAddress) && (mPort == other.mPort) &&
     113        16003 :             (mInterface == other.mInterface);
     114              :     }
     115              : 
     116         9634 :     bool operator!=(const PeerAddress & other) const { return !(*this == other); }
     117              : 
     118              :     /// Maximum size of the string outputes by ToString. Format is of the form:
     119              :     /// "UDP:<ip>:<port>"
     120              :     static constexpr size_t kMaxToStringSize = 3 // type: UDP/TCP/BLE
     121              :         + 1                                      // splitter :
     122              :         + 2                                      // brackets around address
     123              :         + Inet::IPAddress::kMaxStringLength      // address
     124              :         + 1                                      // splitter %
     125              :         + Inet::InterfaceId::kMaxIfNameLength    // interface
     126              :         + 1                                      // splitter :
     127              :         + 5                                      // port: 16 bit interger
     128              :         + 1;                                     // NullTerminator
     129              : 
     130              :     template <size_t N>
     131         9894 :     inline void ToString(char (&buf)[N]) const
     132              :     {
     133         9894 :         ToString(buf, N);
     134         9894 :     }
     135              : 
     136         9894 :     void ToString(char * buf, size_t bufSize) const
     137              :     {
     138              :         char ip_addr[Inet::IPAddress::kMaxStringLength];
     139              : 
     140         9894 :         char interface[Inet::InterfaceId::kMaxIfNameLength + 1] = {}; // +1 to prepend '%'
     141         9894 :         if (mInterface.IsPresent())
     142              :         {
     143            0 :             interface[0]   = '%';
     144            0 :             interface[1]   = 0;
     145            0 :             CHIP_ERROR err = mInterface.GetInterfaceName(interface + 1, sizeof(interface) - 1);
     146            0 :             if (err != CHIP_NO_ERROR)
     147              :             {
     148            0 :                 Platform::CopyString(interface, sizeof(interface), "%(err)");
     149              :             }
     150              :         }
     151              : 
     152         9894 :         switch (mTransportType)
     153              :         {
     154           47 :         case Type::kUndefined:
     155           47 :             snprintf(buf, bufSize, "UNDEFINED");
     156           47 :             break;
     157         9810 :         case Type::kUdp:
     158         9810 :             mIPAddress.ToString(ip_addr);
     159              : #if INET_CONFIG_ENABLE_IPV4
     160         9810 :             if (mIPAddress.IsIPv4())
     161            0 :                 snprintf(buf, bufSize, "UDP:%s%s:%d", ip_addr, interface, mPort);
     162              :             else
     163              : #endif
     164         9810 :                 snprintf(buf, bufSize, "UDP:[%s%s]:%d", ip_addr, interface, mPort);
     165         9810 :             break;
     166           37 :         case Type::kTcp:
     167           37 :             mIPAddress.ToString(ip_addr);
     168              : #if INET_CONFIG_ENABLE_IPV4
     169           37 :             if (mIPAddress.IsIPv4())
     170           15 :                 snprintf(buf, bufSize, "TCP:%s%s:%d", ip_addr, interface, mPort);
     171              :             else
     172              : #endif
     173           22 :                 snprintf(buf, bufSize, "TCP:[%s%s]:%d", ip_addr, interface, mPort);
     174           37 :             break;
     175            0 :         case Type::kWiFiPAF:
     176            0 :             snprintf(buf, bufSize, "Wi-Fi PAF");
     177            0 :             break;
     178            0 :         case Type::kBle:
     179              :             // Note that BLE does not currently use any specific address.
     180            0 :             snprintf(buf, bufSize, "BLE");
     181            0 :             break;
     182            0 :         default:
     183            0 :             snprintf(buf, bufSize, "ERROR");
     184            0 :             break;
     185              :         }
     186         9894 :     }
     187              : 
     188              :     /****** Factory methods for convenience ******/
     189              : 
     190            4 :     static PeerAddress Uninitialized() { return PeerAddress(Inet::IPAddress::Any, Type::kUndefined); }
     191              : 
     192            0 :     static PeerAddress BLE() { return PeerAddress(Type::kBle); }
     193            0 :     static PeerAddress UDP(const Inet::IPAddress & addr) { return PeerAddress(addr, Type::kUdp); }
     194            0 :     static PeerAddress UDP(const Inet::IPAddress & addr, uint16_t port) { return UDP(addr).SetPort(port); }
     195              : 
     196              :     /**
     197              :      * Parses a PeerAddress from the given IP address string with UDP type. For example,
     198              :      * "192.168.1.4", "fe80::2", "fe80::1%wlan0". Notably this will also include the network scope
     199              :      * ID in either index or name form (e.g. %wlan0, %14).
     200              :      */
     201              :     static PeerAddress UDP(char * addrStr, uint16_t port) { return PeerAddress::FromString(addrStr, port, Type::kUdp); }
     202            2 :     static PeerAddress UDP(const Inet::IPAddress & addr, uint16_t port, Inet::InterfaceId interface)
     203              :     {
     204            2 :         return UDP(addr).SetPort(port).SetInterface(interface);
     205              :     }
     206            0 :     static PeerAddress TCP(const Inet::IPAddress & addr) { return PeerAddress(addr, Type::kTcp); }
     207              :     static PeerAddress TCP(const Inet::IPAddress & addr, uint16_t port) { return TCP(addr).SetPort(port); }
     208              : 
     209              :     /**
     210              :      * Parses a PeerAddress from the given IP address string with TCP type. For example,
     211              :      * "192.168.1.4", "fe80::2", "fe80::1%wlan0". Notably this will also include the network scope
     212              :      * ID in either index or name form (e.g. %wlan0, %14).
     213              :      */
     214              :     static PeerAddress TCP(char * addrStr, uint16_t port) { return PeerAddress::FromString(addrStr, port, Type::kTcp); }
     215           25 :     static PeerAddress TCP(const Inet::IPAddress & addr, uint16_t port, Inet::InterfaceId interface)
     216              :     {
     217           25 :         return TCP(addr).SetPort(port).SetInterface(interface);
     218              :     }
     219              : 
     220              :     static PeerAddress WiFiPAF(NodeId remoteId) { return PeerAddress(Type::kWiFiPAF); }
     221              : 
     222            2 :     static PeerAddress Multicast(chip::FabricId fabric, chip::GroupId group)
     223              :     {
     224            2 :         constexpr uint8_t scope        = 0x05; // Site-Local
     225            2 :         constexpr uint8_t prefixLength = 0x40; // 64-bit long network prefix field
     226              :         // The network prefix portion of the Multicast Address is the 64-bit bitstring formed by concatenating:
     227              :         // * 0xFD to designate a locally assigned ULA prefix
     228              :         // * The upper 56-bits of the Fabric ID for the network in big-endian order
     229            2 :         const uint64_t prefix = 0xfd00000000000000 | ((fabric >> 8) & 0x00ffffffffffffff);
     230              :         // The 32-bit group identifier portion of the Multicast Address is the 32-bits formed by:
     231              :         // * The lower 8-bits of the Fabric ID
     232              :         // * 0x00
     233              :         // * The 16-bits Group Identifier in big-endian order
     234            2 :         uint32_t groupId = static_cast<uint32_t>((fabric << 24) & 0xff000000) | group;
     235            2 :         return UDP(Inet::IPAddress::MakeIPv6PrefixMulticast(scope, prefixLength, prefix, groupId));
     236              :     }
     237              : 
     238              : private:
     239              :     static PeerAddress FromString(char * addrStr, uint16_t port, Type type)
     240              :     {
     241              :         Inet::IPAddress addr;
     242              :         Inet::InterfaceId interfaceId;
     243              :         Inet::IPAddress::FromString(addrStr, addr, interfaceId);
     244              :         return PeerAddress(addr, type).SetPort(port).SetInterface(interfaceId);
     245              :     }
     246              :     Inet::IPAddress mIPAddress   = {};
     247              :     Type mTransportType          = Type::kUndefined;
     248              :     uint16_t mPort               = CHIP_PORT; ///< Relevant for UDP data sending.
     249              :     Inet::InterfaceId mInterface = Inet::InterfaceId::Null();
     250              :     NodeId mRemoteId             = 0;
     251              : };
     252              : 
     253              : } // namespace Transport
     254              : } // namespace chip
        

Generated by: LCOV version 2.0-1