Matter SDK Coverage Report
Current view: top level - lib/dnssd - ServiceNaming.cpp (source / functions) Coverage Total Hit
Test: SHA:f84fe08d06f240e801b5d923f8a938a9938ca110 Lines: 88.1 % 84 74
Test Date: 2025-02-22 08:08:07 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /*
       2              :  *
       3              :  *    Copyright (c) 2021 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              : #include "ServiceNaming.h"
      19              : 
      20              : #include <lib/core/CHIPEncoding.h>
      21              : #include <lib/support/BytesToHex.h>
      22              : #include <lib/support/CodeUtils.h>
      23              : 
      24              : #include <cstdio>
      25              : #include <inttypes.h>
      26              : #include <string.h>
      27              : 
      28              : namespace chip {
      29              : namespace Dnssd {
      30              : 
      31           45 : CHIP_ERROR MakeInstanceName(char * buffer, size_t bufferLen, const PeerId & peerId)
      32              : {
      33           45 :     VerifyOrReturnError(bufferLen > Operational::kInstanceNameMaxLength, CHIP_ERROR_BUFFER_TOO_SMALL);
      34              : 
      35           11 :     NodeId nodeId               = peerId.GetNodeId();
      36           11 :     CompressedFabricId fabricId = peerId.GetCompressedFabricId();
      37              : 
      38           11 :     snprintf(buffer, bufferLen, "%08" PRIX32 "%08" PRIX32 "-%08" PRIX32 "%08" PRIX32, static_cast<uint32_t>(fabricId >> 32),
      39           11 :              static_cast<uint32_t>(fabricId), static_cast<uint32_t>(nodeId >> 32), static_cast<uint32_t>(nodeId));
      40              : 
      41           11 :     return CHIP_NO_ERROR;
      42              : }
      43              : 
      44           19 : CHIP_ERROR ExtractIdFromInstanceName(const char * name, PeerId * peerId)
      45              : {
      46           19 :     VerifyOrReturnError(name != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
      47           17 :     VerifyOrReturnError(peerId != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
      48              : 
      49              :     // Make sure the string is long enough.
      50              :     static constexpr size_t fabricIdByteLength   = 8;
      51              :     static constexpr size_t fabricIdStringLength = fabricIdByteLength * 2;
      52              :     static constexpr size_t nodeIdByteLength     = 8;
      53              :     static constexpr size_t nodeIdStringLength   = nodeIdByteLength * 2;
      54              :     static constexpr size_t totalLength          = fabricIdStringLength + nodeIdStringLength + 1; // +1 for '-'
      55              : 
      56              :     // Ensure we have at least totalLength chars.
      57           16 :     size_t len = strnlen(name, totalLength);
      58           16 :     VerifyOrReturnError(len >= totalLength, CHIP_ERROR_INVALID_ARGUMENT);
      59              : 
      60              :     // Check that we have a proper terminator.
      61           12 :     VerifyOrReturnError(name[totalLength] == '\0' || name[totalLength] == '.', CHIP_ERROR_WRONG_NODE_ID);
      62              : 
      63              :     // Check what we have a separator where we expect.
      64           10 :     VerifyOrReturnError(name[fabricIdStringLength] == '-', CHIP_ERROR_WRONG_NODE_ID);
      65              : 
      66              :     static constexpr size_t bufferSize = std::max(fabricIdByteLength, nodeIdByteLength);
      67              :     uint8_t buf[bufferSize];
      68              : 
      69            5 :     VerifyOrReturnError(Encoding::HexToBytes(name, fabricIdStringLength, buf, bufferSize) != 0, CHIP_ERROR_WRONG_NODE_ID);
      70              :     // Buf now stores the fabric id, as big-endian bytes.
      71              :     static_assert(fabricIdByteLength == sizeof(uint64_t), "Wrong number of bytes");
      72            4 :     peerId->SetCompressedFabricId(Encoding::BigEndian::Get64(buf));
      73              : 
      74            4 :     VerifyOrReturnError(Encoding::HexToBytes(name + fabricIdStringLength + 1, nodeIdStringLength, buf, bufferSize) != 0,
      75              :                         CHIP_ERROR_WRONG_NODE_ID);
      76              :     // Buf now stores the node id id, as big-endian bytes.
      77              :     static_assert(nodeIdByteLength == sizeof(uint64_t), "Wrong number of bytes");
      78            4 :     peerId->SetNodeId(Encoding::BigEndian::Get64(buf));
      79              : 
      80            4 :     return CHIP_NO_ERROR;
      81              : }
      82              : 
      83           19 : CHIP_ERROR MakeHostName(char * buffer, size_t bufferLen, const chip::ByteSpan & macOrEui64)
      84              : {
      85           19 :     VerifyOrReturnError(bufferLen >= macOrEui64.size() * 2 + 1, CHIP_ERROR_BUFFER_TOO_SMALL);
      86              : 
      87           19 :     int idx = 0;
      88          157 :     for (size_t i = 0; i < macOrEui64.size(); ++i)
      89              :     {
      90          138 :         idx += snprintf(buffer + idx, 3, "%02X", macOrEui64.data()[i]);
      91              :     }
      92           19 :     return CHIP_NO_ERROR;
      93              : }
      94              : 
      95           80 : CHIP_ERROR MakeServiceSubtype(char * buffer, size_t bufferLen, DiscoveryFilter subtype)
      96              : {
      97              :     int requiredSize;
      98           80 :     switch (subtype.type)
      99              :     {
     100           17 :     case DiscoveryFilterType::kShortDiscriminator:
     101              :         // 4-bit number
     102           17 :         if (subtype.code >= 1 << 4)
     103              :         {
     104            2 :             return CHIP_ERROR_INVALID_ARGUMENT;
     105              :         }
     106           15 :         requiredSize = snprintf(buffer, bufferLen, "_S%u", static_cast<uint16_t>(subtype.code));
     107           15 :         break;
     108           17 :     case DiscoveryFilterType::kLongDiscriminator:
     109              :         // 12-bit number
     110           17 :         if (subtype.code >= 1 << 12)
     111              :         {
     112            2 :             return CHIP_ERROR_INVALID_ARGUMENT;
     113              :         }
     114           15 :         requiredSize = snprintf(buffer, bufferLen, "_L%u", static_cast<uint16_t>(subtype.code));
     115           15 :         break;
     116           16 :     case DiscoveryFilterType::kVendorId:
     117           16 :         if (subtype.code >= 1 << 16)
     118              :         {
     119            2 :             return CHIP_ERROR_INVALID_ARGUMENT;
     120              :         }
     121           14 :         requiredSize = snprintf(buffer, bufferLen, "_V%u", static_cast<uint16_t>(subtype.code));
     122           14 :         break;
     123            5 :     case DiscoveryFilterType::kDeviceType:
     124            5 :         requiredSize = snprintf(buffer, bufferLen, "_T%" PRIu32, static_cast<uint32_t>(subtype.code));
     125            5 :         break;
     126           13 :     case DiscoveryFilterType::kCommissioningMode:
     127           13 :         requiredSize = snprintf(buffer, bufferLen, "_CM");
     128           13 :         break;
     129            0 :     case DiscoveryFilterType::kCommissioner:
     130            0 :         if (subtype.code > 1)
     131              :         {
     132            0 :             return CHIP_ERROR_INVALID_ARGUMENT;
     133              :         }
     134            0 :         requiredSize = snprintf(buffer, bufferLen, "_D%u", static_cast<uint16_t>(subtype.code));
     135            0 :         break;
     136           10 :     case DiscoveryFilterType::kCompressedFabricId:
     137           10 :         requiredSize = snprintf(buffer, bufferLen, "_I");
     138           20 :         return Encoding::Uint64ToHex(subtype.code, &buffer[requiredSize], bufferLen - static_cast<size_t>(requiredSize),
     139           10 :                                      Encoding::HexFlags::kUppercaseAndNullTerminate);
     140              :         break;
     141            1 :     case DiscoveryFilterType::kInstanceName:
     142            1 :         requiredSize = snprintf(buffer, bufferLen, "%s", subtype.instanceName);
     143            1 :         break;
     144            1 :     case DiscoveryFilterType::kNone:
     145            1 :         requiredSize = 0;
     146            1 :         buffer[0]    = '\0';
     147            1 :         break;
     148              :     }
     149           64 :     return (static_cast<size_t>(requiredSize) <= (bufferLen - 1)) ? CHIP_NO_ERROR : CHIP_ERROR_NO_MEMORY;
     150              : }
     151              : 
     152           17 : CHIP_ERROR MakeServiceTypeName(char * buffer, size_t bufferLen, DiscoveryFilter nameDesc, DiscoveryType type)
     153              : {
     154              :     int requiredSize;
     155           17 :     if (nameDesc.type == DiscoveryFilterType::kNone)
     156              :     {
     157            4 :         if (type == DiscoveryType::kCommissionableNode)
     158              :         {
     159            3 :             requiredSize = snprintf(buffer, bufferLen, kCommissionableServiceName);
     160              :         }
     161            1 :         else if (type == DiscoveryType::kCommissionerNode)
     162              :         {
     163            1 :             requiredSize = snprintf(buffer, bufferLen, kCommissionerServiceName);
     164              :         }
     165            0 :         else if (type == DiscoveryType::kOperational)
     166              :         {
     167            0 :             requiredSize = snprintf(buffer, bufferLen, kOperationalServiceName);
     168              :         }
     169              :         else
     170              :         {
     171            0 :             return CHIP_ERROR_NOT_IMPLEMENTED;
     172              :         }
     173              :     }
     174              :     else
     175              :     {
     176           13 :         ReturnErrorOnFailure(MakeServiceSubtype(buffer, bufferLen, nameDesc));
     177           10 :         size_t subtypeLen = strlen(buffer);
     178           10 :         if (type == DiscoveryType::kCommissionableNode)
     179              :         {
     180            9 :             requiredSize = snprintf(buffer + subtypeLen, bufferLen - subtypeLen, ".%s.%s", kSubtypeServiceNamePart,
     181              :                                     kCommissionableServiceName);
     182              :         }
     183            1 :         else if (type == DiscoveryType::kCommissionerNode)
     184              :         {
     185              :             requiredSize =
     186            0 :                 snprintf(buffer + subtypeLen, bufferLen - subtypeLen, ".%s.%s", kSubtypeServiceNamePart, kCommissionerServiceName);
     187              :         }
     188            1 :         else if (type == DiscoveryType::kOperational)
     189              :         {
     190              :             requiredSize =
     191            1 :                 snprintf(buffer + subtypeLen, bufferLen - subtypeLen, ".%s.%s", kSubtypeServiceNamePart, kOperationalServiceName);
     192              :         }
     193              :         else
     194              :         {
     195            0 :             return CHIP_ERROR_NOT_IMPLEMENTED;
     196              :         }
     197              :     }
     198              : 
     199           14 :     return (static_cast<size_t>(requiredSize) <= (bufferLen - 1)) ? CHIP_NO_ERROR : CHIP_ERROR_NO_MEMORY;
     200              : }
     201              : 
     202              : } // namespace Dnssd
     203              : } // namespace chip
        

Generated by: LCOV version 2.0-1