Răsfoiți Sursa

Fix DNS-SD behavior relating to commissioning (#8888)

* cleanup fixes relating to udc

* add tests, fix platform eventloop conflict

* build fix

* restyled fix

* merge with latest

* fix CM and AC in DNS-SD

* address PR comments

* fix breakage, change from bitmap to enum

* PR feedback, read port values from platform config

* straggler

* fix darwin build

* more signature change fixes

* move port config to Mdns and Server

* add command line options for setting ports

* cleanup naming of CM/AC options

* fix builds without MDNS
chrisdecenzo 4 ani în urmă
părinte
comite
515ea65f84

+ 2 - 1
examples/minimal-mdns/advertiser.cpp

@@ -274,7 +274,8 @@ int main(int argc, char ** args)
                 .SetMac(chip::ByteSpan(gOptions.mac, 6))
                 .SetVendorId(gOptions.vendorId)
                 .SetProductId(gOptions.productId)
-                .SetCommissioningMode(gOptions.commissioningMode, gOptions.commissioningModeOpenWindow)
+                .SetCommissioningMode(gOptions.commissioningMode)
+                .SetAdditionalCommissioning(gOptions.commissioningModeOpenWindow)
                 .SetDeviceType(gOptions.deviceType)
                 .SetDeviceName(gOptions.deviceName)
                 .SetRotatingId(gOptions.rotatingId)

+ 12 - 2
examples/platform/linux/AppMain.cpp

@@ -188,8 +188,10 @@ CHIP_ERROR InitCommissioner()
 
     ReturnErrorOnFailure(gOpCredsIssuer.Initialize(gServerStorage));
 
-    ReturnErrorOnFailure(gCommissioner.SetUdpListenPort(CHIP_PORT + 2));
-    ReturnErrorOnFailure(gCommissioner.SetUdcListenPort(CHIP_PORT + 3));
+    // use a different listen port for the commissioner.
+    ReturnErrorOnFailure(gCommissioner.SetUdpListenPort(LinuxDeviceOptions::GetInstance().securedCommissionerPort));
+    // No need to explicitly set the UDC port since we will use default
+    ReturnErrorOnFailure(gCommissioner.SetUdcListenPort(LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort));
 
     chip::Platform::ScopedMemoryBuffer<uint8_t> noc;
     VerifyOrReturnError(noc.Alloc(chip::Controller::kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY);
@@ -234,6 +236,14 @@ void ChipLinuxAppMainLoop()
     chip::Shell::RegisterCommissioneeCommands();
 #endif
 
+#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
+    // use a different service port to make testing possible with other sample devices running on same host
+    ServerConfigParams params;
+    params.securedServicePort   = LinuxDeviceOptions::GetInstance().securedDevicePort;
+    params.unsecuredServicePort = LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort;
+    SetServerConfig(params);
+#endif // CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
+
     // Init ZCL Data Model and CHIP App Server
     InitServer();
 

+ 28 - 0
examples/platform/linux/CommissioneeShellCommands.cpp

@@ -20,6 +20,7 @@
  */
 
 #include <CommissioneeShellCommands.h>
+#include <app/server/Mdns.h>
 #include <app/server/Server.h>
 #include <inttypes.h>
 #include <lib/core/CHIPCore.h>
@@ -61,6 +62,10 @@ static CHIP_ERROR PrintAllCommands()
     streamer_printf(sout,
                     "  sendudc <address> <port>   Send UDC message to address. Usage: commissionee sendudc 127.0.0.1 5543\r\n");
 #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
+    streamer_printf(sout,
+                    "  restartmdns <commissioningMode> (disabled|enabled_basic|enabled_enhanced)   Start Mdns with given "
+                    "settings. Usage: commissionee "
+                    "restartmdns enabled_basic\r\n");
     streamer_printf(sout, "\r\n");
 
     return CHIP_NO_ERROR;
@@ -84,6 +89,29 @@ static CHIP_ERROR CommissioneeHandler(int argc, char ** argv)
         return error  = SendUDC(true, chip::Transport::PeerAddress::UDP(commissioner, port));
     }
 #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT
+    else if (strcmp(argv[0], "restartmdns") == 0)
+    {
+        if (argc < 2)
+        {
+            return PrintAllCommands();
+        }
+        if (strcmp(argv[1], "disabled") == 0)
+        {
+            chip::app::Mdns::StartServer(chip::app::Mdns::CommissioningMode::kDisabled);
+            return CHIP_NO_ERROR;
+        }
+        if (strcmp(argv[1], "enabled_basic") == 0)
+        {
+            chip::app::Mdns::StartServer(chip::app::Mdns::CommissioningMode::kEnabledBasic);
+            return CHIP_NO_ERROR;
+        }
+        else if (strcmp(argv[1], "enabled_enhanced") == 0)
+        {
+            chip::app::Mdns::StartServer(chip::app::Mdns::CommissioningMode::kEnabledEnhanced);
+            return CHIP_NO_ERROR;
+        }
+        return PrintAllCommands();
+    }
     else
     {
         return CHIP_ERROR_INVALID_ARGUMENT;

+ 38 - 10
examples/platform/linux/Options.cpp

@@ -33,16 +33,19 @@ LinuxDeviceOptions gDeviceOptions;
 // Follow the code style of command line arguments in case we need to add more options in the future.
 enum
 {
-    kDeviceOption_BleDevice     = 0x1000,
-    kDeviceOption_WiFi          = 0x1001,
-    kDeviceOption_Thread        = 0x1002,
-    kDeviceOption_Version       = 0x1003,
-    kDeviceOption_VendorID      = 0x1004,
-    kDeviceOption_ProductID     = 0x1005,
-    kDeviceOption_CustomFlow    = 0x1006,
-    kDeviceOption_Capabilities  = 0x1007,
-    kDeviceOption_Discriminator = 0x1008,
-    kDeviceOption_Passcode      = 0x1009
+    kDeviceOption_BleDevice                 = 0x1000,
+    kDeviceOption_WiFi                      = 0x1001,
+    kDeviceOption_Thread                    = 0x1002,
+    kDeviceOption_Version                   = 0x1003,
+    kDeviceOption_VendorID                  = 0x1004,
+    kDeviceOption_ProductID                 = 0x1005,
+    kDeviceOption_CustomFlow                = 0x1006,
+    kDeviceOption_Capabilities              = 0x1007,
+    kDeviceOption_Discriminator             = 0x1008,
+    kDeviceOption_Passcode                  = 0x1009,
+    kDeviceOption_SecuredDevicePort         = 0x100a,
+    kDeviceOption_SecuredCommissionerPort   = 0x100b,
+    kDeviceOption_UnsecuredCommissionerPort = 0x100c
 };
 
 constexpr unsigned kAppUsageLength = 64;
@@ -61,6 +64,9 @@ OptionDef sDeviceOptionDefs[] = { { "ble-device", kArgumentRequired, kDeviceOpti
                                   { "capabilities", kArgumentRequired, kDeviceOption_Capabilities },
                                   { "discriminator", kArgumentRequired, kDeviceOption_Discriminator },
                                   { "passcode", kArgumentRequired, kDeviceOption_Passcode },
+                                  { "secured-device-port", kArgumentRequired, kDeviceOption_SecuredDevicePort },
+                                  { "secured-commissioner-port", kArgumentRequired, kDeviceOption_SecuredCommissionerPort },
+                                  { "unsecured-commissioner-port", kArgumentRequired, kDeviceOption_UnsecuredCommissionerPort },
                                   {} };
 
 const char * sDeviceOptionHelp =
@@ -97,6 +103,16 @@ const char * sDeviceOptionHelp =
     "\n"
     "  --passcode <passcode>\n"
     "       A 27-bit unsigned integer, which serves as proof of possession during commissioning.\n"
+    "\n"
+    "  --secured-device-port <port>\n"
+    "       A 16-bit unsigned integer specifying the listen port to use for secure device messages (default is 5540).\n"
+    "\n"
+    "  --secured-commissioner-port <port>\n"
+    "       A 16-bit unsigned integer specifying the listen port to use for secure commissioner messages (default is 5542). Only "
+    "valid when app is both device and commissioner\n"
+    "\n"
+    "  --unsecured-commissioner-port <port>\n"
+    "       A 16-bit unsigned integer specifying the port to use for unsecured commissioner messages (default is 5550).\n"
     "\n";
 
 bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue)
@@ -150,6 +166,18 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
         LinuxDeviceOptions::GetInstance().payload.setUpPINCode = static_cast<uint32_t>(atoi(aValue));
         break;
 
+    case kDeviceOption_SecuredDevicePort:
+        LinuxDeviceOptions::GetInstance().securedDevicePort = static_cast<uint16_t>(atoi(aValue));
+        break;
+
+    case kDeviceOption_SecuredCommissionerPort:
+        LinuxDeviceOptions::GetInstance().securedCommissionerPort = static_cast<uint16_t>(atoi(aValue));
+        break;
+
+    case kDeviceOption_UnsecuredCommissionerPort:
+        LinuxDeviceOptions::GetInstance().unsecuredCommissionerPort = static_cast<uint16_t>(atoi(aValue));
+        break;
+
     default:
         PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
         retval = false;

+ 6 - 3
examples/platform/linux/Options.h

@@ -32,9 +32,12 @@
 struct LinuxDeviceOptions
 {
     chip::SetupPayload payload;
-    uint32_t mBleDevice = 0;
-    bool mWiFi          = false;
-    bool mThread        = false;
+    uint32_t mBleDevice                = 0;
+    bool mWiFi                         = false;
+    bool mThread                       = false;
+    uint32_t securedDevicePort         = CHIP_PORT;
+    uint32_t securedCommissionerPort   = CHIP_PORT + 2;
+    uint32_t unsecuredCommissionerPort = CHIP_UDC_PORT;
 
     static LinuxDeviceOptions & GetInstance();
 };

+ 79 - 32
src/app/server/Mdns.cpp

@@ -78,6 +78,29 @@ chip::ByteSpan FillMAC(uint8_t (&mac)[8])
 
 } // namespace
 
+uint16_t gSecuredPort   = CHIP_PORT;
+uint16_t gUnsecuredPort = CHIP_UDC_PORT;
+
+void SetSecuredPort(uint16_t port)
+{
+    gSecuredPort = port;
+}
+
+uint16_t GetSecuredPort()
+{
+    return gSecuredPort;
+}
+
+void SetUnsecuredPort(uint16_t port)
+{
+    gUnsecuredPort = port;
+}
+
+uint16_t GetUnsecuredPort()
+{
+    return gUnsecuredPort;
+}
+
 CHIP_ERROR GetCommissionableInstanceName(char * buffer, size_t bufferLen)
 {
     auto & mdnsAdvertiser = chip::Mdns::ServiceAdvertiser::Instance();
@@ -97,7 +120,7 @@ CHIP_ERROR AdvertiseOperational()
                 chip::Mdns::OperationalAdvertisingParameters()
                     .SetPeerId(PeerId().SetFabricId(fabricInfo.GetFabricId()).SetNodeId(fabricInfo.GetNodeId()))
                     .SetMac(FillMAC(mac))
-                    .SetPort(CHIP_PORT)
+                    .SetPort(GetSecuredPort())
                     .SetMRPRetryIntervals(CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL,
                                           CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL)
                     .EnableIpV4(true);
@@ -112,35 +135,27 @@ CHIP_ERROR AdvertiseOperational()
             ReturnErrorOnFailure(mdnsAdvertiser.Advertise(advertiseParameters));
         }
     }
