@webex/plugin-meetings 3.0.0-beta.34 → 3.0.0-beta.340

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 (392) hide show
  1. package/README.md +46 -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/edit-lock-error.js +52 -0
  11. package/dist/breakouts/edit-lock-error.js.map +1 -0
  12. package/dist/breakouts/events.js +45 -0
  13. package/dist/breakouts/events.js.map +1 -0
  14. package/dist/breakouts/index.js +709 -35
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/utils.js +45 -1
  17. package/dist/breakouts/utils.js.map +1 -1
  18. package/dist/common/errors/no-meeting-info.js +51 -0
  19. package/dist/common/errors/no-meeting-info.js.map +1 -0
  20. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  21. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +48 -7
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/common/logs/request.js +5 -1
  27. package/dist/common/logs/request.js.map +1 -1
  28. package/dist/common/queue.js +24 -9
  29. package/dist/common/queue.js.map +1 -1
  30. package/dist/config.js +5 -10
  31. package/dist/config.js.map +1 -1
  32. package/dist/constants.js +233 -29
  33. package/dist/constants.js.map +1 -1
  34. package/dist/controls-options-manager/enums.js +14 -2
  35. package/dist/controls-options-manager/enums.js.map +1 -1
  36. package/dist/controls-options-manager/index.js +109 -15
  37. package/dist/controls-options-manager/index.js.map +1 -1
  38. package/dist/controls-options-manager/types.js +7 -0
  39. package/dist/controls-options-manager/types.js.map +1 -0
  40. package/dist/controls-options-manager/util.js +309 -18
  41. package/dist/controls-options-manager/util.js.map +1 -1
  42. package/dist/index.js +112 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/interpretation/collection.js +23 -0
  45. package/dist/interpretation/collection.js.map +1 -0
  46. package/dist/interpretation/index.js +366 -0
  47. package/dist/interpretation/index.js.map +1 -0
  48. package/dist/interpretation/siLanguage.js +25 -0
  49. package/dist/interpretation/siLanguage.js.map +1 -0
  50. package/dist/locus-info/controlsUtils.js +91 -2
  51. package/dist/locus-info/controlsUtils.js.map +1 -1
  52. package/dist/locus-info/index.js +383 -62
  53. package/dist/locus-info/index.js.map +1 -1
  54. package/dist/locus-info/infoUtils.js +7 -1
  55. package/dist/locus-info/infoUtils.js.map +1 -1
  56. package/dist/locus-info/mediaSharesUtils.js +57 -1
  57. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  58. package/dist/locus-info/parser.js +249 -72
  59. package/dist/locus-info/parser.js.map +1 -1
  60. package/dist/locus-info/selfUtils.js +89 -14
  61. package/dist/locus-info/selfUtils.js.map +1 -1
  62. package/dist/media/index.js +62 -116
  63. package/dist/media/index.js.map +1 -1
  64. package/dist/media/properties.js +73 -124
  65. package/dist/media/properties.js.map +1 -1
  66. package/dist/mediaQualityMetrics/config.js +1 -204
  67. package/dist/mediaQualityMetrics/config.js.map +1 -1
  68. package/dist/meeting/in-meeting-actions.js +86 -2
  69. package/dist/meeting/in-meeting-actions.js.map +1 -1
  70. package/dist/meeting/index.js +3927 -2960
  71. package/dist/meeting/index.js.map +1 -1
  72. package/dist/meeting/locusMediaRequest.js +292 -0
  73. package/dist/meeting/locusMediaRequest.js.map +1 -0
  74. package/dist/meeting/muteState.js +224 -131
  75. package/dist/meeting/muteState.js.map +1 -1
  76. package/dist/meeting/request.js +260 -196
  77. package/dist/meeting/request.js.map +1 -1
  78. package/dist/meeting/util.js +601 -417
  79. package/dist/meeting/util.js.map +1 -1
  80. package/dist/meeting-info/index.js +73 -7
  81. package/dist/meeting-info/index.js.map +1 -1
  82. package/dist/meeting-info/meeting-info-v2.js +192 -51
  83. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  84. package/dist/meeting-info/util.js +1 -1
  85. package/dist/meeting-info/util.js.map +1 -1
  86. package/dist/meeting-info/utilv2.js +36 -36
  87. package/dist/meeting-info/utilv2.js.map +1 -1
  88. package/dist/meetings/collection.js +39 -0
  89. package/dist/meetings/collection.js.map +1 -1
  90. package/dist/meetings/index.js +424 -116
  91. package/dist/meetings/index.js.map +1 -1
  92. package/dist/meetings/meetings.types.js +7 -0
  93. package/dist/meetings/meetings.types.js.map +1 -0
  94. package/dist/meetings/request.js +2 -0
  95. package/dist/meetings/request.js.map +1 -1
  96. package/dist/meetings/util.js +72 -6
  97. package/dist/meetings/util.js.map +1 -1
  98. package/dist/member/index.js +58 -0
  99. package/dist/member/index.js.map +1 -1
  100. package/dist/member/types.js +25 -0
  101. package/dist/member/types.js.map +1 -0
  102. package/dist/member/util.js +132 -25
  103. package/dist/member/util.js.map +1 -1
  104. package/dist/members/collection.js +10 -0
  105. package/dist/members/collection.js.map +1 -1
  106. package/dist/members/index.js +102 -6
  107. package/dist/members/index.js.map +1 -1
  108. package/dist/members/request.js +106 -38
  109. package/dist/members/request.js.map +1 -1
  110. package/dist/members/types.js +15 -0
  111. package/dist/members/types.js.map +1 -0
  112. package/dist/members/util.js +326 -232
  113. package/dist/members/util.js.map +1 -1
  114. package/dist/metrics/constants.js +16 -5
  115. package/dist/metrics/constants.js.map +1 -1
  116. package/dist/metrics/index.js +1 -446
  117. package/dist/metrics/index.js.map +1 -1
  118. package/dist/multistream/mediaRequestManager.js +228 -58
  119. package/dist/multistream/mediaRequestManager.js.map +1 -1
  120. package/dist/multistream/receiveSlot.js +29 -16
  121. package/dist/multistream/receiveSlot.js.map +1 -1
  122. package/dist/multistream/receiveSlotManager.js +39 -36
  123. package/dist/multistream/receiveSlotManager.js.map +1 -1
  124. package/dist/multistream/remoteMedia.js +44 -18
  125. package/dist/multistream/remoteMedia.js.map +1 -1
  126. package/dist/multistream/remoteMediaGroup.js +60 -3
  127. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  128. package/dist/multistream/remoteMediaManager.js +209 -59
  129. package/dist/multistream/remoteMediaManager.js.map +1 -1
  130. package/dist/multistream/sendSlotManager.js +233 -0
  131. package/dist/multistream/sendSlotManager.js.map +1 -0
  132. package/dist/reachability/clusterReachability.js +356 -0
  133. package/dist/reachability/clusterReachability.js.map +1 -0
  134. package/dist/reachability/index.js +273 -391
  135. package/dist/reachability/index.js.map +1 -1
  136. package/dist/reachability/request.js +17 -8
  137. package/dist/reachability/request.js.map +1 -1
  138. package/dist/reachability/util.js +29 -0
  139. package/dist/reachability/util.js.map +1 -0
  140. package/dist/reconnection-manager/index.js +214 -170
  141. package/dist/reconnection-manager/index.js.map +1 -1
  142. package/dist/recording-controller/index.js +21 -2
  143. package/dist/recording-controller/index.js.map +1 -1
  144. package/dist/recording-controller/util.js +9 -8
  145. package/dist/recording-controller/util.js.map +1 -1
  146. package/dist/roap/index.js +62 -35
  147. package/dist/roap/index.js.map +1 -1
  148. package/dist/roap/request.js +112 -97
  149. package/dist/roap/request.js.map +1 -1
  150. package/dist/roap/turnDiscovery.js +95 -38
  151. package/dist/roap/turnDiscovery.js.map +1 -1
  152. package/dist/rtcMetrics/constants.js +12 -0
  153. package/dist/rtcMetrics/constants.js.map +1 -0
  154. package/dist/rtcMetrics/index.js +142 -0
  155. package/dist/rtcMetrics/index.js.map +1 -0
  156. package/dist/statsAnalyzer/index.js +181 -214
  157. package/dist/statsAnalyzer/index.js.map +1 -1
  158. package/dist/statsAnalyzer/mqaUtil.js +22 -18
  159. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  160. package/dist/types/annotation/annotation.types.d.ts +42 -0
  161. package/dist/types/annotation/constants.d.ts +31 -0
  162. package/dist/types/annotation/index.d.ts +117 -0
  163. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  164. package/dist/types/breakouts/events.d.ts +8 -0
  165. package/dist/types/breakouts/utils.d.ts +14 -0
  166. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  167. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  168. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  169. package/dist/types/common/logs/request.d.ts +2 -0
  170. package/dist/types/common/queue.d.ts +9 -7
  171. package/dist/types/config.d.ts +2 -7
  172. package/dist/types/constants.d.ts +201 -30
  173. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  174. package/dist/types/controls-options-manager/index.d.ts +17 -1
  175. package/dist/types/controls-options-manager/types.d.ts +43 -0
  176. package/dist/types/controls-options-manager/util.d.ts +1 -7
  177. package/dist/types/index.d.ts +6 -4
  178. package/dist/types/interpretation/collection.d.ts +5 -0
  179. package/dist/types/interpretation/index.d.ts +5 -0
  180. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  181. package/dist/types/locus-info/index.d.ts +57 -4
  182. package/dist/types/locus-info/parser.d.ts +66 -6
  183. package/dist/types/media/index.d.ts +2 -0
  184. package/dist/types/media/properties.d.ts +34 -48
  185. package/dist/types/mediaQualityMetrics/config.d.ts +0 -128
  186. package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
  187. package/dist/types/meeting/index.d.ts +506 -512
  188. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  189. package/dist/types/meeting/muteState.d.ts +93 -25
  190. package/dist/types/meeting/request.d.ts +72 -43
  191. package/dist/types/meeting/util.d.ts +101 -1
  192. package/dist/types/meeting-info/index.d.ts +13 -1
  193. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  194. package/dist/types/meetings/collection.d.ts +17 -0
  195. package/dist/types/meetings/index.d.ts +91 -21
  196. package/dist/types/meetings/meetings.types.d.ts +4 -0
  197. package/dist/types/member/index.d.ts +14 -0
  198. package/dist/types/member/types.d.ts +32 -0
  199. package/dist/types/members/collection.d.ts +5 -0
  200. package/dist/types/members/index.d.ts +35 -2
  201. package/dist/types/members/request.d.ts +73 -9
  202. package/dist/types/members/types.d.ts +25 -0
  203. package/dist/types/members/util.d.ts +214 -1
  204. package/dist/types/metrics/constants.d.ts +15 -4
  205. package/dist/types/metrics/index.d.ts +4 -111
  206. package/dist/types/multistream/mediaRequestManager.d.ts +72 -5
  207. package/dist/types/multistream/receiveSlot.d.ts +13 -11
  208. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  209. package/dist/types/multistream/remoteMedia.d.ts +8 -29
  210. package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
  211. package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
  212. package/dist/types/multistream/sendSlotManager.d.ts +61 -0
  213. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  214. package/dist/types/reachability/index.d.ts +60 -95
  215. package/dist/types/reachability/request.d.ts +7 -3
  216. package/dist/types/reachability/util.d.ts +8 -0
  217. package/dist/types/reconnection-manager/index.d.ts +19 -0
  218. package/dist/types/recording-controller/index.d.ts +15 -1
  219. package/dist/types/recording-controller/util.d.ts +5 -4
  220. package/dist/types/roap/index.d.ts +2 -1
  221. package/dist/types/roap/request.d.ts +15 -11
  222. package/dist/types/roap/turnDiscovery.d.ts +21 -3
  223. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  224. package/dist/types/rtcMetrics/index.d.ts +54 -0
  225. package/dist/types/statsAnalyzer/index.d.ts +29 -11
  226. package/dist/types/webinar/collection.d.ts +16 -0
  227. package/dist/types/webinar/index.d.ts +5 -0
  228. package/dist/webinar/collection.js +44 -0
  229. package/dist/webinar/collection.js.map +1 -0
  230. package/dist/webinar/index.js +69 -0
  231. package/dist/webinar/index.js.map +1 -0
  232. package/package.json +22 -19
  233. package/src/annotation/annotation.types.ts +50 -0
  234. package/src/annotation/constants.ts +36 -0
  235. package/src/annotation/index.ts +328 -0
  236. package/src/breakouts/README.md +42 -12
  237. package/src/breakouts/breakout.ts +67 -9
  238. package/src/breakouts/edit-lock-error.ts +25 -0
  239. package/src/breakouts/events.ts +56 -0
  240. package/src/breakouts/index.ts +592 -20
  241. package/src/breakouts/utils.ts +42 -0
  242. package/src/common/errors/no-meeting-info.ts +24 -0
  243. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  244. package/src/common/errors/webex-errors.ts +44 -2
  245. package/src/common/logs/logger-proxy.ts +1 -1
  246. package/src/common/logs/request.ts +5 -1
  247. package/src/common/queue.ts +22 -8
  248. package/src/config.ts +4 -9
  249. package/src/constants.ts +224 -20
  250. package/src/controls-options-manager/enums.ts +12 -0
  251. package/src/controls-options-manager/index.ts +116 -21
  252. package/src/controls-options-manager/types.ts +59 -0
  253. package/src/controls-options-manager/util.ts +294 -14
  254. package/src/index.ts +40 -0
  255. package/src/interpretation/README.md +60 -0
  256. package/src/interpretation/collection.ts +19 -0
  257. package/src/interpretation/index.ts +332 -0
  258. package/src/interpretation/siLanguage.ts +18 -0
  259. package/src/locus-info/controlsUtils.ts +108 -0
  260. package/src/locus-info/index.ts +413 -59
  261. package/src/locus-info/infoUtils.ts +10 -2
  262. package/src/locus-info/mediaSharesUtils.ts +64 -0
  263. package/src/locus-info/parser.ts +258 -47
  264. package/src/locus-info/selfUtils.ts +81 -5
  265. package/src/media/index.ts +102 -122
  266. package/src/media/properties.ts +87 -110
  267. package/src/mediaQualityMetrics/config.ts +0 -135
  268. package/src/meeting/in-meeting-actions.ts +171 -3
  269. package/src/meeting/index.ts +3276 -2555
  270. package/src/meeting/locusMediaRequest.ts +313 -0
  271. package/src/meeting/muteState.ts +223 -136
  272. package/src/meeting/request.ts +177 -121
  273. package/src/meeting/util.ts +588 -394
  274. package/src/meeting-info/index.ts +81 -8
  275. package/src/meeting-info/meeting-info-v2.ts +170 -14
  276. package/src/meeting-info/util.ts +1 -1
  277. package/src/meeting-info/utilv2.ts +23 -23
  278. package/src/meetings/collection.ts +33 -0
  279. package/src/meetings/index.ts +454 -125
  280. package/src/meetings/meetings.types.ts +12 -0
  281. package/src/meetings/request.ts +2 -0
  282. package/src/meetings/util.ts +80 -11
  283. package/src/member/index.ts +58 -0
  284. package/src/member/types.ts +38 -0
  285. package/src/member/util.ts +141 -25
  286. package/src/members/collection.ts +8 -0
  287. package/src/members/index.ts +134 -8
  288. package/src/members/request.ts +97 -17
  289. package/src/members/types.ts +29 -0
  290. package/src/members/util.ts +333 -240
  291. package/src/metrics/constants.ts +15 -4
  292. package/src/metrics/index.ts +1 -469
  293. package/src/multistream/mediaRequestManager.ts +277 -82
  294. package/src/multistream/receiveSlot.ts +31 -17
  295. package/src/multistream/receiveSlotManager.ts +34 -24
  296. package/src/multistream/remoteMedia.ts +27 -2
  297. package/src/multistream/remoteMediaGroup.ts +59 -0
  298. package/src/multistream/remoteMediaManager.ts +148 -30
  299. package/src/multistream/sendSlotManager.ts +170 -0
  300. package/src/reachability/clusterReachability.ts +320 -0
  301. package/src/reachability/index.ts +236 -342
  302. package/src/reachability/request.ts +17 -8
  303. package/src/reachability/util.ts +24 -0
  304. package/src/reconnection-manager/index.ts +128 -106
  305. package/src/recording-controller/index.ts +20 -3
  306. package/src/recording-controller/util.ts +26 -9
  307. package/src/roap/index.ts +63 -32
  308. package/src/roap/request.ts +100 -104
  309. package/src/roap/turnDiscovery.ts +48 -26
  310. package/src/rtcMetrics/constants.ts +3 -0
  311. package/src/rtcMetrics/index.ts +124 -0
  312. package/src/statsAnalyzer/index.ts +218 -289
  313. package/src/statsAnalyzer/mqaUtil.ts +28 -30
  314. package/src/webinar/collection.ts +31 -0
  315. package/src/webinar/index.ts +62 -0
  316. package/test/integration/spec/converged-space-meetings.js +60 -3
  317. package/test/integration/spec/journey.js +320 -261
  318. package/test/integration/spec/space-meeting.js +76 -3
  319. package/test/unit/spec/annotation/index.ts +418 -0
  320. package/test/unit/spec/breakouts/breakout.ts +118 -28
  321. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  322. package/test/unit/spec/breakouts/events.ts +89 -0
  323. package/test/unit/spec/breakouts/index.ts +1395 -69
  324. package/test/unit/spec/breakouts/utils.js +52 -1
  325. package/test/unit/spec/common/queue.js +31 -2
  326. package/test/unit/spec/controls-options-manager/index.js +163 -0
  327. package/test/unit/spec/controls-options-manager/util.js +576 -60
  328. package/test/unit/spec/fixture/locus.js +1 -0
  329. package/test/unit/spec/interpretation/collection.ts +15 -0
  330. package/test/unit/spec/interpretation/index.ts +589 -0
  331. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  332. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  333. package/test/unit/spec/locus-info/index.js +1304 -33
  334. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  335. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  336. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  337. package/test/unit/spec/locus-info/parser.js +116 -35
  338. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  339. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  340. package/test/unit/spec/media/index.ts +120 -37
  341. package/test/unit/spec/media/properties.ts +2 -2
  342. package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
  343. package/test/unit/spec/meeting/index.js +5849 -2014
  344. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  345. package/test/unit/spec/meeting/muteState.js +402 -213
  346. package/test/unit/spec/meeting/request.js +483 -49
  347. package/test/unit/spec/meeting/utils.js +679 -64
  348. package/test/unit/spec/meeting-info/index.js +300 -0
  349. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  350. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  351. package/test/unit/spec/meetings/collection.js +26 -0
  352. package/test/unit/spec/meetings/index.js +1231 -212
  353. package/test/unit/spec/meetings/utils.js +202 -2
  354. package/test/unit/spec/member/index.js +61 -6
  355. package/test/unit/spec/member/util.js +510 -34
  356. package/test/unit/spec/members/index.js +432 -1
  357. package/test/unit/spec/members/request.js +206 -27
  358. package/test/unit/spec/members/utils.js +210 -0
  359. package/test/unit/spec/metrics/index.js +1 -50
  360. package/test/unit/spec/multistream/mediaRequestManager.ts +776 -162
  361. package/test/unit/spec/multistream/receiveSlot.ts +28 -20
  362. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  363. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  364. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  365. package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
  366. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  367. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  368. package/test/unit/spec/reachability/index.ts +486 -13
  369. package/test/unit/spec/reachability/request.js +68 -0
  370. package/test/unit/spec/reachability/util.ts +40 -0
  371. package/test/unit/spec/reconnection-manager/index.js +117 -11
  372. package/test/unit/spec/recording-controller/index.js +294 -218
  373. package/test/unit/spec/recording-controller/util.js +223 -96
  374. package/test/unit/spec/roap/index.ts +174 -63
  375. package/test/unit/spec/roap/request.ts +226 -85
  376. package/test/unit/spec/roap/turnDiscovery.ts +76 -34
  377. package/test/unit/spec/rtcMetrics/index.ts +93 -0
  378. package/test/unit/spec/stats-analyzer/index.js +231 -7
  379. package/test/unit/spec/webinar/collection.ts +13 -0
  380. package/test/unit/spec/webinar/index.ts +60 -0
  381. package/test/utils/integrationTestUtils.js +46 -0
  382. package/test/utils/testUtils.js +0 -52
  383. package/dist/meeting/effectsState.js +0 -262
  384. package/dist/meeting/effectsState.js.map +0 -1
  385. package/dist/metrics/config.js +0 -289
  386. package/dist/metrics/config.js.map +0 -1
  387. package/dist/types/meeting/effectsState.d.ts +0 -42
  388. package/dist/types/metrics/config.d.ts +0 -169
  389. package/src/index.js +0 -16
  390. package/src/meeting/effectsState.ts +0 -211
  391. package/src/metrics/config.ts +0 -485
  392. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -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;
