DeviceScanner.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Copyright (c) 2023 Project CHIP Authors
  3. * All rights reserved.
  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 "DeviceScanner.h"
  19. using namespace chip;
  20. using namespace chip::Dnssd;
  21. #if CONFIG_NETWORK_LAYER_BLE
  22. using namespace chip::Ble;
  23. constexpr const char * kBleKey = "BLE";
  24. #endif // CONFIG_NETWORK_LAYER_BLE
  25. CHIP_ERROR DeviceScanner::Start()
  26. {
  27. mDiscoveredResults.clear();
  28. #if CONFIG_NETWORK_LAYER_BLE
  29. ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().StartBleScan(this));
  30. #endif // CONFIG_NETWORK_LAYER_BLE
  31. ReturnErrorOnFailure(chip::Dnssd::Resolver::Instance().Init(DeviceLayer::UDPEndPointManager()));
  32. char serviceName[kMaxCommissionableServiceNameSize];
  33. auto filter = DiscoveryFilterType::kNone;
  34. ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode));
  35. return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
  36. Inet::InterfaceId::Null(), this);
  37. }
  38. CHIP_ERROR DeviceScanner::Stop()
  39. {
  40. #if CONFIG_NETWORK_LAYER_BLE
  41. ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().StopBleScan());
  42. #endif // CONFIG_NETWORK_LAYER_BLE
  43. return ChipDnssdStopBrowse(this);
  44. }
  45. void DeviceScanner::OnNodeDiscovered(const DiscoveredNodeData & nodeData)
  46. {
  47. auto & commissionData = nodeData.commissionData;
  48. auto discriminator = commissionData.longDiscriminator;
  49. auto vendorId = static_cast<VendorId>(commissionData.vendorId);
  50. auto productId = commissionData.productId;
  51. ChipLogProgress(chipTool, "OnNodeDiscovered (MDNS): discriminator: %u, vendorId: %u, productId: %u", discriminator, vendorId,
  52. productId);
  53. auto & resolutionData = nodeData.resolutionData;
  54. auto & instanceData = mDiscoveredResults[commissionData.instanceName];
  55. auto & interfaceData = instanceData[resolutionData.interfaceId.GetPlatformInterface()];
  56. for (size_t i = 0; i < resolutionData.numIPs; i++)
  57. {
  58. auto params = Controller::SetUpCodePairerParameters(resolutionData, i);
  59. DeviceScannerResult result = { params, vendorId, productId, discriminator, chip::MakeOptional(resolutionData) };
  60. interfaceData.push_back(result);
  61. }
  62. nodeData.LogDetail();
  63. }
  64. void DeviceScanner::OnBrowseAdd(chip::Dnssd::DnssdService service)
  65. {
  66. ChipLogProgress(chipTool, "OnBrowseAdd: %s", service.mName);
  67. LogErrorOnFailure(ChipDnssdResolve(&service, service.mInterface, this));
  68. auto & instanceData = mDiscoveredResults[service.mName];
  69. auto & interfaceData = instanceData[service.mInterface.GetPlatformInterface()];
  70. (void) interfaceData;
  71. }
  72. void DeviceScanner::OnBrowseRemove(chip::Dnssd::DnssdService service)
  73. {
  74. ChipLogProgress(chipTool, "OnBrowseRemove: %s", service.mName);
  75. auto & instanceData = mDiscoveredResults[service.mName];
  76. auto & interfaceData = instanceData[service.mInterface.GetPlatformInterface()];
  77. // Check if the interface data has been resolved already, otherwise, just inform the
  78. // back end that we may not need it anymore.
  79. if (interfaceData.size() == 0)
  80. {
  81. ChipDnssdResolveNoLongerNeeded(service.mName);
  82. }
  83. // Delete the interface placeholder.
  84. instanceData.erase(service.mInterface.GetPlatformInterface());
  85. // If there is nothing else to resolve for the given instance name, just remove it
  86. // too.
  87. if (instanceData.size() == 0)
  88. {
  89. mDiscoveredResults.erase(service.mName);
  90. }
  91. }
  92. void DeviceScanner::OnBrowseStop(CHIP_ERROR error)
  93. {
  94. ChipLogProgress(chipTool, "OnBrowseStop: %" CHIP_ERROR_FORMAT, error.Format());
  95. for (auto & instance : mDiscoveredResults)
  96. {
  97. for (auto & interface : instance.second)
  98. {
  99. if (interface.second.size() == 0)
  100. {
  101. ChipDnssdResolveNoLongerNeeded(instance.first.c_str());
  102. }
  103. }
  104. }
  105. }
  106. #if CONFIG_NETWORK_LAYER_BLE
  107. void DeviceScanner::OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificationInfo & info)
  108. {
  109. auto discriminator = info.GetDeviceDiscriminator();
  110. auto vendorId = static_cast<VendorId>(info.GetVendorId());
  111. auto productId = info.GetProductId();
  112. ChipLogProgress(chipTool, "OnBleScanAdd (BLE): %p, discriminator: %u, vendorId: %u, productId: %u", connObj, discriminator,
  113. vendorId, productId);
  114. auto params = Controller::SetUpCodePairerParameters(connObj, false /* connected */);
  115. DeviceScannerResult result = { params, vendorId, productId, discriminator };
  116. auto & instanceData = mDiscoveredResults[kBleKey];
  117. auto & interfaceData = instanceData[chip::Inet::InterfaceId::Null().GetPlatformInterface()];
  118. interfaceData.push_back(result);
  119. }
  120. void DeviceScanner::OnBleScanRemove(BLE_CONNECTION_OBJECT connObj)
  121. {
  122. ChipLogProgress(chipTool, "OnBleScanRemove: %p", connObj);
  123. auto & instanceData = mDiscoveredResults[kBleKey];
  124. auto & interfaceData = instanceData[chip::Inet::InterfaceId::Null().GetPlatformInterface()];
  125. interfaceData.erase(std::remove_if(interfaceData.begin(), interfaceData.end(),
  126. [connObj](const DeviceScannerResult & result) {
  127. return result.mParams.HasDiscoveredObject() &&
  128. result.mParams.GetDiscoveredObject() == connObj;
  129. }),
  130. interfaceData.end());
  131. if (interfaceData.size() == 0)
  132. {
  133. instanceData.clear();
  134. mDiscoveredResults.erase(kBleKey);
  135. }
  136. }
  137. #endif // CONFIG_NETWORK_LAYER_BLE
  138. CHIP_ERROR DeviceScanner::Get(uint16_t index, RendezvousParameters & params)
  139. {
  140. uint16_t currentIndex = 0;
  141. for (auto & instance : mDiscoveredResults)
  142. {
  143. for (auto & interface : instance.second)
  144. {
  145. for (auto & result : interface.second)
  146. {
  147. if (currentIndex == index)
  148. {
  149. params = result.mParams;
  150. return CHIP_NO_ERROR;
  151. }
  152. currentIndex++;
  153. }
  154. }
  155. }
  156. return CHIP_ERROR_NOT_FOUND;
  157. }
  158. CHIP_ERROR DeviceScanner::Get(uint16_t index, Dnssd::CommonResolutionData & resolutionData)
  159. {
  160. uint16_t currentIndex = 0;
  161. for (auto & instance : mDiscoveredResults)
  162. {
  163. for (auto & interface : instance.second)
  164. {
  165. for (auto & result : interface.second)
  166. {
  167. if (currentIndex == index && result.mResolutionData.HasValue())
  168. {
  169. resolutionData = result.mResolutionData.Value();
  170. return CHIP_NO_ERROR;
  171. }
  172. currentIndex++;
  173. }
  174. }
  175. }
  176. return CHIP_ERROR_NOT_FOUND;
  177. }
  178. void DeviceScanner::Log() const
  179. {
  180. auto resultsCount = mDiscoveredResults.size();
  181. VerifyOrReturn(resultsCount > 0, ChipLogProgress(chipTool, "No device discovered."));
  182. uint16_t index = 0;
  183. for (auto & instance : mDiscoveredResults)
  184. {
  185. ChipLogProgress(chipTool, "Instance Name: %s ", instance.first.c_str());
  186. for (auto & interface : instance.second)
  187. {
  188. for (auto & result : interface.second)
  189. {
  190. char addr[Transport::PeerAddress::kMaxToStringSize];
  191. result.mParams.GetPeerAddress().ToString(addr);
  192. ChipLogProgress(chipTool, "\t %u - Discriminator: %u - Vendor: %u - Product: %u - %s", index, result.mDiscriminator,
  193. result.mVendorId, result.mProductId, addr);
  194. index++;
  195. }
  196. }
  197. }
  198. }
  199. DeviceScanner & GetDeviceScanner()
  200. {
  201. static DeviceScanner scanner;
  202. return scanner;
  203. }