react-native-zeroconf 0.15.2 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +27 -536
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/com/balthazargronon/RCTZeroconf/Zeroconf.java +16 -4
  4. package/android/src/main/java/com/balthazargronon/RCTZeroconf/ZeroconfModule.java +95 -13
  5. package/android/src/main/java/com/balthazargronon/RCTZeroconf/nsd/NsdServiceImpl.java +184 -64
  6. package/android/src/main/java/com/balthazargronon/RCTZeroconf/nsd/ServiceInfoCallbacks.java +89 -0
  7. package/android/src/main/java/com/balthazargronon/RCTZeroconf/rx2dnssd/DnssdImpl.java +114 -39
  8. package/android/src/main/jni/Android.mk +1 -24
  9. package/android/src/main/jni/Application.mk +1 -1
  10. package/dist/index.js +244 -27
  11. package/index.d.ts +95 -9
  12. package/ios/RNZeroconf/RNNetServiceSerializer.h +10 -2
  13. package/ios/RNZeroconf/RNNetServiceSerializer.m +51 -59
  14. package/ios/RNZeroconf/RNZeroconf.h +1 -3
  15. package/ios/RNZeroconf/RNZeroconf.m +642 -175
  16. package/package.json +39 -1
  17. package/react-native-zeroconf.podspec +12 -6
  18. package/src/index.js +222 -31
  19. package/android/src/main/java/com/github/druk/dnssd/DNSSDBindable.java +0 -67
  20. package/android/src/main/java/com/github/druk/rx2dnssd/Rx2DnssdBindable.java +0 -35
  21. package/android/src/main/jni/mdnsresponder/Android.bp +0 -215
  22. package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.c +0 -75
  23. package/android/src/main/jni/mdnsresponder/Clients/ClientCommon.h +0 -41
  24. package/android/src/main/jni/mdnsresponder/Clients/Makefile +0 -54
  25. package/android/src/main/jni/mdnsresponder/Clients/ReadMe.txt +0 -25
  26. package/android/src/main/jni/mdnsresponder/Clients/dns-sd.c +0 -1351
  27. package/android/src/main/jni/mdnsresponder/Makefile +0 -41
  28. package/android/src/main/jni/mdnsresponder/PrivateDNS.txt +0 -275
  29. package/android/src/main/jni/mdnsresponder/android/caseMapping/Iphlpapi.h +0 -1
  30. package/android/src/main/jni/mdnsresponder/android/caseMapping/README +0 -3
  31. package/android/src/main/jni/mdnsresponder/android/caseMapping/Resource.h +0 -1
  32. package/android/src/main/jni/mdnsresponder/android/caseMapping/Ws2tcpip.h +0 -1
  33. package/android/src/main/jni/mdnsresponder/android/caseMapping/ipExport.h +0 -1
  34. package/android/src/main/jni/mdnsresponder/android/windows_firewall_dummy.c +0 -10
  35. package/android/src/main/jni/mdnsresponder/mDNSCore/Implementer Notes.txt +0 -66
  36. package/android/src/main/jni/mdnsresponder/mDNSPosix/Client.c +0 -223
  37. package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.c +0 -91
  38. package/android/src/main/jni/mdnsresponder/mDNSPosix/ExampleClientApp.h +0 -18
  39. package/android/src/main/jni/mdnsresponder/mDNSPosix/Identify.c +0 -378
  40. package/android/src/main/jni/mdnsresponder/mDNSPosix/Makefile +0 -520
  41. package/android/src/main/jni/mdnsresponder/mDNSPosix/NetMonitor.c +0 -1010
  42. package/android/src/main/jni/mdnsresponder/mDNSPosix/ProxyResponder.c +0 -300
  43. package/android/src/main/jni/mdnsresponder/mDNSPosix/ReadMe.txt +0 -314
  44. package/android/src/main/jni/mdnsresponder/mDNSPosix/Responder.c +0 -792
  45. package/android/src/main/jni/mdnsresponder/mDNSPosix/Services.txt +0 -36
  46. package/android/src/main/jni/mdnsresponder/mDNSPosix/libnss_mdns.8 +0 -148
  47. package/android/src/main/jni/mdnsresponder/mDNSPosix/mdnsd.sh +0 -73
  48. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_ReadMe.txt +0 -125
  49. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.c +0 -2723
  50. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf +0 -13
  51. package/android/src/main/jni/mdnsresponder/mDNSPosix/nss_mdns.conf.5 +0 -135
  52. package/android/src/main/jni/mdnsresponder/mDNSPosix/parselog.py +0 -247
  53. package/android/src/main/jni/mdnsresponder/mDNSResponder.sln +0 -400
  54. package/android/src/main/jni/mdnsresponder/mDNSShared/DebugServices.c +0 -3075
  55. package/android/src/main/jni/mdnsresponder/mDNSShared/dns-sd.1 +0 -194
  56. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.8 +0 -69
  57. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.c +0 -3146
  58. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd.conf +0 -60
  59. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_lexer.l +0 -84
  60. package/android/src/main/jni/mdnsresponder/mDNSShared/dnsextd_parser.y +0 -585
  61. package/android/src/main/jni/mdnsresponder/mDNSShared/mDNS.1 +0 -198
  62. package/android/src/main/jni/mdnsresponder/mDNSShared/mDNSResponder.8 +0 -116
  63. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.cpp +0 -441
  64. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/BrowsingPage.h +0 -156
  65. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.cpp +0 -59
  66. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigDialog.h +0 -48
  67. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.cpp +0 -301
  68. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ConfigPropertySheet.h +0 -105
  69. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.cpp +0 -380
  70. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.def +0 -20
  71. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.h +0 -84
  72. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.rc +0 -141
  73. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanel.vcproj +0 -727
  74. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelDll.rc +0 -123
  75. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.cpp +0 -373
  76. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.h +0 -48
  77. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.rc +0 -123
  78. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelExe.vcproj +0 -764
  79. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.rc +0 -270
  80. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelLocRes.vcproj +0 -487
  81. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.rc +0 -134
  82. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ControlPanelRes.vcproj +0 -518
  83. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.cpp +0 -197
  84. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/FourthPage.h +0 -87
  85. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.cpp +0 -387
  86. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/RegistrationPage.h +0 -75
  87. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.cpp +0 -544
  88. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SecondPage.h +0 -107
  89. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.cpp +0 -273
  90. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/ServicesPage.h +0 -123
  91. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.cpp +0 -115
  92. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/SharedSecret.h +0 -54
  93. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.dll.manifest +0 -10
  94. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.exe.manifest +0 -17
  95. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.manifest +0 -17
  96. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel.rc2 +0 -13
  97. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/ControlPanel64.manifest +0 -17
  98. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/EnergySaver.ico +0 -0
  99. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/controlpanel.ico +0 -0
  100. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/failure.ico +0 -0
  101. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/res/success.ico +0 -0
  102. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/resource.h +0 -56
  103. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.cpp +0 -20
  104. package/android/src/main/jni/mdnsresponder/mDNSWindows/ControlPanel/stdafx.h +0 -64
  105. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.aps +0 -0
  106. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dll.rc +0 -102
  107. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dllmain.c +0 -112
  108. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.def +0 -48
  109. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/dnssd.vcproj +0 -472
  110. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL/resource.h +0 -27
  111. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/AssemblyInfo.cpp +0 -84
  112. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/PString.h +0 -70
  113. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.cpp +0 -22
  114. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/Stdafx.h +0 -33
  115. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.cpp +0 -1234
  116. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.h +0 -1392
  117. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.ico +0 -0
  118. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.rc +0 -113
  119. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/dnssd_NET.vcproj +0 -446
  120. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLL.NET/resource.h +0 -3
  121. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.cpp +0 -693
  122. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.h +0 -52
  123. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLStub/DLLStub.vcproj +0 -324
  124. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.cpp +0 -208
  125. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.def +0 -35
  126. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.idl +0 -491
  127. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rc +0 -126
  128. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.rgs +0 -11
  129. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DLLX.vcproj +0 -625
  130. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSD.cpp +0 -892
  131. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.cpp +0 -31
  132. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.h +0 -133
  133. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDEventManager.rgs +0 -27
  134. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.cpp +0 -101
  135. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.h +0 -185
  136. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDRecord.rgs +0 -27
  137. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.cpp +0 -2095
  138. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.h +0 -429
  139. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/DNSSDService.rgs +0 -27
  140. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.cpp +0 -344
  141. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/StringServices.h +0 -102
  142. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.cpp +0 -381
  143. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.h +0 -203
  144. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/TXTRecord.rgs +0 -27
  145. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/_IDNSSDEvents_CP.h +0 -358
  146. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.c +0 -51
  147. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/dlldatax.h +0 -49
  148. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/resource.h +0 -30
  149. package/android/src/main/jni/mdnsresponder/mDNSWindows/DLLX/stdafx.h +0 -88
  150. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.sln +0 -21
  151. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2002.vcproj +0 -253
  152. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.sln +0 -21
  153. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/ApplicationVS2003.vcproj +0 -267
  154. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.ico +0 -0
  155. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc +0 -323
  156. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Application.rc2 +0 -20
  157. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Resources/Resource.h +0 -53
  158. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.cpp +0 -71
  159. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/AboutDialog.h +0 -62
  160. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.cpp +0 -111
  161. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/Application.h +0 -68
  162. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.cpp +0 -1426
  163. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/ChooserDialog.h +0 -131
  164. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.cpp +0 -109
  165. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/LoginDialog.h +0 -53
  166. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.cpp +0 -18
  167. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/Windows/Sources/StdAfx.h +0 -48
  168. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcc +0 -37
  169. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcp +0 -868
  170. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Application.vcw +0 -29
  171. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.ico +0 -0
  172. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc +0 -194
  173. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/Application.rc2 +0 -13
  174. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/newres.h +0 -28
  175. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Resources/resource.h +0 -22
  176. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.cpp +0 -92
  177. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/Application.h +0 -57
  178. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.cpp +0 -394
  179. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/BrowserDialog.h +0 -84
  180. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.cpp +0 -18
  181. package/android/src/main/jni/mdnsresponder/mDNSWindows/DNSServiceBrowser/WindowsCE/Sources/StdAfx.h +0 -46
  182. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/Java.vcproj +0 -111
  183. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/jdns_sd.rc +0 -62
  184. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile +0 -143
  185. package/android/src/main/jni/mdnsresponder/mDNSWindows/Java/makefile64 +0 -143
  186. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.aps +0 -0
  187. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.c +0 -581
  188. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.rc +0 -103
  189. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/NSPTool.vcproj +0 -409
  190. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/Prefix.h +0 -28
  191. package/android/src/main/jni/mdnsresponder/mDNSWindows/NSPTool/resource.h +0 -27
  192. package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.c +0 -128
  193. package/android/src/main/jni/mdnsresponder/mDNSWindows/PosixCompat.h +0 -70
  194. package/android/src/main/jni/mdnsresponder/mDNSWindows/README.txt +0 -85
  195. package/android/src/main/jni/mdnsresponder/mDNSWindows/RegNames.h +0 -57
  196. package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.c +0 -338
  197. package/android/src/main/jni/mdnsresponder/mDNSWindows/Secret.h +0 -42
  198. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLog.mc +0 -11
  199. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/EventLogMessages.bin +0 -0
  200. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.cpp +0 -484
  201. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Firewall.h +0 -79
  202. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Prefix.h +0 -30
  203. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.aps +0 -0
  204. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.c +0 -2669
  205. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.h +0 -30
  206. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.mcp +0 -0
  207. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.rc +0 -114
  208. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/Service.vcproj +0 -562
  209. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/main.c +0 -32
  210. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder.manifest +0 -12
  211. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/res/mDNSResponder64.manifest +0 -12
  212. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resource.h +0 -17
  213. package/android/src/main/jni/mdnsresponder/mDNSWindows/SystemService/resrc1.h +0 -15
  214. package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.cpp +0 -165
  215. package/android/src/main/jni/mdnsresponder/mDNSWindows/VPCDetect.h +0 -36
  216. package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.cpp +0 -93
  217. package/android/src/main/jni/mdnsresponder/mDNSWindows/WinServices.h +0 -34
  218. package/android/src/main/jni/mdnsresponder/mDNSWindows/WinVersRes.h +0 -35
  219. package/android/src/main/jni/mdnsresponder/mDNSWindows/isocode.h +0 -135
  220. package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.c +0 -268
  221. package/android/src/main/jni/mdnsresponder/mDNSWindows/loclibrary.h +0 -54
  222. package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.c +0 -5200
  223. package/android/src/main/jni/mdnsresponder/mDNSWindows/mDNSWin32.h +0 -208
  224. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/ReadMe.txt +0 -15
  225. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.aps +0 -0
  226. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.c +0 -2430
  227. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.def +0 -24
  228. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.rc +0 -104
  229. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/mdnsNSP.vcproj +0 -457
  230. package/android/src/main/jni/mdnsresponder/mDNSWindows/mdnsNSP/resource.h +0 -27
  231. package/android/src/main/jni/mdnsresponder/mdnsd.rc +0 -7