@@ -28,31 +28,40 @@ class ReachabilityRequest {
28
28
  }
29
29
 
30
30
  /**
31
- * gets the cluster information
31
+ * Gets the cluster information
32
32
  *
33
- * @param {boolean} includeVideoMesh whether to include the video mesh clusters in the result or not
33
+ * @param {IP_VERSION} ipVersion information about current ip network we're on
34
34
  * @returns {Promise}
35
35
  */
36
- getClusters = (): Promise<ClusterList> =>
36
+ getClusters = (ipVersion?: IP_VERSION): Promise<{clusters: ClusterList; joinCookie: any}> =>
37
37
  this.webex
38
38
  .request({
39
39
  method: HTTP_VERBS.GET,
40
40
  shouldRefreshAccessToken: false,
41
41
  api: API.CALLIOPEDISCOVERY,
42
42
  resource: RESOURCE.CLUSTERS,
43
+ qs: {
44
+ JCSupport: 1,
45
+ ipver: ipVersion,
46
+ },
43
47
  })
44
48
  .then((res) => {
45
- const {clusters} = res.body;
49
+ const {clusters, joinCookie} = res.body;
46
50
 
47
51
  Object.keys(clusters).forEach((key) => {
48
- clusters[key].isVideoMesh = res.body.clusterClasses?.hybridMedia?.includes(key);
52
+ clusters[key].isVideoMesh = !!res.body.clusterClasses?.hybridMedia?.includes(key);
49
53
  });
50
54
 
51
55
  LoggerProxy.logger.log(
52
- `Reachability:request#getClusters --> get clusters successful:${JSON.stringify(clusters)}`
56
+ `Reachability:request#getClusters --> get clusters (ipver=${ipVersion}) successful:${JSON.stringify(
57
+ clusters
58
+ )}`
53
59
  );
54
60
 
55
- return clusters;
61
+ return {
62
+ clusters,
63
+ joinCookie,
64
+ };
56
65
  });
