LCOV - code coverage report
Current view: top level - lib/dnssd - ServiceNaming.cpp (source / functions) Hit Total Coverage
Test: lcov_final.info Lines: 74 82 90.2 %
Date: 2024-02-15 08:20:41 Functions: 5 5 100.0 %

          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 :     ReturnErrorCodeIf(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 :     ReturnErrorCodeIf(name == nullptr, CHIP_ERROR_INVALID_ARGUMENT);
      47          17 :     ReturnErrorCodeIf(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 :     ReturnErrorCodeIf(len < totalLength, CHIP_ERROR_INVALID_ARGUMENT);
      59             : 
      60             :     // Check that we have a proper terminator.
      61          12 :     ReturnErrorCodeIf(name[totalLength] != '\0' && name[totalLength] != '.', CHIP_ERROR_WRONG_NODE_ID);
      62             : 
      63             :     // Check what we have a separator where we expect.
      64          10 :     ReturnErrorCodeIf(name[fabricIdStringLength] != '-', CHIP_ERROR_WRONG_NODE_ID);
      65             : 
      66             :     static constexpr size_t bufferSize = max(fabricIdByteLength, nodeIdByteLength);
      67             :     uint8_t buf[bufferSize];
      68             : 
      69           5 :     ReturnErrorCodeIf(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 :     ReturnErrorCodeIf(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          20 : CHIP_ERROR MakeHostName(char * buffer, size_t bufferLen, const chip::ByteSpan & macOrEui64)
      84             : {
      85          20 :     ReturnErrorCodeIf(bufferLen < macOrEui64.size() * 2 + 1, CHIP_ERROR_BUFFER_TOO_SMALL);
      86             : 
      87          20 :     int idx = 0;
      88         180 :     for (size_t i = 0; i < macOrEui64.size(); ++i)
      89             :     {
      90         160 :         idx += snprintf(buffer + idx, 3, "%02X", macOrEui64.data()[i]);
      91             :     }
      92          20 :     return CHIP_NO_ERROR;
      93             : }
      94             : 
      95          84 : CHIP_ERROR MakeServiceSubtype(char * buffer, size_t bufferLen, DiscoveryFilter subtype)
      96             : {
      97             :     int requiredSize;
      98          84 :     switch (subtype.type)
      99             :     {
     100          18 :     case DiscoveryFilterType::kShortDiscriminator:
     101             :         // 4-bit number
     102          18 :         if (subtype.code >= 1 << 4)
     103             :         {
     104           2 :             return CHIP_ERROR_INVALID_ARGUMENT;
     105             :         }
     106          16 :         requiredSize = snprintf(buffer, bufferLen, "_S%u", static_cast<uint16_t>(subtype.code));
     107          16 :         break;
     108          18 :     case DiscoveryFilterType::kLongDiscriminator:
     109             :         // 12-bit number
     110          18 :         if (subtype.code >= 1 << 12)
     111             :         {
     112           2 :             return CHIP_ERROR_INVALID_ARGUMENT;
     113             :         }
     114          16 :         requiredSize = snprintf(buffer, bufferLen, "_L%u", static_cast<uint16_t>(subtype.code));
     115          16 :         break;
     116          17 :     case DiscoveryFilterType::kVendorId:
     117          17 :         if (subtype.code >= 1 << 16)
     118             :         {
     119           2 :             return CHIP_ERROR_INVALID_ARGUMENT;
     120             :         }
     121          15 :         requiredSize = snprintf(buffer, bufferLen, "_V%u", static_cast<uint16_t>(subtype.code));
     122          15 :         break;
     123           5 :     case DiscoveryFilterType::kDeviceType:
     124           5 :         requiredSize = snprintf(buffer, bufferLen, "_T%" PRIu32, static_cast<uint32_t>(subtype.code));
     125           5 :         break;
     126          14 :     case DiscoveryFilterType::kCommissioningMode:
     127          14 :         requiredSize = snprintf(buffer, bufferLen, "_CM");
     128          14 :         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          68 :     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             :         else
     166             :         {
     167           0 :             return CHIP_ERROR_NOT_IMPLEMENTED;
     168             :         }
     169             :     }
     170             :     else
     171             :     {
     172          13 :         ReturnErrorOnFailure(MakeServiceSubtype(buffer, bufferLen, nameDesc));
     173          10 :         size_t subtypeLen = strlen(buffer);
     174          10 :         if (type == DiscoveryType::kCommissionableNode)
     175             :         {
     176           9 :             requiredSize = snprintf(buffer + subtypeLen, bufferLen - subtypeLen, ".%s.%s", kSubtypeServiceNamePart,
     177             :                                     kCommissionableServiceName);
     178             :         }
     179           1 :         else if (type == DiscoveryType::kCommissionerNode)
     180             :         {
     181             :             requiredSize =
     182           0 :                 snprintf(buffer + subtypeLen, bufferLen - subtypeLen, ".%s.%s", kSubtypeServiceNamePart, kCommissionerServiceName);
     183             :         }
     184           1 :         else if (type == DiscoveryType::kOperational)
     185             :         {
     186             :             requiredSize =
     187           1 :                 snprintf(buffer + subtypeLen, bufferLen - subtypeLen, ".%s.%s", kSubtypeServiceNamePart, kOperationalServiceName);
     188             :         }
     189             :         else
     190             :         {
     191           0 :             return CHIP_ERROR_NOT_IMPLEMENTED;
     192             :         }
     193             :     }
     194             : 
     195          14 :     return (static_cast<size_t>(requiredSize) <= (bufferLen - 1)) ? CHIP_NO_ERROR : CHIP_ERROR_NO_MEMORY;
     196             : }
     197             : 
     198             : } // namespace Dnssd
     199             : } // namespace chip

Generated by: LCOV version 1.14