@@ -8,61 +8,136 @@
8
8
 
9
9
  #import "RNZeroconf.h"
10
10
  #import "RNNetServiceSerializer.h"
11
+ #import <Network/Network.h>
12
+ #import <dns_sd.h>
13
+
14
+ // dns_sd callbacks are delivered on the main queue, and refs must be deallocated on it
15
+ #define RNZ_QUEUE dispatch_get_main_queue()
16
+
17
+ #pragma mark - State
18
+
19
+ @class RNZScan;
20
+
21
+ // A found service being resolved: DNSServiceResolve for host, port and TXT, then DNSServiceGetAddrInfo for addresses
22
+ @interface RNZResolve : NSObject
23
+ @property (nonatomic, weak) RNZeroconf *module;
24
+ @property (nonatomic, weak) RNZScan *scan;
25
+ @property (nonatomic, copy) NSString *name;
26
+ @property (nonatomic, copy) NSString *regtype;
27
+ @property (nonatomic, copy) NSString *domain;
28
+ @property (nonatomic, assign) DNSServiceRef resolveRef;
29
+ @property (nonatomic, assign) DNSServiceRef addressRef;
30
+ @property (nonatomic, copy) NSString *host;
31
+ @property (nonatomic, assign) uint16_t port;
32
+ @property (nonatomic, strong) NSDictionary *txt;
33
+ @property (nonatomic, strong) NSMutableOrderedSet<NSString *> *addresses;
34
+ @property (nonatomic, assign) BOOL retried;
35
+ @property (nonatomic, assign) BOOL finished;
36
+ @property (nonatomic, strong) dispatch_block_t timeoutBlock;
37
+ @property (nonatomic, strong) dispatch_block_t emitBlock;
38
+ @end
11
39
 
12
- @interface RNZeroconf ()
40
+ @implementation RNZResolve
41
+ @end
13
42
 