57
66
 
58
67
  /**
@@ -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,65 @@ 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.');
352
+ return this.executeReconnection({networkDisconnect}).catch((reconnectError) => {
353
+ if (reconnectError instanceof NeedsRetryError) {
314
354
  LoggerProxy.logger.info(
315
- 'ReconnectionManager:index#reconnect --> Sending reconnect success metric.'
355
+ 'ReconnectionManager:index#reconnect --> Reconnection not successful, retrying.'
316
356
  );
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
- }
357
+ // Reset our reconnect status since we are looping back to the beginning
358
+ this.status = RECONNECTION.STATE.DEFAULT_STATUS;
334
359
 
335
- // Reconnect has failed
336
- LoggerProxy.logger.error(
337
- 'ReconnectionManager:index#reconnect --> Reconnection failed.',
338
- reconnectError.message
339
- );
340
- LoggerProxy.logger.info(
341
- 'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
342
- );
360
+ // This is a network retry, so we should not log START metrics again
361
+ return this.reconnect({networkDisconnect: true, networkRetry: true});
362
+ }
343
363
 
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
- }
364
+ // Reconnect has failed
365
+ LoggerProxy.logger.error(
366
+ 'ReconnectionManager:index#reconnect --> Reconnection failed.',
367
+ reconnectError.message
368
+ );
369
+ LoggerProxy.logger.info(
370
+ 'ReconnectionManager:index#reconnect --> Sending reconnect abort metric.'
371
+ );
368
372
 
369
- throw reconnectError;
373
+ // @ts-ignore
374
+ this.webex.internal.newMetrics.submitClientEvent({
375
+ name: 'client.call.aborted',
376
+ payload: {
377
+ errors: [
378
+ {
379
+ category: 'expected',
380
+ errorCode: 2008,
381
+ fatal: true,
382
+ name: 'media-engine',
383
+ shownToUser: false,
384
+ },
385
+ ],
386
+ },
387
+ options: {
388
+ meetingId: this.meeting.id,
389
+ },
370
390
  });
391
+ if (reconnectError instanceof NeedsRejoinError) {
392
+ // send call aborded event with catogery as expected as we are trying to rejoin
393
+
394
+ if (this.autoRejoinEnabled) {
395
+ return this.rejoinMeeting(reconnectError.wasSharing);
396
+ }
397
+ }
398
+
399
+ throw reconnectError;
400
+ });
371
401
  }
372
402
 
373
403
  /**
@@ -385,6 +415,12 @@ export default class ReconnectionManager {
385
415
  'ReconnectionManager:index#executeReconnection --> Attempting to reconnect to meeting.'
386
416
  );
387
417
 
418
+ const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;
419
+
420
+ if (wasSharing) {
421
+ await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEDIA_RECONNECTION);
422
+ }
423
+
388
424
  if (networkDisconnect) {
389
425
  try {
390
426
  await this.reconnectMercuryWebSocket();
@@ -401,29 +437,29 @@ export default class ReconnectionManager {
401
437
  }
402
438
  }
403
439
 
404
- const wasSharing = this.meeting.shareStatus === SHARE_STATUS.LOCAL_SHARE_ACTIVE;
405
-
406
- try {
407
- LoggerProxy.logger.info(
408
- 'ReconnectionManager:index#executeReconnection --> Updating meeting data from server.'
409
- );
410
- await this.webex.meetings.syncMeetings();
411
- } catch (syncError) {
412
- LoggerProxy.logger.info(
413
- 'ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.',
414
- syncError
415
- );
416
- throw new NeedsRetryError(syncError);
440
+ if (!this.webex.credentials.isUnverifiedGuest) {
441
+ try {
442
+ LoggerProxy.logger.info(
443
+ 'ReconnectionManager:index#executeReconnection --> Updating meeting data from server.'
444
+ );
445
+ await this.webex.meetings.syncMeetings();
446
+ } catch (syncError) {
447
+ LoggerProxy.logger.info(
448
+ 'ReconnectionManager:index#executeReconnection --> Unable to sync meetings, reconnecting.',
449
+ syncError
450
+ );
451
+ throw new NeedsRetryError(syncError);
452
+ }
417
453
  }
418
454
 
419
455
  // TODO: try to improve this logic as the reconnection manager saves the instance of deleted meeting object
420
456
  // So that on rejoin it known what parametrs it was using
421
457
  if (!this.meeting || !this.webex.meetings.getMeetingByType(_ID_, this.meeting.id)) {
422
458
  LoggerProxy.logger.info(
423
- 'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely '
459
+ 'ReconnectionManager:index#executeReconnection --> Meeting got deleted due to inactivity or ended remotely.'
424
460
  );
425
461
 
426
- throw new Error('Unable to rejoin a meeting already ended or inactive .');
462
+ throw new Error('Unable to rejoin a meeting already ended or inactive.');
427
463
  }
428
464
 
429
465
  LoggerProxy.logger.info(
@@ -443,14 +479,13 @@ export default class ReconnectionManager {
443
479
  const media = await this.reconnectMedia();
444
480
 
445
481
  LoggerProxy.logger.log(
446
- 'ReconnectionManager:index#executeReconnection --> Media reestablished'
482
+ 'ReconnectionManager:index#executeReconnection --> webRTC media connection renewed and local sdp offer sent'
447
483
  );
448
- this.status = RECONNECTION.STATE.COMPLETE;
449
484
 
450
485
  return media;
451
486
  } catch (error) {
452
487
  LoggerProxy.logger.error(
453
- 'ReconnectionManager:index#executeReconnection --> Media reestablishment failed'
488
+ 'ReconnectionManager:index#executeReconnection --> failed to renew webRTC media connection or initiate offer'
454
489
  );
455
490
  this.status = RECONNECTION.STATE.FAILURE;
456
491
 
@@ -475,24 +510,7 @@ export default class ReconnectionManager {
475
510
  LoggerProxy.logger.info('ReconnectionManager:index#rejoinMeeting --> meeting rejoined');
476
511
 
477
512
  if (wasSharing) {
478
- // Stop the share streams if user tried to rejoin
479
- Media.stopTracks(this.meeting.mediaProperties.shareTrack);
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
- );
513
+ await this.stopLocalShareStream(SHARE_STOPPED_REASON.MEETING_REJOIN);
496
514
  }
497
515
  } catch (joinError) {
498
516
  this.rejoinAttempts += 1;
@@ -534,12 +552,10 @@ export default class ReconnectionManager {
534
552
  * @memberof ReconnectionManager
535
553
  */
