@webex/plugin-meetings 3.0.0-beta.40 → 3.0.0-beta.400

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 (398) hide show
  1. package/README.md +58 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/events.js +45 -0
  11. package/dist/breakouts/events.js.map +1 -0
  12. package/dist/breakouts/index.js +625 -123
  13. package/dist/breakouts/index.js.map +1 -1
  14. package/dist/breakouts/utils.js +27 -8
  15. package/dist/breakouts/utils.js.map +1 -1
  16. package/dist/common/errors/no-meeting-info.js +51 -0
  17. package/dist/common/errors/no-meeting-info.js.map +1 -0
  18. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  19. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  20. package/dist/common/errors/webex-errors.js +48 -7
  21. package/dist/common/errors/webex-errors.js.map +1 -1
  22. package/dist/common/logs/logger-proxy.js +1 -1
  23. package/dist/common/logs/logger-proxy.js.map +1 -1
  24. package/dist/common/logs/request.js +5 -1
  25. package/dist/common/logs/request.js.map +1 -1
  26. package/dist/common/queue.js +24 -9
  27. package/dist/common/queue.js.map +1 -1
  28. package/dist/config.js +6 -10
  29. package/dist/config.js.map +1 -1
  30. package/dist/constants.js +247 -34
  31. package/dist/constants.js.map +1 -1
  32. package/dist/controls-options-manager/enums.js +14 -2
  33. package/dist/controls-options-manager/enums.js.map +1 -1
  34. package/dist/controls-options-manager/index.js +109 -15
  35. package/dist/controls-options-manager/index.js.map +1 -1
  36. package/dist/controls-options-manager/types.js +7 -0
  37. package/dist/controls-options-manager/types.js.map +1 -0
  38. package/dist/controls-options-manager/util.js +309 -18
  39. package/dist/controls-options-manager/util.js.map +1 -1
  40. package/dist/index.js +116 -2
  41. package/dist/index.js.map +1 -1
  42. package/dist/interceptors/index.js +15 -0
  43. package/dist/interceptors/index.js.map +1 -0
  44. package/dist/interceptors/locusRetry.js +93 -0
  45. package/dist/interceptors/locusRetry.js.map +1 -0
  46. package/dist/interpretation/collection.js +23 -0
  47. package/dist/interpretation/collection.js.map +1 -0
  48. package/dist/interpretation/index.js +380 -0
  49. package/dist/interpretation/index.js.map +1 -0
  50. package/dist/interpretation/siLanguage.js +25 -0
  51. package/dist/interpretation/siLanguage.js.map +1 -0
  52. package/dist/locus-info/controlsUtils.js +91 -2
  53. package/dist/locus-info/controlsUtils.js.map +1 -1
  54. package/dist/locus-info/index.js +386 -62
  55. package/dist/locus-info/index.js.map +1 -1
  56. package/dist/locus-info/infoUtils.js +7 -1
  57. package/dist/locus-info/infoUtils.js.map +1 -1
  58. package/dist/locus-info/mediaSharesUtils.js +71 -1
  59. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  60. package/dist/locus-info/parser.js +249 -72
  61. package/dist/locus-info/parser.js.map +1 -1
  62. package/dist/locus-info/selfUtils.js +89 -14
  63. package/dist/locus-info/selfUtils.js.map +1 -1
  64. package/dist/media/index.js +65 -102
  65. package/dist/media/index.js.map +1 -1
  66. package/dist/media/properties.js +73 -124
  67. package/dist/media/properties.js.map +1 -1
  68. package/dist/mediaQualityMetrics/config.js +135 -330
  69. package/dist/mediaQualityMetrics/config.js.map +1 -1
  70. package/dist/meeting/in-meeting-actions.js +86 -2
  71. package/dist/meeting/in-meeting-actions.js.map +1 -1
  72. package/dist/meeting/index.js +4509 -3000
  73. package/dist/meeting/index.js.map +1 -1
  74. package/dist/meeting/locusMediaRequest.js +292 -0
  75. package/dist/meeting/locusMediaRequest.js.map +1 -0
  76. package/dist/meeting/muteState.js +236 -136
  77. package/dist/meeting/muteState.js.map +1 -1
  78. package/dist/meeting/request.js +185 -155
  79. package/dist/meeting/request.js.map +1 -1
  80. package/dist/meeting/util.js +676 -417
  81. package/dist/meeting/util.js.map +1 -1
  82. package/dist/meeting/voicea-meeting.js +172 -0
  83. package/dist/meeting/voicea-meeting.js.map +1 -0
  84. package/dist/meeting-info/index.js +73 -7
  85. package/dist/meeting-info/index.js.map +1 -1
  86. package/dist/meeting-info/meeting-info-v2.js +201 -57
  87. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  88. package/dist/meeting-info/util.js +8 -7
  89. package/dist/meeting-info/util.js.map +1 -1
  90. package/dist/meeting-info/utilv2.js +44 -40
  91. package/dist/meeting-info/utilv2.js.map +1 -1
  92. package/dist/meetings/collection.js +39 -0
  93. package/dist/meetings/collection.js.map +1 -1
  94. package/dist/meetings/index.js +484 -119
  95. package/dist/meetings/index.js.map +1 -1
  96. package/dist/meetings/meetings.types.js +7 -0
  97. package/dist/meetings/meetings.types.js.map +1 -0
  98. package/dist/meetings/request.js +2 -0
  99. package/dist/meetings/request.js.map +1 -1
  100. package/dist/meetings/util.js +73 -7
  101. package/dist/meetings/util.js.map +1 -1
  102. package/dist/member/index.js +57 -0
  103. package/dist/member/index.js.map +1 -1
  104. package/dist/member/types.js +25 -0
  105. package/dist/member/types.js.map +1 -0
  106. package/dist/member/util.js +132 -25
  107. package/dist/member/util.js.map +1 -1
  108. package/dist/members/collection.js +10 -0
  109. package/dist/members/collection.js.map +1 -1
  110. package/dist/members/index.js +100 -5
  111. package/dist/members/index.js.map +1 -1
  112. package/dist/members/request.js +106 -38
  113. package/dist/members/request.js.map +1 -1
  114. package/dist/members/types.js +15 -0
  115. package/dist/members/types.js.map +1 -0
  116. package/dist/members/util.js +326 -232
  117. package/dist/members/util.js.map +1 -1
  118. package/dist/metrics/constants.js +18 -1
  119. package/dist/metrics/constants.js.map +1 -1
  120. package/dist/metrics/index.js +1 -446
  121. package/dist/metrics/index.js.map +1 -1
  122. package/dist/multistream/mediaRequestManager.js +223 -32
  123. package/dist/multistream/mediaRequestManager.js.map +1 -1
  124. package/dist/multistream/receiveSlot.js +10 -0
  125. package/dist/multistream/receiveSlot.js.map +1 -1
  126. package/dist/multistream/receiveSlotManager.js +39 -36
  127. package/dist/multistream/receiveSlotManager.js.map +1 -1
  128. package/dist/multistream/remoteMedia.js +3 -1
  129. package/dist/multistream/remoteMedia.js.map +1 -1
  130. package/dist/multistream/remoteMediaGroup.js +76 -5
  131. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  132. package/dist/multistream/remoteMediaManager.js +366 -104
  133. package/dist/multistream/remoteMediaManager.js.map +1 -1
  134. package/dist/multistream/sendSlotManager.js +255 -0
  135. package/dist/multistream/sendSlotManager.js.map +1 -0
  136. package/dist/reachability/clusterReachability.js +356 -0
  137. package/dist/reachability/clusterReachability.js.map +1 -0
  138. package/dist/reachability/index.js +263 -390
  139. package/dist/reachability/index.js.map +1 -1
  140. package/dist/reachability/request.js +6 -4
  141. package/dist/reachability/request.js.map +1 -1
  142. package/dist/reachability/util.js +29 -0
  143. package/dist/reachability/util.js.map +1 -0
  144. package/dist/reconnection-manager/index.js +266 -202
  145. package/dist/reconnection-manager/index.js.map +1 -1
  146. package/dist/recording-controller/index.js +21 -2
  147. package/dist/recording-controller/index.js.map +1 -1
  148. package/dist/recording-controller/util.js +9 -8
  149. package/dist/recording-controller/util.js.map +1 -1
  150. package/dist/roap/index.js +66 -28
  151. package/dist/roap/index.js.map +1 -1
  152. package/dist/roap/request.js +48 -64
  153. package/dist/roap/request.js.map +1 -1
  154. package/dist/roap/turnDiscovery.js +407 -79
  155. package/dist/roap/turnDiscovery.js.map +1 -1
  156. package/dist/rtcMetrics/constants.js +12 -0
  157. package/dist/rtcMetrics/constants.js.map +1 -0
  158. package/dist/rtcMetrics/index.js +179 -0
  159. package/dist/rtcMetrics/index.js.map +1 -0
  160. package/dist/statsAnalyzer/index.js +357 -295
  161. package/dist/statsAnalyzer/index.js.map +1 -1
  162. package/dist/statsAnalyzer/mqaUtil.js +296 -156
  163. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  164. package/dist/types/annotation/annotation.types.d.ts +42 -0
  165. package/dist/types/annotation/constants.d.ts +31 -0
  166. package/dist/types/annotation/index.d.ts +117 -0
  167. package/dist/types/breakouts/events.d.ts +8 -0
  168. package/dist/types/breakouts/utils.d.ts +9 -2
  169. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  170. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  171. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  172. package/dist/types/common/logs/request.d.ts +2 -0
  173. package/dist/types/common/queue.d.ts +9 -7
  174. package/dist/types/config.d.ts +2 -7
  175. package/dist/types/constants.d.ts +204 -32
  176. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  177. package/dist/types/controls-options-manager/index.d.ts +17 -1
  178. package/dist/types/controls-options-manager/types.d.ts +43 -0
  179. package/dist/types/controls-options-manager/util.d.ts +1 -7
  180. package/dist/types/index.d.ts +6 -5
  181. package/dist/types/interceptors/index.d.ts +2 -0
  182. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  183. package/dist/types/interpretation/collection.d.ts +5 -0
  184. package/dist/types/interpretation/index.d.ts +5 -0
  185. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  186. package/dist/types/locus-info/index.d.ts +57 -4
  187. package/dist/types/locus-info/parser.d.ts +66 -6
  188. package/dist/types/media/index.d.ts +2 -0
  189. package/dist/types/media/properties.d.ts +34 -49
  190. package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
  191. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  192. package/dist/types/meeting/index.d.ts +630 -505
  193. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  194. package/dist/types/meeting/muteState.d.ts +88 -26
  195. package/dist/types/meeting/request.d.ts +65 -43
  196. package/dist/types/meeting/util.d.ts +117 -1
  197. package/dist/types/meeting/voicea-meeting.d.ts +16 -0
  198. package/dist/types/meeting-info/index.d.ts +13 -1
  199. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  200. package/dist/types/meetings/collection.d.ts +17 -0
  201. package/dist/types/meetings/index.d.ts +113 -21
  202. package/dist/types/meetings/meetings.types.d.ts +4 -0
  203. package/dist/types/member/index.d.ts +14 -0
  204. package/dist/types/member/types.d.ts +32 -0
  205. package/dist/types/members/collection.d.ts +5 -0
  206. package/dist/types/members/index.d.ts +35 -2
  207. package/dist/types/members/request.d.ts +73 -9
  208. package/dist/types/members/types.d.ts +25 -0
  209. package/dist/types/members/util.d.ts +214 -1
  210. package/dist/types/metrics/constants.d.ts +17 -0
  211. package/dist/types/metrics/index.d.ts +4 -111
  212. package/dist/types/multistream/mediaRequestManager.d.ts +72 -3
  213. package/dist/types/multistream/receiveSlot.d.ts +7 -3
  214. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  215. package/dist/types/multistream/remoteMedia.d.ts +3 -31
  216. package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
  217. package/dist/types/multistream/remoteMediaManager.d.ts +62 -2
  218. package/dist/types/multistream/sendSlotManager.d.ts +70 -0
  219. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  220. package/dist/types/reachability/index.d.ts +60 -95
  221. package/dist/types/reachability/request.d.ts +3 -1
  222. package/dist/types/reachability/util.d.ts +8 -0
  223. package/dist/types/reconnection-manager/index.d.ts +19 -0
  224. package/dist/types/recording-controller/index.d.ts +15 -1
  225. package/dist/types/recording-controller/util.d.ts +5 -4
  226. package/dist/types/roap/index.d.ts +11 -2
  227. package/dist/types/roap/request.d.ts +9 -8
  228. package/dist/types/roap/turnDiscovery.d.ts +90 -9
  229. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  230. package/dist/types/rtcMetrics/index.d.ts +61 -0
  231. package/dist/types/statsAnalyzer/index.d.ts +34 -12
  232. package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
  233. package/dist/types/webinar/collection.d.ts +16 -0
  234. package/dist/types/webinar/index.d.ts +5 -0
  235. package/dist/webinar/collection.js +44 -0
  236. package/dist/webinar/collection.js.map +1 -0
  237. package/dist/webinar/index.js +69 -0
  238. package/dist/webinar/index.js.map +1 -0
  239. package/package.json +22 -19
  240. package/src/annotation/annotation.types.ts +50 -0
  241. package/src/annotation/constants.ts +36 -0
  242. package/src/annotation/index.ts +328 -0
  243. package/src/breakouts/README.md +27 -6
  244. package/src/breakouts/breakout.ts +67 -9
  245. package/src/breakouts/events.ts +56 -0
  246. package/src/breakouts/index.ts +494 -73
  247. package/src/breakouts/utils.ts +26 -8
  248. package/src/common/errors/no-meeting-info.ts +24 -0
  249. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  250. package/src/common/errors/webex-errors.ts +44 -2
  251. package/src/common/logs/logger-proxy.ts +1 -1
  252. package/src/common/logs/request.ts +5 -1
  253. package/src/common/queue.ts +22 -8
  254. package/src/config.ts +6 -13
  255. package/src/constants.ts +234 -22
  256. package/src/controls-options-manager/enums.ts +12 -0
  257. package/src/controls-options-manager/index.ts +116 -21
  258. package/src/controls-options-manager/types.ts +59 -0
  259. package/src/controls-options-manager/util.ts +294 -14
  260. package/src/index.ts +45 -0
  261. package/src/interceptors/index.ts +3 -0
  262. package/src/interceptors/locusRetry.ts +67 -0
  263. package/src/interpretation/README.md +60 -0
  264. package/src/interpretation/collection.ts +19 -0
  265. package/src/interpretation/index.ts +349 -0
  266. package/src/interpretation/siLanguage.ts +18 -0
  267. package/src/locus-info/controlsUtils.ts +108 -0
  268. package/src/locus-info/index.ts +417 -59
  269. package/src/locus-info/infoUtils.ts +10 -2
  270. package/src/locus-info/mediaSharesUtils.ts +80 -0
  271. package/src/locus-info/parser.ts +258 -47
  272. package/src/locus-info/selfUtils.ts +81 -5
  273. package/src/media/index.ts +100 -108
  274. package/src/media/properties.ts +88 -117
  275. package/src/mediaQualityMetrics/config.ts +103 -238
  276. package/src/meeting/in-meeting-actions.ts +171 -3
  277. package/src/meeting/index.ts +3899 -2622
  278. package/src/meeting/locusMediaRequest.ts +313 -0
  279. package/src/meeting/muteState.ts +237 -136
  280. package/src/meeting/request.ts +166 -122
  281. package/src/meeting/util.ts +690 -395
  282. package/src/meeting/voicea-meeting.ts +122 -0
  283. package/src/meeting-info/index.ts +81 -8
  284. package/src/meeting-info/meeting-info-v2.ts +166 -16
  285. package/src/meeting-info/util.ts +13 -10
  286. package/src/meeting-info/utilv2.ts +47 -37
  287. package/src/meetings/collection.ts +33 -0
  288. package/src/meetings/index.ts +507 -127
  289. package/src/meetings/meetings.types.ts +12 -0
  290. package/src/meetings/request.ts +2 -0
  291. package/src/meetings/util.ts +81 -12
  292. package/src/member/index.ts +57 -0
  293. package/src/member/types.ts +38 -0
  294. package/src/member/util.ts +141 -25
  295. package/src/members/collection.ts +8 -0
  296. package/src/members/index.ts +133 -7
  297. package/src/members/request.ts +97 -17
  298. package/src/members/types.ts +29 -0
  299. package/src/members/util.ts +333 -240
  300. package/src/metrics/constants.ts +17 -0
  301. package/src/metrics/index.ts +1 -469
  302. package/src/multistream/mediaRequestManager.ts +271 -56
  303. package/src/multistream/receiveSlot.ts +11 -4
  304. package/src/multistream/receiveSlotManager.ts +34 -24
  305. package/src/multistream/remoteMedia.ts +5 -3
  306. package/src/multistream/remoteMediaGroup.ts +78 -0
  307. package/src/multistream/remoteMediaManager.ts +248 -44
  308. package/src/multistream/sendSlotManager.ts +199 -0
  309. package/src/reachability/clusterReachability.ts +320 -0
  310. package/src/reachability/index.ts +229 -346
  311. package/src/reachability/request.ts +8 -4
  312. package/src/reachability/util.ts +24 -0
  313. package/src/reconnection-manager/index.ts +128 -97
  314. package/src/recording-controller/index.ts +20 -3
  315. package/src/recording-controller/util.ts +26 -9
  316. package/src/roap/index.ts +76 -25
  317. package/src/roap/request.ts +48 -67
  318. package/src/roap/turnDiscovery.ts +331 -67
  319. package/src/rtcMetrics/constants.ts +3 -0
  320. package/src/rtcMetrics/index.ts +166 -0
  321. package/src/statsAnalyzer/index.ts +457 -416
  322. package/src/statsAnalyzer/mqaUtil.ts +317 -170
  323. package/src/webinar/collection.ts +31 -0
  324. package/src/webinar/index.ts +62 -0
  325. package/test/integration/spec/converged-space-meetings.js +60 -3
  326. package/test/integration/spec/journey.js +321 -262
  327. package/test/integration/spec/space-meeting.js +76 -3
  328. package/test/unit/spec/annotation/index.ts +418 -0
  329. package/test/unit/spec/breakouts/breakout.ts +119 -28
  330. package/test/unit/spec/breakouts/events.ts +89 -0
  331. package/test/unit/spec/breakouts/index.ts +1204 -118
  332. package/test/unit/spec/breakouts/utils.js +27 -2
  333. package/test/unit/spec/common/queue.js +31 -2
  334. package/test/unit/spec/controls-options-manager/index.js +163 -0
  335. package/test/unit/spec/controls-options-manager/util.js +576 -60
  336. package/test/unit/spec/fixture/locus.js +1 -0
  337. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  338. package/test/unit/spec/interpretation/collection.ts +15 -0
  339. package/test/unit/spec/interpretation/index.ts +625 -0
  340. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  341. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  342. package/test/unit/spec/locus-info/index.js +1372 -37
  343. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  344. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  345. package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
  346. package/test/unit/spec/locus-info/parser.js +116 -35
  347. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  348. package/test/unit/spec/locus-info/selfUtils.js +203 -17
  349. package/test/unit/spec/media/index.ts +178 -81
  350. package/test/unit/spec/media/properties.ts +2 -2
  351. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  352. package/test/unit/spec/meeting/index.js +7520 -2267
  353. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  354. package/test/unit/spec/meeting/muteState.js +549 -207
  355. package/test/unit/spec/meeting/request.js +476 -54
  356. package/test/unit/spec/meeting/utils.js +827 -74
  357. package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
  358. package/test/unit/spec/meeting-info/index.js +300 -0
  359. package/test/unit/spec/meeting-info/meetinginfov2.js +535 -9
  360. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  361. package/test/unit/spec/meetings/collection.js +26 -0
  362. package/test/unit/spec/meetings/index.js +1489 -219
  363. package/test/unit/spec/meetings/utils.js +229 -2
  364. package/test/unit/spec/member/index.js +61 -6
  365. package/test/unit/spec/member/util.js +510 -34
  366. package/test/unit/spec/members/index.js +432 -1
  367. package/test/unit/spec/members/request.js +206 -27
  368. package/test/unit/spec/members/utils.js +210 -0
  369. package/test/unit/spec/metrics/index.js +2 -52
  370. package/test/unit/spec/multistream/mediaRequestManager.ts +782 -114
  371. package/test/unit/spec/multistream/receiveSlot.ts +9 -1
  372. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  373. package/test/unit/spec/multistream/remoteMedia.ts +2 -0
  374. package/test/unit/spec/multistream/remoteMediaGroup.ts +345 -0
  375. package/test/unit/spec/multistream/remoteMediaManager.ts +525 -0
  376. package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
  377. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  378. package/test/unit/spec/reachability/index.ts +551 -14
  379. package/test/unit/spec/reachability/request.js +3 -1
  380. package/test/unit/spec/reachability/util.ts +40 -0
  381. package/test/unit/spec/reconnection-manager/index.js +171 -11
  382. package/test/unit/spec/recording-controller/index.js +293 -218
  383. package/test/unit/spec/recording-controller/util.js +223 -96
  384. package/test/unit/spec/roap/index.ts +233 -81
  385. package/test/unit/spec/roap/request.ts +100 -62
  386. package/test/unit/spec/roap/turnDiscovery.ts +682 -108
  387. package/test/unit/spec/rtcMetrics/index.ts +122 -0
  388. package/test/unit/spec/stats-analyzer/index.js +1252 -12
  389. package/test/unit/spec/webinar/collection.ts +13 -0
  390. package/test/unit/spec/webinar/index.ts +60 -0
  391. package/test/utils/integrationTestUtils.js +46 -0
  392. package/test/utils/testUtils.js +0 -57
  393. package/test/utils/webex-test-users.js +12 -4
  394. package/dist/metrics/config.js +0 -289
  395. package/dist/metrics/config.js.map +0 -1
  396. package/dist/types/metrics/config.d.ts +0 -169
  397. package/src/index.js +0 -18
  398. package/src/metrics/config.ts +0 -485