14
- @property (nonatomic, strong, readonly) NSMutableDictionary *resolvingServices;
15
- @property (nonatomic, strong, readonly) NSMutableDictionary *publishedServices;
16
- // Services already retried after a resolve timeout
17
- @property (nonatomic, strong, readonly) NSMutableSet<NSString *> *retriedServices;
18
- // Stopped browsers, kept alive until their asynchronous stop has been processed
19
- @property (nonatomic, strong, readonly) NSMutableSet<NSNetServiceBrowser *> *stoppingBrowsers;
43
+ // One browse, keyed by the id of the JS instance that started it, several can run at once
44
+ @interface RNZScan : NSObject
45
+ @property (nonatomic, weak) RNZeroconf *module;
46
+ @property (nonatomic, copy) NSString *scanId;
47
+ @property (nonatomic, assign) DNSServiceRef browseRef;
20
48
  @property (nonatomic, assign) NSTimeInterval resolveTimeoutSeconds;
49
+ // Services are reported once per network interface, count them so found/remove are emitted once
50
+ @property (nonatomic, strong) NSMutableDictionary<NSString *, NSNumber *> *foundInterfaces;
51
+ @property (nonatomic, strong) NSMutableDictionary<NSString *, RNZResolve *> *resolvingServices;
52
+ @end
21
53
 
54
+ @implementation RNZScan
22
55
  @end
23
56
 
24
- @implementation RNZeroconf
57
+ // A service registered with DNSServiceRegister
58
+ @interface RNZPublication : NSObject
59
+ @property (nonatomic, weak) RNZeroconf *module;
60
+ @property (nonatomic, copy) NSString *name;
61
+ @property (nonatomic, copy) NSString *regtype;
62
+ @property (nonatomic, copy) NSString *domain;
63
+ @property (nonatomic, assign) uint16_t port;
64
+ @property (nonatomic, strong) NSDictionary *txt;
65
+ @property (nonatomic, assign) DNSServiceRef ref;
66
+ @property (nonatomic, copy) RCTPromiseResolveBlock resolve;
67
+ @property (nonatomic, copy) RCTPromiseRejectBlock reject;
68
+ @end
25
69
 
26
- @synthesize bridge = _bridge;
70
+ @implementation RNZPublication
71
+ @end
27
72
 
28
- RCT_EXPORT_MODULE()
73
+ @interface RNZeroconf ()
74
+
75
+ @property (nonatomic, strong, readonly) NSMutableDictionary<NSString *, RNZScan *> *scans;
76
+ // Registered, keyed by the name actually used (it can differ from the requested one)
77
+ @property (nonatomic, strong, readonly) NSMutableDictionary<NSString *, RNZPublication *> *publishedServices;
78
+ // Waiting for the register callback
79
+ @property (nonatomic, strong, readonly) NSMutableSet<RNZPublication *> *pendingPublications;
29
80
 
30
- RCT_EXPORT_METHOD(scan:(NSString *)type protocol:(NSString *)protocol domain:(NSString *)domain)
81
+ - (void) handleBrowse:(RNZScan *)scan flags:(DNSServiceFlags)flags error:(DNSServiceErrorType)error name:(const char *)name regtype:(const char *)regtype domain:(const char *)domain;
82
+ - (void) handleResolve:(RNZResolve *)resolve error:(DNSServiceErrorType)error host:(const char *)host port:(uint16_t)port txtLength:(uint16_t)txtLength txt:(const unsigned char *)txt;
83
+ - (void) handleAddress:(RNZResolve *)resolve flags:(DNSServiceFlags)flags error:(DNSServiceErrorType)error address:(const struct sockaddr *)address;
84
+ - (void) handleRegister:(RNZPublication *)publication flags:(DNSServiceFlags)flags error:(DNSServiceErrorType)error name:(const char *)name;
85
+
86
+ @end
87
+
88
+ #pragma mark - dns_sd callbacks
89
+
90
+ static void RNZBrowseReply(DNSServiceRef ref, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType error,
91
+ const char *name, const char *regtype, const char *domain, void *context)
31
92
  {
32
- [self stop];
93
+ RNZScan *scan = (__bridge RNZScan *)context;
94
+ [scan.module handleBrowse:scan flags:flags error:error name:name regtype:regtype domain:domain];
95
+ }
33
96
 
34
- // A fresh browser for each scan, restarting a search on a browser that is still stopping can crash (#154)
35
- self.browser = [[NSNetServiceBrowser alloc] init];
36
- [self.browser setDelegate:self];
37
- [self.browser searchForServicesOfType:[NSString stringWithFormat:@"_%@._%@.", type, protocol] inDomain:domain];
97
+ static void RNZResolveReply(DNSServiceRef ref, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType error,
98
+ const char *fullName, const char *host, uint16_t port, uint16_t txtLength,
99
+ const unsigned char *txt, void *context)
100
+ {
101
+ RNZResolve *resolve = (__bridge RNZResolve *)context;
102
+ [resolve.module handleResolve:resolve error:error host:host port:ntohs(port) txtLength:txtLength txt:txt];
38
103
  }
39
104
 
40
- RCT_EXPORT_METHOD(stop)
105
+ static void RNZAddressReply(DNSServiceRef ref, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType error,
106
+ const char *host, const struct sockaddr *address, uint32_t ttl, void *context)
41
107
  {
42
- NSNetServiceBrowser *browser = self.browser;
43
- if (browser) {
44
- self.browser = nil;
45
- [self.stoppingBrowsers addObject:browser];
46
- [browser stop];
108
+ RNZResolve *resolve = (__bridge RNZResolve *)context;
109
+ [resolve.module handleAddress:resolve flags:flags error:error address:address];
110
+ }
47
111
 
48
- // The stop completes asynchronously on the run loop, release the browser well after it
49
- __weak RNZeroconf *weakSelf = self;
50
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
51
- browser.delegate = nil;
52
- [weakSelf.stoppingBrowsers removeObject:browser];
53
- });
54
- }
55
- for (NSNetService *service in self.resolvingServices.allValues) {
56
- service.delegate = nil;
57
- [service stop];
112
+ static void RNZRegisterReply(DNSServiceRef ref, DNSServiceFlags flags, DNSServiceErrorType error,
113
+ const char *name, const char *regtype, const char *domain, void *context)
114
+ {
115
+ RNZPublication *publication = (__bridge RNZPublication *)context;
116
+ [publication.module handleRegister:publication flags:flags error:error name:name];
117
+ }
118
+
119
+ // Deallocates on the next turn of the queue, for refs whose callback may currently be running.
120
+ // keepAlive keeps the callback context alive until then.
121
+ static void RNZDeallocateLater(DNSServiceRef ref, id keepAlive)
122
+ {
123
+ if (ref == NULL) {
124
+ return;
58
125
  }
59
- [self.resolvingServices removeAllObjects];
60
- [self.retriedServices removeAllObjects];
126
+ dispatch_async(RNZ_QUEUE, ^{
127
+ DNSServiceRefDeallocate(ref);
128
+ (void)keepAlive;
129
+ });
61
130
  }
62
131
 
132
+ @implementation RNZeroconf
133
+
134
+ @synthesize bridge = _bridge;
135
+
136
+ RCT_EXPORT_MODULE()
137
+
63
138
  - (dispatch_queue_t)methodQueue
64
139
  {
65
- return dispatch_get_main_queue();
140
+ return RNZ_QUEUE;
66
141
  }
67
142
 
68
143
  + (BOOL)requiresMainQueueSetup
@@ -70,226 +145,618 @@ RCT_EXPORT_METHOD(stop)
70
145
  return YES;
71
146
  }
72
147
 