536
554
  async reconnectMedia() {
537
- LoggerProxy.logger.log(
538
- 'ReconnectionManager:index#reconnectMedia --> Begin reestablishment of media'
539
- );
555
+ LoggerProxy.logger.log('ReconnectionManager:index#reconnectMedia --> do turn discovery');
540
556
 
541
- // do the TURN server discovery again since the TURN server might change
542
- const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true);
557
+ // do the TURN server discovery again and ignore reachability results since the TURN server might change
558
+ const turnServerResult = await this.meeting.roap.doTurnDiscovery(this.meeting, true, true);
543
559
 
544
560
  const iceServers = [];
545
561
 
@@ -551,13 +567,19 @@ export default class ReconnectionManager {
551
567
  });
552
568
  }
553
569
 
570
+ LoggerProxy.logger.log(
571
+ 'ReconnectionManager:index#reconnectMedia --> renew webRTC media connection and send local sdp offer'
572
+ );
573
+
554
574
  await this.meeting.mediaProperties.webrtcMediaConnection.reconnect(iceServers);
555
575
 
556
576
  // resend media requests
557
577
  if (this.meeting.isMultistream) {
558
- Object.values(this.meeting.mediaRequestManagers).forEach((mediaRequestManager) =>
559
- // @ts-ignore - Fix type
560
- mediaRequestManager.commit()
578
+ Object.values(this.meeting.mediaRequestManagers).forEach(
579
+ (mediaRequestManager: MediaRequestManager) => {
580
+ mediaRequestManager.clearPreviousRequests();
581
+ mediaRequestManager.commit();
582
+ }
561
583
  );
562
584
  }
563
585
  }