-
     return CHIP_NO_ERROR;
 }
 
-/// Set MDNS commissioner advertisement
-CHIP_ERROR AdvertiseCommisioner()
-{
-    return Advertise(false);
-}
-
-/// Set MDNS commissionable node advertisement
-CHIP_ERROR AdvertiseCommissionableNode()
+/// Overloaded utility method for commissioner and commissionable advertisement
+/// This method is used for both commissioner discovery and commissionable node discovery since
+/// they share many fields.
+///   commissionableNode = true : advertise commissionable node
+///   commissionableNode = false : advertise commissioner
+CHIP_ERROR Advertise(bool commissionableNode, CommissioningMode mode)
 {
-    return Advertise(true);
-}
+    bool commissioningMode       = (mode != CommissioningMode::kDisabled);
+    bool additionalCommissioning = (mode == CommissioningMode::kEnabledEnhanced);
 
-/// commissionableNode
-// CHIP_ERROR Advertise(chip::Mdns::CommssionAdvertiseMode mode)
-CHIP_ERROR Advertise(bool commissionableNode)
-{
-    auto advertiseParameters = chip::Mdns::CommissionAdvertisingParameters().SetPort(CHIP_PORT).EnableIpV4(true);
+    auto advertiseParameters = chip::Mdns::CommissionAdvertisingParameters()
+                                   .SetPort(commissionableNode ? GetSecuredPort() : GetUnsecuredPort())
+                                   .EnableIpV4(true);
     advertiseParameters.SetCommissionAdvertiseMode(commissionableNode ? chip::Mdns::CommssionAdvertiseMode::kCommissionableNode
                                                                       : chip::Mdns::CommssionAdvertiseMode::kCommissioner);
 
-    // TODO: device can re-enter commissioning mode after being fully provisioned
-    // (additionalPairing == true)
-    bool notYetCommissioned = !DeviceLayer::ConfigurationMgr().IsFullyProvisioned();
-    bool additionalPairing  = false;
-    advertiseParameters.SetCommissioningMode(notYetCommissioned, additionalPairing);
+    advertiseParameters.SetCommissioningMode(commissioningMode);
+    advertiseParameters.SetAdditionalCommissioning(additionalCommissioning);
 
     char pairingInst[chip::Mdns::kKeyPairingInstructionMaxLength + 1];
 
@@ -192,7 +207,7 @@ CHIP_ERROR Advertise(bool commissionableNode)
     advertiseParameters.SetRotatingId(chip::Optional<const char *>::Value(rotatingDeviceIdHexBuffer));
 #endif
 
-    if (notYetCommissioned)
+    if (!additionalCommissioning)
     {
         if (DeviceLayer::ConfigurationMgr().GetInitialPairingHint(value) != CHIP_NO_ERROR)
         {
@@ -241,10 +256,23 @@ CHIP_ERROR Advertise(bool commissionableNode)
     return mdnsAdvertiser.Advertise(advertiseParameters);
 }
 
+/// Set MDNS commissioner advertisement
+CHIP_ERROR AdvertiseCommissioner()
+{
+    return Advertise(false /* commissionableNode */, CommissioningMode::kDisabled);
+}
+
+/// Set MDNS commissionable node advertisement
+CHIP_ERROR AdvertiseCommissionableNode(CommissioningMode mode)
+{
+    return Advertise(true /* commissionableNode */, mode);
+}
+
 /// (Re-)starts the minmdns server
-void StartServer()
+/// - if device has not yet been commissioned, then commissioning mode will show as enabled (CM=1, AC=0)
+/// - if device has been commissioned, then commissioning mode will reflect the state of mode argument
+void StartServer(CommissioningMode mode)
 {
-    ChipLogProgress(Discovery, "Start dns-sd server");
     CHIP_ERROR err = chip::Mdns::ServiceAdvertiser::Instance().Start(&chip::DeviceLayer::InetLayer, chip::Mdns::kMdnsPort);
 
     err = app::Mdns::AdvertiseOperational();
@@ -255,25 +283,44 @@ void StartServer()
 
     if (HaveOperationalCredentials())
     {
+        if (mode != CommissioningMode::kDisabled)
+        {
+            err = app::Mdns::AdvertiseCommissionableNode(mode);
+            if (err != CHIP_NO_ERROR)
+            {
+                ChipLogError(Discovery, "Failed to advertise commissionable node: %s", chip::ErrorStr(err));
+            }
+        }
 #if CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
-        err = app::Mdns::AdvertiseCommissionableNode();
-#endif
+        else
+        {
+            err = app::Mdns::AdvertiseCommissionableNode(mode);
+            if (err != CHIP_NO_ERROR)
+            {
+                ChipLogError(Discovery, "Failed to advertise extended commissionable node: %s", chip::ErrorStr(err));
+            }
+        }
+#endif // CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY
     }
     else
     {
 #if CHIP_DEVICE_CONFIG_ENABLE_UNPROVISIONED_MDNS
-        err = app::Mdns::AdvertiseCommissionableNode();
+        ChipLogProgress(Discovery, "Start dns-sd server - no current nodeId");
+        err = app::Mdns::AdvertiseCommissionableNode(CommissioningMode::kEnabledBasic);
+        if (err != CHIP_NO_ERROR)
+        {
+            ChipLogError(Discovery, "Failed to advertise unprovisioned commissionable node: %s", chip::ErrorStr(err));
+        }
 #endif
     }
 
 #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
-    err = app::Mdns::AdvertiseCommisioner();
-#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
-
+    err = app::Mdns::AdvertiseCommissioner();
     if (err != CHIP_NO_ERROR)
     {
-        ChipLogError(Discovery, "Failed to start mDNS server: %s", chip::ErrorStr(err));
+        ChipLogError(Discovery, "Failed to advertise commissioner: %s", chip::ErrorStr(err));
     }
+#endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
 }
 
 #if CHIP_ENABLE_ROTATING_DEVICE_ID

+ 23 - 6
src/app/server/Mdns.h

@@ -24,6 +24,25 @@ namespace chip {
 namespace app {
 namespace Mdns {
 
+enum class CommissioningMode
+{
+    kDisabled,       // Commissioning Mode is disabled, CM=0, AC=0 in DNS-SD key/value pairs
+    kEnabledBasic,   // Basic Commissioning Mode, CM=1, AC=0 in DNS-SD key/value pairs
+    kEnabledEnhanced // Enhanced Commissioning Mode, CM=1, AC=1 in DNS-SD key/value pairs
+};
+
+/// Sets the secure Matter port
+void SetSecuredPort(uint16_t port);
+
+/// Gets the secure Matter port
+uint16_t GetSecuredPort();
+
+/// Sets the unsecure Matter port
+void SetUnsecuredPort(uint16_t port);
+
+/// Gets the unsecure Matter port
+uint16_t GetUnsecuredPort();
+
 /// Start operational advertising
 CHIP_ERROR AdvertiseOperational();
 
@@ -31,14 +50,12 @@ CHIP_ERROR AdvertiseOperational();
 CHIP_ERROR AdvertiseCommissioner();
 
 /// Set MDNS commissionable node advertisement
-CHIP_ERROR AdvertiseCommissionableNode();
-
-/// Set MDNS advertisement
-// CHIP_ERROR Advertise(chip::Mdns::CommssionAdvertiseMode mode);
-CHIP_ERROR Advertise(bool commissionableNode);
+CHIP_ERROR AdvertiseCommissionableNode(CommissioningMode mode);
 
 /// (Re-)starts the minmdns server
-void StartServer();
+/// - if device has not yet been commissioned, then commissioning mode will show as enabled (CM=1, AC=0)
+/// - if device has been commissioned, then commissioning mode will reflect the state of mode argument
+void StartServer(CommissioningMode mode = CommissioningMode::kDisabled);
 
 CHIP_ERROR GenerateRotatingDeviceId(char rotatingDeviceIdHexBuffer[], size_t rotatingDeviceIdHexBufferSize);
 

+ 11 - 0
src/app/server/RendezvousServer.cpp

@@ -55,6 +55,8 @@ void RendezvousServer::OnPlatformEvent(const DeviceLayer::ChipDeviceEvent * even
             ChipLogError(Discovery, "Commissioning errored out with error %" CHIP_ERROR_FORMAT,
                          event->CommissioningComplete.status.Format());
         }
+        // reset all advertising
+        app::Mdns::StartServer(app::Mdns::CommissioningMode::kDisabled);
     }
     else if (event->Type == DeviceLayer::DeviceEventType::kOperationalNetworkEnabled)
     {
@@ -91,6 +93,12 @@ CHIP_ERROR RendezvousServer::WaitForPairing(const RendezvousParameters & params,
         ReturnErrorOnFailure(GetAdvertisementDelegate()->StartAdvertisement());
     }
 
+    // reset all advertising, indicating we are in commissioningMode
+    // and we were put into this state via a command for additional commissioning
+    // NOTE: when device has never been commissioned, Rendezvous will ensure AP is false
+    app::Mdns::StartServer(params.HasPASEVerifier() ? app::Mdns::CommissioningMode::kEnabledBasic
+                                                    : app::Mdns::CommissioningMode::kEnabledEnhanced);
+
     mSessionMgr      = sessionMgr;
     mExchangeManager = exchangeManager;
 
@@ -124,6 +132,9 @@ void RendezvousServer::Cleanup()
     {
         GetAdvertisementDelegate()->StopAdvertisement();
     }
+
+    // reset all advertising
+    app::Mdns::StartServer(app::Mdns::CommissioningMode::kDisabled);
 }
 
 void RendezvousServer::OnSessionEstablishmentError(CHIP_ERROR err)

+ 20 - 5
src/app/server/Server.cpp

@@ -328,6 +328,15 @@ bool IsPairingWindowOpen()
     return gPairingWindowOpen;
 }
 
+uint16_t gSecuredServicePort   = CHIP_PORT;
+uint16_t gUnsecuredServicePort = CHIP_UDC_PORT;
+
+void SetServerConfig(ServerConfigParams params)
+{
+    gSecuredServicePort   = params.securedServicePort;
+    gUnsecuredServicePort = params.unsecuredServicePort;
+}
+
 // The function will initialize datamodel handler and then start the server
 // The server assumes the platform's networking has been setup already
 void InitServer(AppDelegate * delegate)
@@ -355,15 +364,16 @@ void InitServer(AppDelegate * delegate)
     SuccessOrExit(err);
 
     // Init transport before operations with secure session mgr.
-    err = gTransports.Init(UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv6)
+    err = gTransports.Init(
+        UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv6).SetListenPort(gSecuredServicePort)
 
 #if INET_CONFIG_ENABLE_IPV4
-                               ,
-                           UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv4)
+            ,
+        UdpListenParameters(&DeviceLayer::InetLayer).SetAddressType(kIPAddressType_IPv4).SetListenPort(gSecuredServicePort)
 #endif
 #if CONFIG_NETWORK_LAYER_BLE
-                               ,
-                           BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer())
+            ,
+        BleListenParameters(DeviceLayer::ConnectivityMgr().GetBleLayer())
 #endif
     );
 