@@ -1,5 +1,5 @@
1
1
  import LoggerProxy from '../common/logs/logger-proxy';
2
- import {HTTP_VERBS, RESOURCE, API} from '../constants';
2
+ import {HTTP_VERBS, RESOURCE, API, IP_VERSION} from '../constants';
3
3
 
4
4
  export interface ClusterNode {
5
5
  isVideoMesh: boolean;
@@ -30,9 +30,10 @@ class ReachabilityRequest {
30
30
  /**
31
31
  * Gets the cluster information
32
32
  *
33
+ * @param {IP_VERSION} ipVersion information about current ip network we're on
33
34
  * @returns {Promise}
34
35
  */
35
- getClusters = (): Promise<{clusters: ClusterList; joinCookie: any}> =>
36
+ getClusters = (ipVersion?: IP_VERSION): Promise<{clusters: ClusterList; joinCookie: any}> =>
36
37
  this.webex
37
38
  .request({
38
39
  method: HTTP_VERBS.GET,
@@ -41,17 +42,20 @@ class ReachabilityRequest {
41
42
  resource: RESOURCE.CLUSTERS,
42
43
  qs: {
43
44
  JCSupport: 1,
45
+ ipver: ipVersion,
44
46
  },
45
47
  })
46
48
  .then((res) => {
47
49
  const {clusters, joinCookie} = res.body;
48
50
 
49
51
  Object.keys(clusters).forEach((key) => {
50
- clusters[key].isVideoMesh = res.body.clusterClasses?.hybridMedia?.includes(key);
52
+ clusters[key].isVideoMesh = !!res.body.clusterClasses?.hybridMedia?.includes(key);
51
53
  });
52
54
 
53
55
  LoggerProxy.logger.log(
54
- `Reachability:request#getClusters --> get clusters successful:${JSON.stringify(clusters)}`
56
+ `Reachability:request#getClusters --> get clusters (ipver=${ipVersion}) successful:${JSON.stringify(
57
+ clusters
58
+ )}`
55
59
  );
56
60
 
57
61
  return {
@@ -0,0 +1,24 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ /**
3
+ * Converts a stun url to a turn url
4
+ *
5
+ * @param {string} stunUrl url of a stun server
6
+ * @param {'tcp'|'udp'} protocol what protocol to use for the turn server
7
+ * @returns {string} url of a turn server
8
+ */
9
+ export function convertStunUrlToTurn(stunUrl: string, protocol: 'udp' | 'tcp') {
10
+ // stunUrl looks like this: "stun:external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004"
11
+ // and we need it to be like this: "turn:external-media91.public.wjfkm-a-10.prod.infra.webex.com:5004?transport=tcp"
12
+ const url = new URL(stunUrl);
13
+
14
+ if (url.protocol !== 'stun:') {
15
+ throw new Error(`Not a STUN URL: ${stunUrl}`);
16
+ }
17
+
18
+ url.protocol = 'turn:';
19
+ if (protocol === 'tcp') {
20
+ url.searchParams.append('transport', 'tcp');
21
+ }
22
+
23
+ return url.toString();
24
+ }
@@ -14,14 +14,14 @@ import {
14
14
  _CALL_,
15
15
  _LEFT_,
16
16
  _ID_,
17
+ RECONNECTION_STATE,
17
18
  } from '../constants';
18
19
  import BEHAVIORAL_METRICS from '../metrics/constants';
19
- import ReconnectionError from '../common/errors/reconnection';
20
20
  import ReconnectInProgress from '../common/errors/reconnection-in-progress';
21
- import {eventType, reconnection, errorObjects} from '../metrics/config';
22
- import Media from '../media';
23
21
  import Metrics from '../metrics';
24
22
  import Meeting from '../meeting';
23
+ import {MediaRequestManager} from '../multistream/mediaRequestManager';
24
+ import ReconnectionError from '../common/errors/reconnection';
25
25
 
26
26
  /**
27
27
  * Used to indicate that the reconnect logic needs to be retried.
@@ -97,7 +97,7 @@ export default class ReconnectionManager {
97
97
 
98
98
  /**
99
99
  * @instance
100
- * @type {String}
100
+ * @type {RECONNECTION_STATE}
101
101
  * @private
102
102
  * @memberof ReconnectionManager
103
103
  */
@@ -228,7 +228,32 @@ export default class ReconnectionManager {
228
228
  */
229
229
  public cleanUp() {
230
230
  this.reset();
231
- this.meeting = null;
231
+ }
232
+
233
+ /**
234
+ * Stop the local share stream.
235
+ *
236
+ * @param {string} reason a {@link SHARE_STOPPED_REASON}
237
+ * @returns {undefined}
238
+ * @private
239
+ * @memberof ReconnectionManager
240
+ */
241
+ private async stopLocalShareStream(reason: string) {
242
+ await this.meeting.unpublishStreams([
243
+ this.meeting.mediaProperties.shareVideoStream,
244
+ this.meeting.mediaProperties.shareAudioStream,
245
+ ]);
246
+ Trigger.trigger(
247
+ this.meeting,
248
+ {
249
+ file: 'reconnection-manager/index',
250
+ function: 'stopLocalShareStream',
251
+ },
252
+ EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
253
+ {
254
+ reason,
255
+ }
256
+ );
232
257
  }
233
258
 
234
259
  /**
@@ -240,6 +265,18 @@ export default class ReconnectionManager {
240
265
  return this.status === RECONNECTION.STATE.IN_PROGRESS;
241
266
  }
242
267
 
268
+ /**
269
+ * Sets the reconnection status
270
+ *
271
+ * @public
272
+ * @param {RECONNECTION_STATE} status
273
+ * @memberof ReconnectionManager
274
+ * @returns {undefined}
275
+ */
276
+ public setStatus(status: RECONNECTION_STATE) {
277
+ this.status = status;
278
+ }
279
+
243
280
  /**
244
281
  * @returns {Boolean}
245
282
  * @throws {ReconnectionError}
@@ -302,72 +339,76 @@ export default class ReconnectionManager {
302
339
  LoggerProxy.logger.info(
303
340
  'ReconnectionManager:index#reconnect --> Sending reconnect start metric.'
304
341
  );
305
- Metrics.postEvent({
306
- event: eventType.MEDIA_RECONNECTING,
307
- meeting: this.meeting,
342
+
343
+ // @ts-ignore
344
+ this.webex.internal.newMetrics.submitClientEvent({
345
+ name: 'client.media.reconnecting',
346
+ options: {
347
+ meetingId: this.meeting.id,
348
+ },
308
349
  });
309
350
  }
310
351
 
311
- return this.executeReconnection({networkDisconnect})
312
- .then(() => {
313
- LoggerProxy.logger.info('ReconnectionManager:index#reconnect --> Reconnection successful.');
314
- LoggerProxy.logger.info(
315
- 'ReconnectionManager:index#reconnect --> Sending reconnect success metric.'
316
- );
317
- Metrics.postEvent({
318
- event: eventType.MEDIA_RECOVERED,
319
- meeting: this.meeting,
320
- data: {recoveredBy: reconnection.RECOVERED_BY_NEW},
321
- });
322
- })
323
- .catch((reconnectError) => {
324
- if (reconnectError instanceof NeedsRetryError) {
325
- LoggerProxy.logger.info(
326
- 'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
327
- );
328
- // Reset our reconnect status since we are looping back to the beginning
329
- this.status = RECONNECTION.STATE.DEFAULT_STATUS;
330
-
331
- // This is a network retry, so we should not log START metrics again
332
- return this.reconnect({networkDisconnect: true, networkRetry: true});
333
- }
352
+ try {
353
+ await this.webex.meetings.startReachability();
354
+ } catch (err) {
355
+ LoggerProxy.logger.info(
356
+ 'ReconnectionManager:index#reconnect --> Reachability failed, continuing with reconnection attempt, err: ',
357
+ err
358
+ );
359
+ }
334
360
 
335
- // Reconnect has failed
336
- LoggerProxy.logger.error(
337
- 'ReconnectionManager:index#reconnect --> Reconnection failed.',
338
- reconnectError.message
339
- );
361
+ try {
362
+ const media = await this.executeReconnection({networkDisconnect});
363
+
364
+ return media;
365
+ } catch (reconnectError) {
366
+ if (reconnectError instanceof NeedsRetryError) {
340
367
  LoggerProxy.logger.info(
341
- 'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
368
+ 'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
342
369
  );
370
+ // Reset our reconnect status since we are looping back to the beginning
371
+ this.status = RECONNECTION.STATE.DEFAULT_STATUS;
343
372
 
344
- const reconnectMetric = {
345
- event: eventType.CALL_ABORTED,
346
- meeting: this.meeting,
347
- data: {
348
- errors: [
349
- {
350
- category: errorObjects.category.expected,
351
- errorCode: 2008,
352
- fatal: true,
353
- name: errorObjects.name.mediaEngine,
354
- shownToUser: false,
355
- },
356
- ],
357
- },
358
- };
359
-
360
- Metrics.postEvent(reconnectMetric);
361
- if (reconnectError instanceof NeedsRejoinError) {
362
- // send call aborded event with catogery as expected as we are trying to rejoin
363
-
364
- if (this.autoRejoinEnabled) {
365
- return this.rejoinMeeting(reconnectError.wasSharing);
366
- }
367
- }
373
+ // This is a network retry, so we should not log START metrics again
374
+ return this.reconnect({networkDisconnect: true, networkRetry: true});
375
+ }
376
+
377
+ // Reconnect has failed
378
+ LoggerProxy.logger.error(
379
+ 'ReconnectionManager:index#reconnect --> Reconnection failed.',
380
+ reconnectError.message
381
+ );
382
+ LoggerProxy.logger.info(
383
+ 'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
384
+ );
368
385
 
369
- throw reconnectError;
386
+ // send call aborted event with catogery as expected as we are trying to rejoin
387
+ // @ts-ignore
388
+ this.webex.internal.newMetrics.submitClientEvent({
389
+ name: 'client.call.aborted',
390
+ payload: {
391
+ errors: [
392
+ {
393
+ category: 'expected',
394
+ errorCode: 2008,
395
+ fatal: true,
396
+ name: 'media-engine',
397
+ shownToUser: false,
398
+ },
399
+ ],
400
+ },
401
+ options: {
402
+ meetingId: this.meeting.id,
403
+ },
370
404
  });
405
+
406
+ if (reconnectError instanceof NeedsRejoinError && this.autoRejoinEnabled) {
407
+ return this.rejoinMeeting(reconnectError.wasSharing);
408
+ }
409
+
410
+ throw reconnectError;
411
+ }
371
412
  }
372
413
 
373
414
  /**
@@ -385,6 +426,12 @@ export default class ReconnectionManager {
385
426
  'ReconnectionManager:index#executeReconnection --> Attempting to reconnect to meeting.'
386
427
  );
387
428
 
429
+ const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;
430
+
431
+ if (wasSharing) {
432
+ await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEDIA_RECONNECTION);
433
+ }
434
+
388
435
  if (networkDisconnect) {
389
436
  try {
390
437
  await this.reconnectMercuryWebSocket();
@@ -401,13 +448,11 @@ export default class ReconnectionManager {
401
448
  }
402
449
  }
403
450
 
404
- const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;
405
-
406
451
  try {
407
452
  LoggerProxy.logger.info(
408
453
  'ReconnectionManager:index#executeReconnection --> Updating meeting data from server.'
409
454
  );
410
- await this.webex.meetings.syncMeetings();
455
+ await this.webex.meetings.syncMeetings({keepOnlyLocusMeetings: false});
411
456
  } catch (syncError) {
412
457
  LoggerProxy.logger.info(
413
458
  'ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.',
@@ -420,10 +465,10 @@ export default class ReconnectionManager {
420
465
  // So that on rejoin it known what parametrs it was using
421
466
  if (!this.meeting || !this.webex.meetings.getMeetingByType(_ID_, this.meeting.id)) {
422
467
  LoggerProxy.logger.info(
423
- 'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely '
468
+ 'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely.'
424
469
  );
425
470
 
426
- throw new Error('Unable to rejoin a meeting already ended or inactive .');
471
+ throw new Error('Unable to rejoin a meeting already ended or inactive.');
427
472
  }
428
473
 
429
474
  LoggerProxy.logger.info(
@@ -443,14 +488,13 @@ export default class ReconnectionManager {
443
488
  const media = await this.reconnectMedia();
444
489
 
445
490
  LoggerProxy.logger.log(
446
- 'ReconnectionManager:index#executeReconnection --> Media reestablished'
491
+ 'ReconnectionManager:index#executeReconnection --> webRTC media connection renewed and local sdp offer sent'
447
492
  );
448
- this.status = RECONNECTION.STATE.COMPLETE;
449
493
 
450
494
  return media;
451
495
  } catch (error) {
452
496
  LoggerProxy.logger.error(
453
- 'ReconnectionManager:index#executeReconnection --> Media reestablishment failed'
497
+ 'ReconnectionManager:index#executeReconnection --> failed to renew webRTC media connection or initiate offer'
454
498
  );
455
499
  this.status = RECONNECTION.STATE.FAILURE;
456
500
 
@@ -475,24 +519,7 @@ export default class ReconnectionManager {
475
519
  LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');
476
520
 
477
521
  if (wasSharing) {
478
- // Stop the share streams if user tried to rejoin
479
- this.meeting.setLocalShareTrack(null);
480
- this.meeting.isSharing = false;
481
- if (this.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE) {
482
- this.meeting.shareStatus = SHARE_STATUS.NO_SHARE;
483
- }
484
- this.meeting.mediaProperties.mediaDirection.sendShare = false;
485
- Trigger.trigger(
486
- this.meeting,
487
- {
488
- file: 'reconnection-manager/index',
489
- function: 'rejoinMeeting',
490
- },
491
- EVENT_TRIGGERS.MEETING_STOPPED_SHARING_LOCAL,
492
- {
493
- reason: SHARE_STOPPED_REASON.MEETING_REJOIN,
494
- }
495
- );
522
+ await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEETING_REJOIN);
496
523
  }
497
524
  } catch (joinError) {
498
525
  this.rejoinAttempts += 1;
@@ -534,16 +561,14 @@ export default class ReconnectionManager {
534
561
  * @memberof ReconnectionManager
535
562
  */
536
563
  async reconnectMedia() {
537
- LoggerProxy.logger.log(
538
- 'ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media'
539
- );
564
+ LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> do turn discovery');
540
565
 
541
- // do the TURN server discovery again since the TURN server might change
542
- const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true);
566
+ // do the TURN server discovery again and ignore reachability results since the TURN server might change
567
+ const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true, true);
543
568
 
544
569
  const iceServers = [];
545
570
 
546
- if (turnServerResult.turnServerInfo) {
571
+ if (turnServerResult.turnServerInfo?.url) {
547
572
  iceServers.push({
548
573
  urls: turnServerResult.turnServerInfo.url,
549
574
  username: turnServerResult.turnServerInfo.username || '',
@@ -551,13 +576,19 @@ export default class ReconnectionManager {
551
576
  });
552
577
  }
553
578
 
579
+ LoggerProxy.logger.log(
580
+ 'ReconnectionManager:index#reconnectMedia --> renew webRTC media connection and send local sdp offer'
581
+ );
582
+
554
583
  await this.meeting.mediaProperties.webrtcMediaConnection.reconnect(iceServers);
555
584
 
556
585
  // resend media requests
557
586
  if (this.meeting.isMultistream) {
558
- Object.values(this.meeting.mediaRequestManagers).forEach((mediaRequestManager) =>
559
- // @ts-ignore - Fix type
560
- mediaRequestManager.commit()
587
+ Object.values(this.meeting.mediaRequestManagers).forEach(
588
+ (mediaRequestManager: MediaRequestManager) => {
589
+ mediaRequestManager.clearPreviousRequests();
590
+ mediaRequestManager.commit();
591
+ }
561
592
  );
562
593
  }
563
594
  }
@@ -1,5 +1,5 @@
1
1
  import PermissionError from '../common/errors/permission';
2
- import {CONTROLS, HTTP_VERBS} from '../constants';
2
+ import {CONTROLS, HTTP_VERBS, SELF_POLICY} from '../constants';
3
3
  import MeetingRequest from '../meeting/request';
4
4
  import RecordingAction from './enums';
5
5
  import Util from './util';
@@ -28,6 +28,14 @@ export default class RecordingController {
28
28
  */
29
29
  private displayHints: Array<string> = [];
30
30
 
31
+ /**
32
+ * @instance
33
+ * @type {Object}
34
+ * @private
35
+ * @memberof RecordingInfo
36
+ */
37
+ private selfUserPolicies: Record<SELF_POLICY, boolean>;
38
+
31
39
  /**
32
40
  * @instance
33
41
  * @type {string}
@@ -81,7 +89,6 @@ export default class RecordingController {
81
89
 
82
90
  /**
83
91
  * @param {MeetingRequest} request
84
- * @param {LocusInfo} info
85
92
  * @returns {void}
86
93
  * @private
87
94
  * @memberof RecordingController
@@ -126,6 +133,16 @@ export default class RecordingController {
126
133
  this.displayHints = hints;
127
134
  }
128
135
 
136
+ /**
137
+ * @param {Object} selfUserPolicies
138
+ * @returns {void}
139
+ * @public
140
+ * @memberof RecordingController
141
+ */
142
+ public setUserPolicy(selfUserPolicies: Record<SELF_POLICY, boolean>) {
143
+ this.selfUserPolicies = selfUserPolicies;
144
+ }
145
+
129
146
  /**
130
147
  * @param {string} id
131
148
  * @returns {void}
@@ -264,7 +281,7 @@ export default class RecordingController {
264
281
  );
265
282
 
266
283
  // assumes action is proper cased (i.e., Example)
267
- if (Util?.[`canUser${action}`](this.displayHints)) {
284
+ if (Util?.[`canUser${action}`](this.displayHints, this.selfUserPolicies)) {
268
285
  if (this.serviceUrl) {
269
286
  return this.recordingService(action);
270
287
  }
@@ -1,17 +1,34 @@
1
- import {DISPLAY_HINTS} from '../constants';
1
+ import {DISPLAY_HINTS, SELF_POLICY} from '../constants';
2
2
  import RecordingAction from './enums';
3
+ import MeetingUtil from '../meeting/util';
3
4
 
4
- const canUserStart = (displayHints: Array<string>): boolean =>
5
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START);
5
+ const canUserStart = (
6
+ displayHints: Array<string>,
7
+ userPolicies: Record<SELF_POLICY, boolean>
8
+ ): boolean =>
9
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_START) &&
10
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
6
11
 
7
- const canUserPause = (displayHints: Array<string>): boolean =>
8
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE);
12
+ const canUserPause = (
13
+ displayHints: Array<string>,
14
+ userPolicies: Record<SELF_POLICY, boolean>
15
+ ): boolean =>
16
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_PAUSE) &&
17
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
9
18
 
10
- const canUserResume = (displayHints: Array<string>): boolean =>
11
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME);
19
+ const canUserResume = (
20
+ displayHints: Array<string>,
21
+ userPolicies: Record<SELF_POLICY, boolean>
22
+ ): boolean =>
23
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_RESUME) &&
24
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
12
25
 
13
- const canUserStop = (displayHints: Array<string>): boolean =>
14
- displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP);
26
+ const canUserStop = (
27
+ displayHints: Array<string>,
28
+ userPolicies: Record<SELF_POLICY, boolean>
29
+ ): boolean =>
30
+ displayHints.includes(DISPLAY_HINTS.RECORDING_CONTROL_STOP) &&
31
+ MeetingUtil.selfSupportsFeature(SELF_POLICY.SUPPORT_NETWORK_BASED_RECORD, userPolicies);
15
32
 
16
33
  const extractLocusId = (url: string) => {
17
34
  return url?.split('/').pop();
package/src/roap/index.ts CHANGED
@@ -5,8 +5,17 @@ import {ROAP} from '../constants';
5
5
  import LoggerProxy from '../common/logs/logger-proxy';
6
6
 
7
7
  import RoapRequest from './request';
8
- import TurnDiscovery from './turnDiscovery';
8
+ import TurnDiscovery, {TurnDiscoveryResult} from './turnDiscovery';
9
9
  import Meeting from '../meeting';
10
+ import MeetingUtil from '../meeting/util';
11
+ import Metrics from '../metrics';
12
+ import BEHAVIORAL_METRICS from '../metrics/constants';
13
+
14
+ export {
15
+ type TurnDiscoveryResult,
16
+ type TurnServerInfo,
17
+ type TurnDiscoverySkipReason,
18
+ } from './turnDiscovery';
10
19
 
11
20
  /**
12
21
  * Roap options
@@ -36,7 +45,7 @@ export default class Roap extends StatelessWebexPlugin {
36
45
  options: any;
37
46
  roapHandler: any;
38
47
  roapRequest: any;
39
- turnDiscovery: any;
48
+ turnDiscovery: TurnDiscovery;
40
49
 
41
50
  /**
42
51
  *
@@ -98,11 +107,8 @@ export default class Roap extends StatelessWebexPlugin {
98
107
  roapMessage,
99
108
  locusSelfUrl: meeting.selfUrl,
100
109
  mediaId: options.mediaId,
101
- correlationId: options.correlationId,
102
- audioMuted: meeting.audio?.isLocallyMuted(),
103
- videoMuted: meeting.video?.isLocallyMuted(),
104
110
  meetingId: meeting.id,
105
- preferTranscoding: !meeting.isMultistream,
111
+ locusMediaRequest: meeting.locusMediaRequest,
106
112
  })
107
113
  .then(() => {
108
114
  LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);
@@ -135,11 +141,8 @@ export default class Roap extends StatelessWebexPlugin {
135
141
  roapMessage,
136
142
  locusSelfUrl: meeting.selfUrl,
137
143
  mediaId: options.mediaId,
138
- correlationId: options.correlationId,
139
- audioMuted: meeting.isAudioMuted(),
140
- videoMuted: meeting.isVideoMuted(),
141
144
  meetingId: meeting.id,
142
- preferTranscoding: !meeting.isMultistream,
145
+ locusMediaRequest: meeting.locusMediaRequest,
143
146
  });
144
147
  }
145
148
 
@@ -167,11 +170,8 @@ export default class Roap extends StatelessWebexPlugin {
167
170
  roapMessage,
168
171
  locusSelfUrl: meeting.selfUrl,
169
172
  mediaId: options.mediaId,
170
- correlationId: options.correlationId,
171
- audioMuted: meeting.audio?.isLocallyMuted(),
172
- videoMuted: meeting.video?.isLocallyMuted(),
173
173
  meetingId: meeting.id,
174
- preferTranscoding: !meeting.isMultistream,
174
+ locusMediaRequest: meeting.locusMediaRequest,
175
175
  })
176
176
  .then(() => {
177
177
  LoggerProxy.logger.log(
@@ -187,37 +187,71 @@ export default class Roap extends StatelessWebexPlugin {
187
187
  * @memberof Roap
188
188
  */
189
189
  sendRoapMediaRequest(options: any) {
190
- const {meeting, seq, sdp, reconnect, tieBreaker} = options;
190
+ const {meeting, seq, sdp, tieBreaker} = options;
191
191
  const roapMessage = {
192
192
  messageType: ROAP.ROAP_TYPES.OFFER,
193
193
  sdps: [sdp],
194
194
  version: ROAP.ROAP_VERSION,
195
195
  seq,
196
196
  tieBreaker,
197
+ headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
197
198
  };
198
199
 
199
- // When reconnecting, it's important that the first roap message being sent out has empty media id.
200
- // Normally this is the roap offer, but when TURN discovery is enabled,
201
- // then this is the TURN discovery request message
202
- const sendEmptyMediaId = reconnect && !meeting.config.experimental.enableTurnDiscovery;
200
+ // The only time we want to send an empty media id is when we are reconnecting, because this way we tell Locus
201
+ // that it needs to create a new confluence, but when reconnecting we always send TURN_DISCOVERY_REQUEST first,
202
+ // so we don't need to ever send an empty media id here
203
+ const sendEmptyMediaId = false;
203
204
 
204
205
  return this.roapRequest
205
206
  .sendRoap({
206
207
  roapMessage,
207
- correlationId: meeting.correlationId,
208
208
  locusSelfUrl: meeting.selfUrl,
209
209
  mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
210
- audioMuted: meeting.audio?.isLocallyMuted(),
211
- videoMuted: meeting.video?.isLocallyMuted(),
212
210
  meetingId: meeting.id,
213
211
  preferTranscoding: !meeting.isMultistream,
212
+ locusMediaRequest: meeting.locusMediaRequest,
213
+ ipVersion: MeetingUtil.getIpVersion(meeting.webex),
214
214
  })
215
215
  .then(({locus, mediaConnections}) => {
216
216
  if (mediaConnections) {
217
217
  meeting.updateMediaConnections(mediaConnections);
218
218
  }
219
219
 
220
- return locus;
220
+ let roapAnswer;
221
+
222
+ if (mediaConnections?.[0]?.remoteSdp) {
223
+ const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);
224
+
225
+ if (remoteSdp.roapMessage) {
226
+ const {
227
+ seq: answerSeq,
228
+ messageType,
229
+ sdps,
230
+ errorType,
231
+ errorCause,
232
+ headers,
233
+ } = remoteSdp.roapMessage;
234
+
235
+ roapAnswer = {
236
+ seq: answerSeq,
237
+ messageType,
238
+ sdp: sdps[0],
239
+ errorType,
240
+ errorCause,
241
+ headers,
242
+ };
243
+ }
244
+ }
245
+
246
+ if (!roapAnswer) {
247
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {
248
+ correlationId: meeting.correlationId,
249
+ messageType: 'ANSWER',
250
+ isMultistream: meeting.isMultistream,
251
+ });
252
+ }
253
+
254
+ return {locus, roapAnswer};
221
255
  });
222
256
  }
223
257
 
@@ -229,9 +263,26 @@ export default class Roap extends StatelessWebexPlugin {
229
263
  * @param {Meeting} meeting
230
264
  * @param {Boolean} isReconnecting should be set to true if this is a new
231
265
  * media connection just after a reconnection
266
+ * @param {Boolean} [isForced]
232
267
  * @returns {Promise}
233
268
  */
234
- doTurnDiscovery(meeting: Meeting, isReconnecting: boolean) {
235
- return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting);
269
+ doTurnDiscovery(
270
+ meeting: Meeting,
271
+ isReconnecting: boolean,
272
+ isForced?: boolean
273
+ ): Promise<TurnDiscoveryResult> {
274
+ return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting, isForced);
275
+ }
276
+
277
+ generateTurnDiscoveryRequestMessage(meeting: Meeting, isForced: boolean) {
278
+ return this.turnDiscovery.generateTurnDiscoveryRequestMessage(meeting, isForced);
279
+ }
280
+
281
+ handleTurnDiscoveryHttpResponse(meeting: Meeting, httpResponse: object) {
282
+ return this.turnDiscovery.handleTurnDiscoveryHttpResponse(meeting, httpResponse);
283
+ }
284
+
285
+ abortTurnDiscovery() {
286
+ return this.turnDiscovery.abort();
236
287
  }
237
288
  }