73
- RCT_EXPORT_METHOD(registerService:(NSString *)type
74
- protocol:(NSString *)protocol
75
- domain:(NSString *)domain
76
- name:(NSString *)name
77
- port:(int)port
78
- txt:(NSArray<NSArray<NSString *> *> *)txt)
148
+ - (instancetype) init
79
149
  {
80
- const NSNetService *svc = [[NSNetService alloc] initWithDomain:domain type:[NSString stringWithFormat:@"_%@._%@.", type, protocol] name:name port:port];
81
- [svc setDelegate:self];
82
- [svc scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
150
+ self = [super init];
83
151
 
84
- if (txt.count > 0) {
85
- [svc setTXTRecordData:[self TXTRecordDataFromPairs:txt]];
152
+ if (self) {
153
+ _scans = [[NSMutableDictionary alloc] init];
154
+ _publishedServices = [[NSMutableDictionary alloc] init];
155
+ _pendingPublications = [[NSMutableSet alloc] init];
86
156
  }
87
157
 
88
- [svc publish];
89
- self.publishedServices[svc.name] = svc;
90
- NSLog(@"zeroconf publish called");
158
+ return self;
91
159
  }
92
160
 
93
- RCT_EXPORT_METHOD(unregisterService:(NSString *) serviceName)
94
- {
95
- NSNetService *svc = self.publishedServices[serviceName];
161
+ #pragma mark - Scan
96
162
 
97
- if (svc) {
98
- [svc stop];
163
+ RCT_EXPORT_METHOD(scan:(NSString *)scanId
164
+ type:(NSString *)type
165
+ protocol:(NSString *)protocol
166
+ domain:(NSString *)domain
167
+ resolveTimeout:(double)resolveTimeout)
168
+ {
169
+ [self stopScan:scanId];
170
+
171
+ RNZScan *scan = [[RNZScan alloc] init];
172
+ scan.module = self;
173
+ scan.scanId = scanId;
174
+ scan.resolveTimeoutSeconds = resolveTimeout > 0 ? resolveTimeout : 5.0;
175
+ scan.foundInterfaces = [[NSMutableDictionary alloc] init];
176
+ scan.resolvingServices = [[NSMutableDictionary alloc] init];
177
+
178
+ NSString *regtype = [NSString stringWithFormat:@"_%@._%@", type, protocol];
179
+ DNSServiceRef ref = NULL;
180
+ DNSServiceErrorType error = DNSServiceBrowse(&ref, 0, kDNSServiceInterfaceIndexAny, regtype.UTF8String,
181
+ domain.length > 0 ? domain.UTF8String : NULL,
182
+ RNZBrowseReply, (__bridge void *)scan);
183
+ if (error != kDNSServiceErr_NoError) {
184
+ [self sendError:[self errorWithCode:error action:@"Browsing services" serviceName:nil] scan:scan];
185
+ return;
99
186
  }
187
+ DNSServiceSetDispatchQueue(ref, RNZ_QUEUE);
188
+ scan.browseRef = ref;
189
+ self.scans[scanId] = scan;
190
+ [self sendEvent:@"RNZeroconfStart" scan:scan body:@{}];
100
191
  }
101
192
 
102
- #pragma mark - NSNetServiceBrowserDelegate
103
-
104
- // When a service is discovered.
105
- - (void) netServiceBrowser:(NSNetServiceBrowser *)browser
106
- didFindService:(NSNetService *)service
107
- moreComing:(BOOL)moreComing
193
+ // Stops the scan with this id, or every scan without one
194
+ RCT_EXPORT_METHOD(stop:(NSString *)scanId)
108
195
  {
109
- if (service == nil) {
110
- return;
196
+ if (scanId.length > 0) {
197
+ [self stopScan:scanId];
198
+ return;
111
199
  }
200
+ for (NSString *key in self.scans.allKeys) {
201
+ [self stopScan:key];
202
+ }
203
+ }
112
204
 
113
- NSDictionary *serviceInfo = [RNNetServiceSerializer serializeServiceToDictionary:service resolved:NO];
114
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfFound" body:serviceInfo];
205
+ - (void) stopScan:(NSString *)scanId
206
+ {
207
+ RNZScan *scan = self.scans[scanId];
208
+ if (!scan) {
209
+ return;
210
+ }
211
+ [self.scans removeObjectForKey:scanId];
115
212
 
116
- // resolving services must be strongly referenced or they will be garbage collected
117
- // and will never resolve or timeout.
118
- // source: http://stackoverflow.com/a/16130535/2715
119
- self.resolvingServices[service.name] = service;
213
+ for (RNZResolve *resolve in scan.resolvingServices.allValues) {
214
+ [self cancelResolve:resolve];
215
+ }
216
+ [scan.resolvingServices removeAllObjects];
217
+ [scan.foundInterfaces removeAllObjects];
120
218
 
121
- service.delegate = self;
122
- [service resolveWithTimeout:self.resolveTimeoutSeconds];
219
+ if (scan.browseRef) {
220
+ DNSServiceRefDeallocate(scan.browseRef);
221
+ scan.browseRef = NULL;
222
+ }
223
+ [self sendEvent:@"RNZeroconfStop" scan:scan body:@{}];
123
224
  }
124
225
 
125
- // When a service is removed.
126
- - (void) netServiceBrowser:(NSNetServiceBrowser*)netServiceBrowser
127
- didRemoveService:(NSNetService*)service
128
- moreComing:(BOOL)moreComing
226
+ - (void) handleBrowse:(RNZScan *)scan flags:(DNSServiceFlags)flags error:(DNSServiceErrorType)error name:(const char *)name regtype:(const char *)regtype domain:(const char *)domain
129
227
  {
130
- if (service == nil) {
131
- return;
228
+ if (scan.browseRef == NULL) {
229
+ return;
230
+ }
231
+ if (error != kDNSServiceErr_NoError) {
232
+ [self sendError:[self errorWithCode:error action:@"Browsing services" serviceName:nil] scan:scan];
233
+ // The browse can't continue after an error
234
+ RNZDeallocateLater(scan.browseRef, scan);
235
+ scan.browseRef = NULL;
236
+ if (self.scans[scan.scanId] == scan) {
237
+ [self stopScan:scan.scanId];
238
+ }
239
+ return;
132
240
  }
133
241
 
134
- // Stop any pending resolve for the removed service
135
- NSNetService *resolving = self.resolvingServices[service.name];
136
- if (resolving) {
137
- resolving.delegate = nil;
138
- [resolving stop];
139
- [self.resolvingServices removeObjectForKey:service.name];
242
+ NSString *serviceName = name ? [NSString stringWithUTF8String:name] : nil;
243
+ if (!serviceName) {
244
+ return;
140
245
  }
246
+ NSInteger interfaces = scan.foundInterfaces[serviceName].integerValue;
141
247
 
142
- NSDictionary *serviceInfo = [RNNetServiceSerializer serializeServiceToDictionary:service resolved:NO];
143
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfRemove" body:serviceInfo];
248
+ if (flags & kDNSServiceFlagsAdd) {
249
+ scan.foundInterfaces[serviceName] = @(interfaces + 1);
250
+ if (interfaces == 0) {
251
+ [self sendEvent:@"RNZeroconfFound" scan:scan body:@{ kRNServiceKeysName: serviceName }];
252
+ [self startResolve:serviceName regtype:[NSString stringWithUTF8String:regtype] domain:[NSString stringWithUTF8String:domain] scan:scan];
253
+ }
254
+ return;
255
+ }
256
+
257
+ if (interfaces > 1) {
258
+ scan.foundInterfaces[serviceName] = @(interfaces - 1);
259
+ return;
260
+ }
261
+ [scan.foundInterfaces removeObjectForKey:serviceName];
262
+
263
+ // Stop any pending resolve for the removed service
264
+ RNZResolve *resolve = scan.resolvingServices[serviceName];
265
+ if (resolve) {
266
+ [self cancelResolve:resolve];
267
+ [scan.resolvingServices removeObjectForKey:serviceName];
268
+ }
269
+ [self sendEvent:@"RNZeroconfRemove" scan:scan body:@{ kRNServiceKeysName: serviceName }];
144
270
  }
145
271
 
146
- // When the search fails.
147
- - (void) netServiceBrowser:(NSNetServiceBrowser *)browser
148
- didNotSearch:(NSDictionary *)errorDict
272
+ #pragma mark - Resolve
273
+
274
+ - (void) startResolve:(NSString *)name regtype:(NSString *)regtype domain:(NSString *)domain scan:(RNZScan *)scan
149
275
  {
150
- [self reportError:errorDict];
276
+ RNZResolve *resolve = [[RNZResolve alloc] init];
277
+ resolve.module = self;
278
+ resolve.scan = scan;
279
+ resolve.name = name;
280
+ resolve.regtype = regtype;
281
+ resolve.domain = domain;
282
+ scan.resolvingServices[name] = resolve;
283
+ [self resolve:resolve];
151
284
  }
152
285
 
153
- // When the search stops.
154
- - (void) netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)browser
286
+ - (void) resolve:(RNZResolve *)resolve
155
287
  {
156
- // A browser replaced by a newer scan stopping late shouldn't report the new scan as stopped
157
- if (self.browser == nil || self.browser == browser) {
158
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfStop" body:nil];
288
+ resolve.finished = NO;
289
+ resolve.addresses = [[NSMutableOrderedSet alloc] init];
290
+
291
+ DNSServiceRef ref = NULL;
292
+ DNSServiceErrorType error = DNSServiceResolve(&ref, 0, kDNSServiceInterfaceIndexAny, resolve.name.UTF8String,
293
+ resolve.regtype.UTF8String, resolve.domain.UTF8String,
294
+ RNZResolveReply, (__bridge void *)resolve);
295
+ if (error != kDNSServiceErr_NoError) {
296
+ [self failResolve:resolve error:[self errorWithCode:error action:@"Resolving service" serviceName:resolve.name]];
297
+ return;
159
298
  }
299
+ DNSServiceSetDispatchQueue(ref, RNZ_QUEUE);
300
+ resolve.resolveRef = ref;
301
+
302
+ __weak RNZeroconf *weakSelf = self;
303
+ __weak RNZResolve *weakResolve = resolve;
304
+ resolve.timeoutBlock = dispatch_block_create(0, ^{
305
+ [weakSelf resolveTimedOut:weakResolve];
306
+ });
307
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(resolve.scan.resolveTimeoutSeconds * NSEC_PER_SEC)), RNZ_QUEUE, resolve.timeoutBlock);
160
308
  }
161
309
 
162
- // When the search starts.
163
- - (void) netServiceBrowserWillSearch:(NSNetServiceBrowser *)browser
310
+ - (void) resolveTimedOut:(RNZResolve *)resolve
164
311
  {
165
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfStart" body:nil];
166
- }
312
+ if (!resolve || resolve.finished || resolve.scan.resolvingServices[resolve.name] != resolve) {
313
+ return;
314
+ }
315
+ [self cancelResolve:resolve];
167
316
 
168
- #pragma mark - NSNetServiceDelegate
317
+ // Slow devices can time out, retry once before reporting the error (#186)
318
+ if (!resolve.retried) {
319
+ resolve.retried = YES;
320
+ [self resolve:resolve];
321
+ return;
322
+ }
169
323
 
170
- // When the service has resolved it's network data (IP addresses, etc)
171
- - (void) netServiceDidResolveAddress:(NSNetService *)sender
324
+ [self failResolve:resolve error:@{
325
+ @"message": [NSString stringWithFormat:@"Resolving service %@ failed: timed out", resolve.name],
326
+ @"code": @"TIMEOUT",
327
+ @"domain": @"RNZeroconf",
328
+ @"serviceName": resolve.name,
329
+ }];
330
+ }
331
+
332
+ - (void) handleResolve:(RNZResolve *)resolve error:(DNSServiceErrorType)error host:(const char *)host port:(uint16_t)port txtLength:(uint16_t)txtLength txt:(const unsigned char *)txt
172
333
  {
173
- NSDictionary *serviceInfo = [RNNetServiceSerializer serializeServiceToDictionary:sender resolved:YES];
174
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfResolved" body:serviceInfo];
334
+ if (resolve.finished || resolve.resolveRef == NULL) {
335
+ return;
336
+ }
337
+ if (error != kDNSServiceErr_NoError) {
338
+ [self failResolve:resolve error:[self errorWithCode:error action:@"Resolving service" serviceName:resolve.name]];
339
+ return;
340
+ }
341
+
342
+ // Only the first answer is needed
343
+ RNZDeallocateLater(resolve.resolveRef, resolve);
344
+ resolve.resolveRef = NULL;
345
+
346
+ resolve.host = host ? [NSString stringWithUTF8String:host] : nil;
347
+ resolve.port = port;
348
+ resolve.txt = [RNNetServiceSerializer dictionaryFromTXTRecord:txt length:txtLength];
175
349
 
176
- sender.delegate = nil;
177
- [self.resolvingServices removeObjectForKey:sender.name];
178
- [self.retriedServices removeObject:sender.name];
350
+ DNSServiceRef ref = NULL;
351
+ DNSServiceErrorType addressError = DNSServiceGetAddrInfo(&ref, 0, kDNSServiceInterfaceIndexAny,
352
+ kDNSServiceProtocol_IPv4 | kDNSServiceProtocol_IPv6,
353
+ host, RNZAddressReply, (__bridge void *)resolve);
354
+ if (addressError != kDNSServiceErr_NoError) {
355
+ [self failResolve:resolve error:[self errorWithCode:addressError action:@"Resolving service" serviceName:resolve.name]];
356
+ return;
357
+ }
358
+ DNSServiceSetDispatchQueue(ref, RNZ_QUEUE);
359
+ resolve.addressRef = ref;
179
360
  }
180
361
 
181
- // When the service has failed to resolve it's network data (IP addresses, etc)
182
- - (void) netService:(NSNetService *)sender
183
- didNotResolve:(NSDictionary *)errorDict
362
+ - (void) handleAddress:(RNZResolve *)resolve flags:(DNSServiceFlags)flags error:(DNSServiceErrorType)error address:(const struct sockaddr *)address
184
363
  {
185
- // Slow devices can time out, retry once before reporting the error (#186)
186
- NSNumber *code = errorDict[NSNetServicesErrorCode];
187
- if (code.integerValue == NSNetServicesTimeoutError && ![self.retriedServices containsObject:sender.name]) {
188
- [self.retriedServices addObject:sender.name];
189
- [sender resolveWithTimeout:self.resolveTimeoutSeconds];
364
+ if (resolve.finished || resolve.addressRef == NULL) {
365
+ return;
366
+ }
367
+ if (error != kDNSServiceErr_NoError) {
368
+ // No record for one of the address families is not a failure
369
+ if (error == kDNSServiceErr_NoSuchRecord) {
370
+ return;
371
+ }
372
+ [self failResolve:resolve error:[self errorWithCode:error action:@"Resolving service" serviceName:resolve.name]];
190
373
  return;
191
374
  }
192
- [self.retriedServices removeObject:sender.name];
193
375
 
194
- [self reportError:errorDict];
376
+ NSString *string = [RNNetServiceSerializer stringFromAddress:address];
377
+ if (string && (flags & kDNSServiceFlagsAdd)) {
378
+ [resolve.addresses addObject:string];
379
+ }
380
+ if (flags & kDNSServiceFlagsMoreComing) {
381
+ return;
382
+ }
195
383
 
196
- sender.delegate = nil;
197
- [self.resolvingServices removeObjectForKey:sender.name];
384
+ // IPv4 and IPv6 answers can arrive in separate batches, wait briefly before emitting
385
+ if (resolve.emitBlock) {
386
+ dispatch_block_cancel(resolve.emitBlock);
387
+ }
388
+ __weak RNZeroconf *weakSelf = self;
389
+ __weak RNZResolve *weakResolve = resolve;
390
+ resolve.emitBlock = dispatch_block_create(0, ^{
391
+ [weakSelf finishResolve:weakResolve];
392
+ });
393
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), RNZ_QUEUE, resolve.emitBlock);
198
394
  }
199
395
 
200
- - (void)netServiceWillPublish:(NSNetService *)sender
396
+ - (void) finishResolve:(RNZResolve *)resolve
201
397
  {
202
- NSLog(@"zeroconf netServiceWillPublish");
398
+ if (!resolve || resolve.finished || resolve.addresses.count == 0) {
399
+ return;
400
+ }
401
+ [self cancelResolve:resolve];
402
+ if (resolve.scan.resolvingServices[resolve.name] == resolve) {
403
+ [resolve.scan.resolvingServices removeObjectForKey:resolve.name];
404
+ }
405
+
406
+ [self sendEvent:@"RNZeroconfResolved" scan:resolve.scan body:@{
407
+ kRNServiceKeysName: resolve.name,
408
+ kRNServiceKeysFullName: [NSString stringWithFormat:@"%@%@.", resolve.host ?: @"", resolve.regtype],
409
+ kRNServiceKeysHost: resolve.host ?: @"",
410
+ kRNServiceKeysPort: @(resolve.port),
411
+ kRNServiceKeysAddresses: resolve.addresses.array,
412
+ kRNServiceTxtRecords: resolve.txt ?: @{},
413
+ }];
203
414
  }
204
415
 
205
- // When a service is successfully published
206
- - (void)netServiceDidPublish:(NSNetService *)sender
416
+ - (void) failResolve:(RNZResolve *)resolve error:(NSDictionary *)error
207
417
  {
208
- NSLog(@"zeroconf netServiceDidPublish");
209
- NSDictionary *serviceInfo = [RNNetServiceSerializer serializeServiceToDictionary:sender resolved:YES];
210
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfServiceRegistered" body:serviceInfo];
211
-
212
- self.publishedServices[sender.name] = sender;
418
+ [self cancelResolve:resolve];
419
+ if (resolve.scan.resolvingServices[resolve.name] == resolve) {
420
+ [resolve.scan.resolvingServices removeObjectForKey:resolve.name];
421
+ }
422
+ [self sendError:error scan:resolve.scan];
423
+ }
213
424
 
425
+ // Stops everything in flight for a resolve, safe to call from its own callbacks
426
+ - (void) cancelResolve:(RNZResolve *)resolve
427
+ {
428
+ resolve.finished = YES;
429
+ if (resolve.timeoutBlock) {
430
+ dispatch_block_cancel(resolve.timeoutBlock);
431
+ resolve.timeoutBlock = nil;
432
+ }
433
+ if (resolve.emitBlock) {
434
+ dispatch_block_cancel(resolve.emitBlock);
435
+ resolve.emitBlock = nil;
436
+ }
437
+ RNZDeallocateLater(resolve.resolveRef, resolve);
438
+ resolve.resolveRef = NULL;
439
+ RNZDeallocateLater(resolve.addressRef, resolve);
440
+ resolve.addressRef = NULL;
214
441
  }
215
442
 
216
- - (void)netService:(NSNetService *)sender
217
- didNotPublish:(NSDictionary<NSString *,NSNumber *> *)errorDict
443
+ #pragma mark - Publish
444
+
445
+ RCT_EXPORT_METHOD(registerService:(NSString *)type
446
+ protocol:(NSString *)protocol
447
+ domain:(NSString *)domain
448
+ name:(NSString *)name
449
+ port:(int)port
450
+ txt:(NSArray<NSArray<NSString *> *> *)txt
451
+ resolve:(RCTPromiseResolveBlock)resolve
452
+ reject:(RCTPromiseRejectBlock)reject)
218
453
  {
219
- NSLog(@"zeroconf netServiceDidNotPublish");
454
+ NSMutableArray<NSString *> *tooLong = [NSMutableArray array];
455
+ NSData *txtRecord = [RNNetServiceSerializer TXTRecordFromPairs:txt ?: @[] tooLong:tooLong];
456
+ for (NSString *key in tooLong) {
457
+ [self sendError:@{
458
+ @"message": [NSString stringWithFormat:@"TXT record entry %@ is longer than 255 bytes", key],
459
+ @"code": @"TXT_ENTRY_TOO_LONG",
460
+ @"domain": @"RNZeroconf",
461
+ @"serviceName": name,
462
+ }];
463
+ }
220
464
 
221
- [self reportError:errorDict];
222
- NSLog(@"zeroconf %@", errorDict);
223
- sender.delegate = nil;
224
- [self.publishedServices removeObjectForKey:sender.name];
465
+ // dns_sd lets the same app register a name twice, rename like Bonjour does on conflicts
466
+ NSString *availableName = name;
467
+ for (NSInteger suffix = 2; [self isNameInUse:availableName]; suffix++) {
468
+ availableName = [NSString stringWithFormat:@"%@ (%ld)", name, (long)suffix];
469
+ }
470
+ name = availableName;
471
+
472
+ RNZPublication *publication = [[RNZPublication alloc] init];
473
+ publication.module = self;
474
+ publication.name = name;
475
+ publication.regtype = [NSString stringWithFormat:@"_%@._%@", type, protocol];
476
+ publication.domain = domain.length > 0 ? domain : @"local.";
477
+ publication.port = (uint16_t)port;
478
+ publication.txt = [RNNetServiceSerializer dictionaryFromTXTRecord:txtRecord.bytes length:(uint16_t)txtRecord.length];
479
+ publication.resolve = resolve;
480
+ publication.reject = reject;
481
+
482
+ DNSServiceRef ref = NULL;
483
+ DNSServiceErrorType error = DNSServiceRegister(&ref, 0, kDNSServiceInterfaceIndexAny, name.UTF8String,
484
+ publication.regtype.UTF8String,
485
+ domain.length > 0 ? domain.UTF8String : NULL,
486
+ NULL, htons((uint16_t)port),
487
+ (uint16_t)txtRecord.length, txtRecord.length > 0 ? txtRecord.bytes : NULL,
488
+ RNZRegisterReply, (__bridge void *)publication);
489
+ if (error != kDNSServiceErr_NoError) {
490
+ NSDictionary *errorInfo = [self errorWithCode:error action:@"Publishing service" serviceName:name];
491
+ [self sendError:errorInfo];
492
+ [self reject:reject error:errorInfo];
493
+ return;
494
+ }
495
+ DNSServiceSetDispatchQueue(ref, RNZ_QUEUE);
496
+ publication.ref = ref;
497
+ [self.pendingPublications addObject:publication];
498
+ }
499
+
500
+ - (void) handleRegister:(RNZPublication *)publication flags:(DNSServiceFlags)flags error:(DNSServiceErrorType)error name:(const char *)name
501
+ {
502
+ if (publication.ref == NULL) {
503
+ return;
504
+ }
505
+ if (error != kDNSServiceErr_NoError) {
506
+ NSDictionary *errorInfo = [self errorWithCode:error action:@"Publishing service" serviceName:publication.name];
507
+ [self sendError:errorInfo];
508
+ [self.pendingPublications removeObject:publication];
509
+ if (self.publishedServices[publication.name] == publication) {
510
+ [self.publishedServices removeObjectForKey:publication.name];
511
+ }
512
+ RNZDeallocateLater(publication.ref, publication);
513
+ publication.ref = NULL;
514
+ if (publication.reject) {
515
+ [self reject:publication.reject error:errorInfo];
516
+ }
517
+ publication.resolve = nil;
518
+ publication.reject = nil;
519
+ return;
520
+ }
521
+ if (!(flags & kDNSServiceFlagsAdd)) {
522
+ return;
523
+ }
225
524
 
525
+ // The name can differ from the requested one when it was already taken
526
+ NSString *registeredName = (name ? [NSString stringWithUTF8String:name] : nil) ?: publication.name;
527
+ if (self.publishedServices[publication.name] == publication) {
528
+ [self.publishedServices removeObjectForKey:publication.name];
529
+ }
530
+ publication.name = registeredName;
531
+ self.publishedServices[registeredName] = publication;
532
+ [self.pendingPublications removeObject:publication];
533
+
534
+ NSDictionary *serviceInfo = [self publicationInfo:publication];
535
+ [self sendEvent:@"RNZeroconfServiceRegistered" body:serviceInfo];
536
+ if (publication.resolve) {
537
+ publication.resolve(serviceInfo);
538
+ }
539
+ publication.resolve = nil;
540
+ publication.reject = nil;
226
541
  }
227
542
 
228
- - (void)netServiceDidStop:(NSNetService *)sender
543
+ RCT_EXPORT_METHOD(unregisterService:(NSString *)serviceName
544
+ resolve:(RCTPromiseResolveBlock)resolve
545
+ reject:(RCTPromiseRejectBlock)reject)
229
546
  {
230
- sender.delegate = nil;
231
- [self.publishedServices removeObjectForKey:sender.name];
547
+ RNZPublication *publication = self.publishedServices[serviceName];
548
+ if (!publication) {
549
+ [self reject:reject error:@{
550
+ @"message": [NSString stringWithFormat:@"Service %@ is not published", serviceName],
551
+ @"code": @"NOT_PUBLISHED",
552
+ @"domain": @"RNZeroconf",
553
+ @"serviceName": serviceName,
554
+ }];
555
+ return;
556
+ }
232
557
 
233
- NSDictionary *serviceInfo = [RNNetServiceSerializer serializeServiceToDictionary:sender resolved:YES];
234
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfServiceUnregistered" body:serviceInfo];
558
+ // Deallocating the ref unregisters the service
559
+ [self.publishedServices removeObjectForKey:serviceName];
560
+ DNSServiceRefDeallocate(publication.ref);
561
+ publication.ref = NULL;
235
562
 
563
+ NSDictionary *serviceInfo = [self publicationInfo:publication];
564
+ [self sendEvent:@"RNZeroconfServiceUnregistered" body:serviceInfo];
565
+ resolve(serviceInfo);
236
566
  }
237
567
 
238
- #pragma mark - Class methods
239
-
240
- - (instancetype) init
568
+ - (BOOL) isNameInUse:(NSString *)name
241
569
  {
242
- self = [super init];
243
-
244
- if (self) {
245
- _resolvingServices = [[NSMutableDictionary alloc] init];
246
- _publishedServices = [[NSMutableDictionary alloc] init];
247
- _retriedServices = [[NSMutableSet alloc] init];
248
- _stoppingBrowsers = [[NSMutableSet alloc] init];
249
- _resolveTimeoutSeconds = 5.0;
570
+ if (self.publishedServices[name]) {
571
+ return YES;
250
572
  }
573
+ for (RNZPublication *publication in self.pendingPublications) {
574
+ if ([publication.name isEqualToString:name]) {
575
+ return YES;
576
+ }
577
+ }
578
+ return NO;
579
+ }
251
580
 
252
- return self;
581
+ - (NSDictionary *) publicationInfo:(RNZPublication *)publication
582
+ {
583
+ return @{
584
+ kRNServiceKeysName: publication.name,
585
+ kRNServiceKeysFullName: [NSString stringWithFormat:@"%@.%@.%@", publication.name, publication.regtype, publication.domain],
586
+ kRNServiceKeysPort: @(publication.port),
587
+ kRNServiceKeysAddresses: @[],
588
+ kRNServiceTxtRecords: publication.txt ?: @{},
589
+ };
253
590
  }
254
591
 
255
- // Builds the TXT record in the given order, unlike dataFromTXTRecordDictionary
256
- - (NSData *) TXTRecordDataFromPairs:(NSArray<NSArray<NSString *> *> *)pairs
592
+ #pragma mark - Local Network access
593
+
594
+ /**
595
+ * Resolves 'granted', 'denied' or 'unknown'. There is no API to read the Local Network permission,
596
+ * so this advertises a temporary Bonjour service and browses for it: seeing it means access is granted,
597
+ * a browser waiting with kDNSServiceErr_PolicyDenied until the timeout means it is denied.
598
+ * The type must be listed in NSBonjourServices, defaults to the first one. It can show the permission prompt.
599
+ */
600
+ RCT_EXPORT_METHOD(checkLocalNetworkAccess:(NSString *)type
601
+ timeout:(double)timeout
602
+ resolve:(RCTPromiseResolveBlock)resolve
603
+ reject:(RCTPromiseRejectBlock)reject)
257
604
  {
258
- NSMutableData *data = [NSMutableData data];
259
- for (NSArray<NSString *> *pair in pairs) {
260
- if (pair.count != 2) {
261
- continue;
605
+ NSString *serviceType = type;
606
+ if (serviceType.length == 0) {
607
+ NSArray *declared = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSBonjourServices"];
608
+ serviceType = [declared isKindOfClass:[NSArray class]] ? declared.firstObject : nil;
609
+ }
610
+ if (serviceType.length == 0) {
611
+ [self reject:reject error:@{
612
+ @"message": @"No service type to check with, add one to NSBonjourServices in Info.plist",
613
+ @"code": @"MISSING_BONJOUR_SERVICES",
614
+ @"domain": @"RNZeroconf",
615
+ }];
616
+ return;
617
+ }
618
+ // "_http._tcp." -> "_http._tcp"
619
+ if ([serviceType hasSuffix:@"."]) {
620
+ serviceType = [serviceType substringToIndex:serviceType.length - 1];
621
+ }
622
+
623
+ NSString *name = [NSString stringWithFormat:@"rnzeroconf-%@", [[NSUUID UUID].UUIDString substringToIndex:8]];
624
+ dispatch_queue_t queue = RNZ_QUEUE;
625
+
626
+ nw_parameters_t parameters = nw_parameters_create_secure_tcp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION);
627
+ nw_listener_t listener = nw_listener_create(parameters);
628
+ nw_listener_set_advertise_descriptor(listener, nw_advertise_descriptor_create_bonjour_service(name.UTF8String, serviceType.UTF8String, "local."));
629
+ nw_listener_set_queue(listener, queue);
630
+ nw_listener_set_new_connection_handler(listener, ^(nw_connection_t connection) {
631
+ nw_connection_cancel(connection);
632
+ });
633
+
634
+ nw_browse_descriptor_t descriptor = nw_browse_descriptor_create_bonjour_service(serviceType.UTF8String, "local.");
635
+ nw_browser_t browser = nw_browser_create(descriptor, nw_parameters_create_secure_tcp(NW_PARAMETERS_DISABLE_PROTOCOL, NW_PARAMETERS_DEFAULT_CONFIGURATION));
636
+ nw_browser_set_queue(browser, queue);
637
+
638
+ __block BOOL finished = NO;
639
+ __block BOOL policyDenied = NO;
640
+ void (^finish)(NSString *) = ^(NSString *result) {
641
+ if (finished) {
642
+ return;
262
643
  }
263
- NSData *entry = [[NSString stringWithFormat:@"%@=%@", pair[0], pair[1]] dataUsingEncoding:NSUTF8StringEncoding];
264
- if (entry.length > 255) {
265
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfError" body:[NSString stringWithFormat:@"TXT record entry %@ is longer than 255 bytes", pair[0]]];
266
- continue;
644
+ finished = YES;
645
+ nw_browser_cancel(browser);
646
+ nw_listener_cancel(listener);
647
+ resolve(result);
648
+ };
649
+
650
+ nw_browser_set_browse_results_changed_handler(browser, ^(nw_browse_result_t oldResult, nw_browse_result_t newResult, bool batchComplete) {
651
+ nw_endpoint_t endpoint = newResult ? nw_browse_result_copy_endpoint(newResult) : nil;
652
+ const char *found = endpoint ? nw_endpoint_get_bonjour_service_name(endpoint) : NULL;
653
+ if (found && strcmp(found, name.UTF8String) == 0) {
654
+ finish(@"granted");
267
655
  }
268
- uint8_t length = (uint8_t)entry.length;
269
- [data appendBytes:&length length:1];
270
- [data appendData:entry];
271
- }
272
- return data;
656
+ });
657
+ nw_browser_set_state_changed_handler(browser, ^(nw_browser_state_t state, nw_error_t error) {
658
+ if (error && nw_error_get_error_domain(error) == nw_error_domain_dns) {
659
+ // Stays waiting while the prompt is shown, only conclude on timeout
660
+ policyDenied = nw_error_get_error_code(error) == kDNSServiceErr_PolicyDenied;
661
+ } else if (state == nw_browser_state_ready) {
662
+ policyDenied = NO;
663
+ }
664
+ });
665
+
666
+ nw_listener_start(listener);
667
+ nw_browser_start(browser);
668
+
669
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((timeout > 0 ? timeout : 5.0) * NSEC_PER_SEC)), queue, ^{
670
+ finish(policyDenied ? @"denied" : @"unknown");
671
+ });
273
672
  }
274
673
 
674
+ #pragma mark - Teardown
675
+
275
676
  // Called when the bridge is torn down (e.g. reload): stop scanning and unpublish services
276
677
  - (void) invalidate
277
678
  {
278
- [self stop];
279
- // Delegates are unretained, detach them so stopping browsers never call a released module
280
- for (NSNetServiceBrowser *browser in self.stoppingBrowsers) {
281
- browser.delegate = nil;
282
- }
283
- for (NSNetService *service in self.publishedServices.allValues) {
284
- service.delegate = nil;
285
- [service stop];
679
+ [self stop:nil];
680
+ for (RNZPublication *publication in self.publishedServices.allValues) {
681
+ DNSServiceRefDeallocate(publication.ref);
682
+ publication.ref = NULL;
286
683
  }
287
684
  [self.publishedServices removeAllObjects];
685
+ for (RNZPublication *publication in self.pendingPublications) {
686
+ DNSServiceRefDeallocate(publication.ref);
687
+ publication.ref = NULL;
688
+ }
689
+ [self.pendingPublications removeAllObjects];
288
690
  }
289
691
 
290
- - (void) reportError:(NSDictionary *)errorDict
692
+ #pragma mark - Events and errors
693
+
694
+ - (void) sendEvent:(NSString *)name body:(id)body
695
+ {
696
+ [self.bridge.eventDispatcher sendDeviceEventWithName:name body:body];
697
+ }
698
+
699
+ // Scan events carry the id of the scan they belong to
700
+ - (void) sendEvent:(NSString *)name scan:(RNZScan *)scan body:(NSDictionary *)body
291
701
  {
292
- [self.bridge.eventDispatcher sendDeviceEventWithName:@"RNZeroconfError" body:[NSString stringWithFormat:@"%@",errorDict]];
702
+ NSMutableDictionary *withScan = [body mutableCopy];
703
+ withScan[@"scanId"] = scan.scanId ?: @"";
704
+ [self sendEvent:name body:withScan];
705
+ }
706
+
707
+ - (void) sendError:(NSDictionary *)error scan:(RNZScan *)scan
708
+ {
709
+ NSMutableDictionary *withScan = [error mutableCopy];
710
+ withScan[@"scanId"] = scan.scanId ?: @"";
711
+ [self sendError:withScan];
712
+ }
713
+
714
+ // Emits an error event as { message, code, domain, serviceName }
715
+ - (void) sendError:(NSDictionary *)error
716
+ {
717
+ [self sendEvent:@"RNZeroconfError" body:error];
718
+ }
719
+
720
+ // Rejects a promise with the same { message, code, domain, serviceName } shape as error events, in userInfo
721
+ - (void) reject:(RCTPromiseRejectBlock)reject error:(NSDictionary *)error
722
+ {
723
+ id code = error[@"code"];
724
+ NSError *nsError = [NSError errorWithDomain:error[@"domain"]
725
+ code:[code isKindOfClass:[NSNumber class]] ? [code integerValue] : 0
726
+ userInfo:error];
727
+ reject([NSString stringWithFormat:@"%@", code], error[@"message"], nsError);
728
+ }
729
+
730
+ - (NSDictionary *) errorWithCode:(DNSServiceErrorType)code action:(NSString *)action serviceName:(NSString *)serviceName
731
+ {
732
+ NSString *subject = serviceName ? [NSString stringWithFormat:@"%@ %@", action, serviceName] : action;
733
+ NSMutableDictionary *error = [@{
734
+ @"message": [NSString stringWithFormat:@"%@ failed: %@", subject, [RNZeroconf describeError:code]],
735
+ @"code": @(code),
736
+ @"domain": @"DNSSD",
737
+ } mutableCopy];
738
+ if (serviceName) {
739
+ error[@"serviceName"] = serviceName;
740
+ }
741
+ return error;
742
+ }
743
+
744
+ // Readable description of a DNSServiceErrorType
745
+ + (NSString *) describeError:(DNSServiceErrorType)code
746
+ {
747
+ switch (code) {
748
+ case kDNSServiceErr_NoAuth: return @"not authorized, add the service type to NSBonjourServices in Info.plist";
749
+ case kDNSServiceErr_PolicyDenied: return @"Local Network access denied";
750
+ case kDNSServiceErr_NameConflict: return @"name already in use";
751
+ case kDNSServiceErr_BadParam: return @"bad parameter";
752
+ case kDNSServiceErr_NoSuchName: return @"no such name";
753
+ case kDNSServiceErr_NoSuchRecord: return @"no such record";
754
+ case kDNSServiceErr_ServiceNotRunning: return @"mDNSResponder is not running";
755
+ case kDNSServiceErr_Timeout: return @"timed out";
756
+ case kDNSServiceErr_NoMemory: return @"out of memory";
757
+ case kDNSServiceErr_Unsupported: return @"unsupported";
758
+ default: return [NSString stringWithFormat:@"error %d", code];
759
+ }
293
760
  }
294
761
 
295
762
  @end