@@ -403,8 +413,13 @@ void InitServer(AppDelegate * delegate)
 #endif
     }
 
+#if CHIP_DEVICE_CONFIG_ENABLE_MDNS
+    app::Mdns::SetSecuredPort(gSecuredServicePort);
+    app::Mdns::SetUnsecuredPort(gUnsecuredServicePort);
+#endif // CHIP_DEVICE_CONFIG_ENABLE_MDNS
 // ESP32 and Mbed OS examples have a custom logic for enabling DNS-SD
 #if CHIP_DEVICE_CONFIG_ENABLE_MDNS && !CHIP_DEVICE_LAYER_TARGET_ESP32 && !CHIP_DEVICE_LAYER_TARGET_MBED
+    // StartServer only enables commissioning mode if device has not been commissioned
     app::Mdns::StartServer();
 #endif
 

+ 14 - 0
src/app/server/Server.h

@@ -27,6 +27,12 @@
 #include <transport/raw/BLE.h>
 #include <transport/raw/UDP.h>
 
+struct ServerConfigParams
+{
+    uint16_t securedServicePort   = CHIP_PORT;
+    uint16_t unsecuredServicePort = CHIP_UDC_PORT;
+};
+
 constexpr size_t kMaxBlePendingPackets = 1;
 
 using DemoTransportMgr = chip::TransportMgr<chip::Transport::UDP