@@ -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
@@ -7,6 +7,9 @@ import LoggerProxy from '../common/logs/logger-proxy';
7
7
  import RoapRequest from './request';
8
8
  import TurnDiscovery 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';
10
13
 
11
14
  /**
12
15
  * Roap options
@@ -98,11 +101,8 @@ export default class Roap extends StatelessWebexPlugin {
98
101
  roapMessage,
99
102
  locusSelfUrl: meeting.selfUrl,
100
103
  mediaId: options.mediaId,
101
- correlationId: options.correlationId,
102
- audioMuted: meeting.audio?.isLocallyMuted(),
103
- videoMuted: meeting.video?.isLocallyMuted(),
104
104
  meetingId: meeting.id,
105
- preferTranscoding: !meeting.isMultistream,
105
+ locusMediaRequest: meeting.locusMediaRequest,
106
106
  })
107
107
  .then(() => {
108
108
  LoggerProxy.logger.log(`Roap:index#sendRoapOK --> ROAP OK sent with seq ${options.seq}`);
@@ -135,11 +135,8 @@ export default class Roap extends StatelessWebexPlugin {
135
135
  roapMessage,
136
136
  locusSelfUrl: meeting.selfUrl,
137
137
  mediaId: options.mediaId,
138
- correlationId: options.correlationId,
139
- audioMuted: meeting.isAudioMuted(),
140
- videoMuted: meeting.isVideoMuted(),
141
138
  meetingId: meeting.id,
142
- preferTranscoding: !meeting.isMultistream,
139
+ locusMediaRequest: meeting.locusMediaRequest,
143
140
  });
144
141
  }
145
142
 
@@ -167,11 +164,8 @@ export default class Roap extends StatelessWebexPlugin {
167
164
  roapMessage,
168
165
  locusSelfUrl: meeting.selfUrl,
169
166
  mediaId: options.mediaId,
170
- correlationId: options.correlationId,
171
- audioMuted: meeting.audio?.isLocallyMuted(),
172
- videoMuted: meeting.video?.isLocallyMuted(),
173
167
  meetingId: meeting.id,
174
- preferTranscoding: !meeting.isMultistream,
168
+ locusMediaRequest: meeting.locusMediaRequest,
175
169
  })
176
170
  .then(() => {
177
171
  LoggerProxy.logger.log(
@@ -194,31 +188,67 @@ export default class Roap extends StatelessWebexPlugin {
194
188
  version: ROAP.ROAP_VERSION,
195
189
  seq,
196
190
  tieBreaker,
191
+ headers: ['includeAnswerInHttpResponse', 'noOkInTransaction'],
197
192
  };
198
193
 
199
194
  // When reconnecting, it's important that the first roap message being sent out has empty media id.
200
195
  // Normally this is the roap offer, but when TURN discovery is enabled,
201
196
  // then this is the TURN discovery request message
202
- const sendEmptyMediaId = reconnect && !meeting.config.experimental.enableTurnDiscovery;
197
+ return this.turnDiscovery.isSkipped(meeting).then((isTurnDiscoverySkipped) => {
198
+ const sendEmptyMediaId = reconnect && isTurnDiscoverySkipped;
203
199
 
204
- return this.roapRequest
205
- .sendRoap({
206
- roapMessage,
207
- correlationId: meeting.correlationId,
208
- locusSelfUrl: meeting.selfUrl,
209
- mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
210
- audioMuted: meeting.audio?.isLocallyMuted(),
211
- videoMuted: meeting.video?.isLocallyMuted(),
212
- meetingId: meeting.id,
213
- preferTranscoding: !meeting.isMultistream,
214
- })
215
- .then(({locus, mediaConnections}) => {
216
- if (mediaConnections) {
217
- meeting.updateMediaConnections(mediaConnections);
218
- }
200
+ return this.roapRequest
201
+ .sendRoap({
202
+ roapMessage,
203
+ locusSelfUrl: meeting.selfUrl,
204
+ mediaId: sendEmptyMediaId ? '' : meeting.mediaId,
205
+ meetingId: meeting.id,
206
+ preferTranscoding: !meeting.isMultistream,
207
+ locusMediaRequest: meeting.locusMediaRequest,
208
+ ipVersion: MeetingUtil.getIpVersion(meeting.webex),
209
+ })
210
+ .then(({locus, mediaConnections}) => {
211
+ if (mediaConnections) {
212
+ meeting.updateMediaConnections(mediaConnections);
213
+ }
219
214
 
220
- return locus;
221
- });
215
+ let roapAnswer;
216
+
217
+ if (mediaConnections?.[0]?.remoteSdp) {
218
+ const remoteSdp = JSON.parse(mediaConnections[0].remoteSdp);
219
+
220
+ if (remoteSdp.roapMessage) {
221
+ const {
222
+ seq: answerSeq,
223
+ messageType,
224
+ sdps,
225
+ errorType,
226
+ errorCause,
227
+ headers,
228
+ } = remoteSdp.roapMessage;
229
+
230
+ roapAnswer = {
231
+ seq: answerSeq,
232
+ messageType,
233
+ sdp: sdps[0],
234
+ errorType,
235
+ errorCause,
236
+ headers,
237
+ };
238
+ }
239
+ }
240
+
241
+ if (!roapAnswer) {
242
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ROAP_HTTP_RESPONSE_MISSING, {
243
+ correlationId: meeting.correlationId,
244
+ messageType: 'ANSWER',
245
+ isMultistream: meeting.isMultistream,
246
+ });
247
+ }
248
+
249
+ return {locus, roapAnswer};
250
+ });
251
+ });
222
252
  }
223
253
 
224
254
  /**
@@ -229,9 +259,10 @@ export default class Roap extends StatelessWebexPlugin {
229
259
  * @param {Meeting} meeting
230
260
  * @param {Boolean} isReconnecting should be set to true if this is a new
231
261
  * media connection just after a reconnection
262
+ * @param {Boolean} [isForced]
232
263
  * @returns {Promise}
233
264
  */
234
- doTurnDiscovery(meeting: Meeting, isReconnecting: boolean) {
235
- return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting);
265
+ doTurnDiscovery(meeting: Meeting, isReconnecting: boolean, isForced?: boolean) {
266
+ return this.turnDiscovery.doTurnDiscovery(meeting, isReconnecting, isForced);
236
267
  }
237
268
  }