@@ -39,6 +45,14 @@ using DemoTransportMgr = chip::TransportMgr<chip::Transport::UDP
                                             chip::Transport::BLE<kMaxBlePendingPackets>
 #endif
                                             >;
+/**
+ * Currently, this method must be called BEFORE InitServer.
+ * In the future, it would be nice to be able to call it
+ * at any time but that requires handling for changes to every
+ * field on ServerConfigParams (restarting port listener, etc).
+ *
+ */
+void SetServerConfig(ServerConfigParams params);
 
 /**
  * Initialize DataModelHandler and start CHIP datamodel server, the server

+ 1 - 1
src/controller/CHIPDeviceController.h

@@ -618,7 +618,7 @@ private:
     UserDirectedCommissioningServer * mUdcServer = nullptr;
     // mUdcTransportMgr is for insecure communication (ex. user directed commissioning)
     DeviceTransportMgr * mUdcTransportMgr = nullptr;
-    uint16_t mUdcListenPort               = CHIP_PORT + 1;
+    uint16_t mUdcListenPort               = CHIP_UDC_PORT;
 #endif // CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
 
     void PersistDeviceList();

+ 11 - 0
src/lib/core/CHIPConfig.h

@@ -1340,6 +1340,17 @@
 #define CHIP_PORT 5540
 #endif // CHIP_PORT
 
+/**
+ *  @def CHIP_UDC_PORT
+ *
+ *  @brief
+ *    chip TCP/UDP port for unsecured user-directed-commissioning traffic.
+ *
+ */
+#ifndef CHIP_UDC_PORT
+#define CHIP_UDC_PORT CHIP_PORT + 10
+#endif // CHIP_UDC_PORT
+
 /**
  *  @def CHIP_UNSECURED_PORT
  *

+ 34 - 28
src/lib/mdns/Advertiser.h

@@ -41,26 +41,27 @@ static constexpr size_t kTxtRetryIntervalActiveMaxLength = 7; // [CRA] 0-3600000
 static constexpr size_t kMaxRetryInterval                = 3600000;
 
 // Commissionable/commissioner node TXT entries
-static constexpr size_t kKeyDiscriminatorMaxLength      = 5;
-static constexpr size_t kKeyVendorProductMaxLength      = 11;
-static constexpr size_t kKeyAdditionalPairingMaxLength  = 1;
-static constexpr size_t kKeyCommissioningModeMaxLength  = 1;
-static constexpr size_t kKeyDeviceTypeMaxLength         = 5;
-static constexpr size_t kKeyDeviceNameMaxLength         = 32;
-static constexpr size_t kKeyRotatingIdMaxLength         = 100;
-static constexpr size_t kKeyPairingInstructionMaxLength = 128;
-static constexpr size_t kKeyPairingHintMaxLength        = 10;
+static constexpr size_t kKeyDiscriminatorMaxLength           = 5;
+static constexpr size_t kKeyVendorProductMaxLength           = 11;
+static constexpr size_t kKeyAdditionalCommissioningMaxLength = 1;
+static constexpr size_t kKeyCommissioningModeMaxLength       = 1;
+static constexpr size_t kKeyDeviceTypeMaxLength              = 5;
+static constexpr size_t kKeyDeviceNameMaxLength              = 32;
+static constexpr size_t kKeyRotatingIdMaxLength              = 100;
+static constexpr size_t kKeyPairingInstructionMaxLength      = 128;
+static constexpr size_t kKeyPairingHintMaxLength             = 10;
 
 // Commissionable/commissioner node subtypes
-static constexpr size_t kSubTypeShortDiscriminatorMaxLength = 4; // _S<dd>
-static constexpr size_t kSubTypeLongDiscriminatorMaxLength  = 6; // _L<dddd>
-static constexpr size_t kSubTypeVendorMaxLength             = 7; // _V<ddddd>
-static constexpr size_t kSubTypeDeviceTypeMaxLength         = 5; // _T<ddd>
-static constexpr size_t kSubTypeCommissioningModeMaxLength  = 3; // _C<d>
-static constexpr size_t kSubTypeAdditionalPairingMaxLength  = 3; // _A<d>
-static constexpr size_t kSubTypeMaxNumber                   = 6;
+static constexpr size_t kSubTypeShortDiscriminatorMaxLength      = 4; // _S<dd>
+static constexpr size_t kSubTypeLongDiscriminatorMaxLength       = 6; // _L<dddd>
+static constexpr size_t kSubTypeVendorMaxLength                  = 7; // _V<ddddd>
+static constexpr size_t kSubTypeDeviceTypeMaxLength              = 5; // _T<ddd>
+static constexpr size_t kSubTypeCommissioningModeMaxLength       = 3; // _C<d>
+static constexpr size_t kSubTypeAdditionalCommissioningMaxLength = 3; // _A<d>
+static constexpr size_t kSubTypeMaxNumber                        = 6;
 static constexpr size_t kSubTypeTotalLength = kSubTypeShortDiscriminatorMaxLength + kSubTypeLongDiscriminatorMaxLength +
-    kSubTypeVendorMaxLength + kSubTypeDeviceTypeMaxLength + kSubTypeCommissioningModeMaxLength + kSubTypeAdditionalPairingMaxLength;
+    kSubTypeVendorMaxLength + kSubTypeDeviceTypeMaxLength + kSubTypeCommissioningModeMaxLength +
+    kSubTypeAdditionalCommissioningMaxLength;
 
 enum class CommssionAdvertiseMode : uint8_t
 {
@@ -142,12 +143,12 @@ public:
     static constexpr uint8_t kTxtMaxNumber  = 9;
     static constexpr uint8_t kTxtMaxKeySize = MaxStringLength("D", "VP", "CM", "DT", "DN", "RI", "PI", "PH"); // possible keys
     static constexpr uint8_t kTxtMaxValueSize =
-        std::max({ kKeyDiscriminatorMaxLength, kKeyVendorProductMaxLength, kKeyAdditionalPairingMaxLength,
+        std::max({ kKeyDiscriminatorMaxLength, kKeyVendorProductMaxLength, kKeyAdditionalCommissioningMaxLength,
                    kKeyCommissioningModeMaxLength, kKeyDeviceTypeMaxLength, kKeyDeviceNameMaxLength, kKeyRotatingIdMaxLength,
                    kKeyPairingInstructionMaxLength, kKeyPairingHintMaxLength });
     static constexpr size_t kTxtTotalKeySize   = TotalStringLength("D", "VP", "CM", "DT", "DN", "RI", "PI", "PH"); // possible keys
     static constexpr size_t kTxtTotalValueSize = kKeyDiscriminatorMaxLength + kKeyVendorProductMaxLength +
-        kKeyAdditionalPairingMaxLength + kKeyCommissioningModeMaxLength + kKeyDeviceTypeMaxLength + kKeyDeviceNameMaxLength +
+        kKeyAdditionalCommissioningMaxLength + kKeyCommissioningModeMaxLength + kKeyDeviceTypeMaxLength + kKeyDeviceNameMaxLength +
         kKeyRotatingIdMaxLength + kKeyPairingInstructionMaxLength + kKeyPairingHintMaxLength;
 
     CommissionAdvertisingParameters & SetShortDiscriminator(uint8_t discriminator)
@@ -178,14 +179,19 @@ public:
     }
     Optional<uint16_t> GetProductId() const { return mProductId; }
 
-    CommissionAdvertisingParameters & SetCommissioningMode(bool modeEnabled, bool openWindow)
+    CommissionAdvertisingParameters & SetCommissioningMode(bool modeEnabled)
     {
-        mCommissioningModeEnabled    = modeEnabled;
-        mOpenWindowCommissioningMode = openWindow;
+        mCommissioningModeEnabled = modeEnabled;
         return *this;
     }
     bool GetCommissioningMode() const { return mCommissioningModeEnabled; }
-    bool GetOpenWindowCommissioningMode() const { return mOpenWindowCommissioningMode; }
+
+    CommissionAdvertisingParameters & SetAdditionalCommissioning(bool additionalCommissioningEnabled)
+    {
+        mAdditionalCommissioningEnabled = additionalCommissioningEnabled;
+        return *this;
+    }
+    bool GetAdditionalCommissioning() const { return mAdditionalCommissioningEnabled; }
 
     CommissionAdvertisingParameters & SetDeviceType(Optional<uint16_t> deviceType)
     {
@@ -263,11 +269,11 @@ public:
     CommssionAdvertiseMode GetCommissionAdvertiseMode() const { return mMode; }
 
 private:
-    uint8_t mShortDiscriminator       = 0;
-    uint16_t mLongDiscriminator       = 0; // 12-bit according to spec
-    CommssionAdvertiseMode mMode      = CommssionAdvertiseMode::kCommissionableNode;
-    bool mCommissioningModeEnabled    = false;
-    bool mOpenWindowCommissioningMode = false;
+    uint8_t mShortDiscriminator          = 0;
+    uint16_t mLongDiscriminator          = 0; // 12-bit according to spec
+    CommssionAdvertiseMode mMode         = CommssionAdvertiseMode::kCommissionableNode;
+    bool mCommissioningModeEnabled       = false;
+    bool mAdditionalCommissioningEnabled = false;
     chip::Optional<uint16_t> mVendorId;
     chip::Optional<uint16_t> mProductId;
     chip::Optional<uint16_t> mDeviceType;

+ 5 - 5
src/lib/mdns/Advertiser_ImplMinimalMdns.cpp

@@ -502,7 +502,7 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters &
             }
         }
 
-        if (params.GetCommissioningMode() && params.GetOpenWindowCommissioningMode())
+        if (params.GetCommissioningMode() && params.GetAdditionalCommissioning())
         {
             MakeServiceSubtype(nameBuffer, sizeof(nameBuffer),
                                DiscoveryFilter(DiscoveryFilterType::kCommissioningModeFromCommand, 1));
@@ -589,11 +589,11 @@ FullQName AdvertiserMinMdns::GetCommisioningTextEntries(const CommissionAdvertis
         snprintf(txtCommissioningMode, sizeof(txtCommissioningMode), "CM=%d", params.GetCommissioningMode() ? 1 : 0);
         txtFields[numTxtFields++] = txtCommissioningMode;
 
-        char txtOpenWindowCommissioningMode[chip::Mdns::kKeyAdditionalPairingMaxLength + 4];
-        if (params.GetCommissioningMode() && params.GetOpenWindowCommissioningMode())
+        char txtAdditionalCommissioning[chip::Mdns::kKeyAdditionalCommissioningMaxLength + 4];
+        if (params.GetCommissioningMode() && params.GetAdditionalCommissioning())
         {
-            snprintf(txtOpenWindowCommissioningMode, sizeof(txtOpenWindowCommissioningMode), "AP=1");
-            txtFields[numTxtFields++] = txtOpenWindowCommissioningMode;
+            snprintf(txtAdditionalCommissioning, sizeof(txtAdditionalCommissioning), "AP=1");
+            txtFields[numTxtFields++] = txtAdditionalCommissioning;
         }
 
         char txtRotatingDeviceId[chip::Mdns::kKeyRotatingIdMaxLength + 4];

+ 11 - 11
src/lib/mdns/Discovery_ImplPlatform.cpp

@@ -126,7 +126,7 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter
     char discriminatorBuf[kKeyDiscriminatorMaxLength + 1];
     char vendorProductBuf[kKeyVendorProductMaxLength + 1];
     char commissioningModeBuf[kKeyCommissioningModeMaxLength + 1];
-    char additionalPairingBuf[kKeyAdditionalPairingMaxLength + 1];
+    char additionalCommissioningingBuf[kKeyAdditionalCommissioningMaxLength + 1];
     char deviceTypeBuf[kKeyDeviceTypeMaxLength + 1];
     char deviceNameBuf[kKeyDeviceNameMaxLength + 1];
     char rotatingIdBuf[kKeyRotatingIdMaxLength + 1];
@@ -140,7 +140,7 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter
     char longDiscriminatorSubtype[kSubTypeLongDiscriminatorMaxLength + 1];
     char vendorSubType[kSubTypeVendorMaxLength + 1];
     char commissioningModeSubType[kSubTypeCommissioningModeMaxLength + 1];
-    char openWindowSubType[kSubTypeAdditionalPairingMaxLength + 1];
+    char additionalCommissioningSubType[kSubTypeAdditionalCommissioningMaxLength + 1];
     char deviceTypeSubType[kSubTypeDeviceTypeMaxLength + 1];
     // size of subTypes array should be count of SubTypes above
     const char * subTypes[kSubTypeMaxNumber];
@@ -210,11 +210,11 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter
         textEntries[textEntrySize++] = { "CM", reinterpret_cast<const uint8_t *>(commissioningModeBuf),
                                          strnlen(commissioningModeBuf, sizeof(commissioningModeBuf)) };
 
-        if (params.GetCommissioningMode() && params.GetOpenWindowCommissioningMode())
+        if (params.GetCommissioningMode() && params.GetAdditionalCommissioning())
         {
-            snprintf(additionalPairingBuf, sizeof(additionalPairingBuf), "1");
-            textEntries[textEntrySize++] = { "AP", reinterpret_cast<const uint8_t *>(additionalPairingBuf),
-                                             strnlen(additionalPairingBuf, sizeof(additionalPairingBuf)) };
+            snprintf(additionalCommissioningingBuf, sizeof(additionalCommissioningingBuf), "1");
+            textEntries[textEntrySize++] = { "AP", reinterpret_cast<const uint8_t *>(additionalCommissioningingBuf),
+                                             strnlen(additionalCommissioningingBuf, sizeof(additionalCommissioningingBuf)) };
         }
 
         if (params.GetRotatingId().HasValue())
@@ -254,12 +254,12 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter
         {
             subTypes[subTypeSize++] = commissioningModeSubType;
         }
-        if (params.GetCommissioningMode() && params.GetOpenWindowCommissioningMode())
+        if (params.GetCommissioningMode() && params.GetAdditionalCommissioning())
         {
-            if (MakeServiceSubtype(openWindowSubType, sizeof(openWindowSubType),
+            if (MakeServiceSubtype(additionalCommissioningSubType, sizeof(additionalCommissioningSubType),
                                    DiscoveryFilter(DiscoveryFilterType::kCommissioningModeFromCommand, 1)) == CHIP_NO_ERROR)
             {
-                subTypes[subTypeSize++] = openWindowSubType;
+                subTypes[subTypeSize++] = additionalCommissioningSubType;
             }
         }
     }
@@ -283,7 +283,7 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const CommissionAdvertisingParameter
 
     service.mTextEntries   = textEntries;
     service.mTextEntrySize = textEntrySize;
-    service.mPort          = CHIP_PORT;
+    service.mPort          = params.GetPort();
     service.mInterface     = INET_NULL_INTERFACEID;
     service.mSubTypes      = subTypes;
     service.mSubTypeSize   = subTypeSize;
@@ -398,7 +398,7 @@ CHIP_ERROR DiscoveryImplPlatform::Advertise(const OperationalAdvertisingParamete
     ReturnErrorOnFailure(MakeInstanceName(service.mName, sizeof(service.mName), params.GetPeerId()));
     strncpy(service.mType, kOperationalServiceName, sizeof(service.mType));
     service.mProtocol      = MdnsServiceProtocol::kMdnsProtocolTcp;
-    service.mPort          = CHIP_PORT;
+    service.mPort          = params.GetPort();
     service.mTextEntries   = mrpRetryIntervalEntries;
     service.mTextEntrySize = textEntrySize;
     service.mInterface     = INET_NULL_INTERFACEID;

+ 4 - 2
src/lib/mdns/minimal/tests/TestAdvertiser.cpp

@@ -130,7 +130,8 @@ CommissionAdvertisingParameters commissionableNodeParamsSmall =
         .SetMac(ByteSpan(kMac))
         .SetLongDiscriminator(0xFFE)
         .SetShortDiscriminator(0xF)
-        .SetCommissioningMode(false, false);
+        .SetCommissioningMode(false)
+        .SetAdditionalCommissioning(false);
 const QNamePart txtCommissionableNodeParamsSmallParts[] = { "CM=0", "D=4094" };
 FullQName txtCommissionableNodeParamsSmallName          = FullQName(txtCommissionableNodeParamsSmallParts);
 TxtResourceRecord txtCommissionableNodeParamsSmall      = TxtResourceRecord(instanceName, txtCommissionableNodeParamsSmallName);
@@ -143,7 +144,8 @@ CommissionAdvertisingParameters commissionableNodeParamsLarge =
         .SetShortDiscriminator(2)
         .SetVendorId(chip::Optional<uint16_t>(555))
         .SetDeviceType(chip::Optional<uint16_t>(25))
-        .SetCommissioningMode(true, true)
+        .SetCommissioningMode(true)
+        .SetAdditionalCommissioning(true)
         .SetDeviceName(chip::Optional<const char *>("testy-test"))
         .SetPairingHint(chip::Optional<uint16_t>(3))
         .SetPairingInstr(chip::Optional<const char *>("Pair me"))