@wazo/sdk 0.43.15 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (899) hide show
  1. package/dist/index.js +10630 -0
  2. package/dist/index.mjs +10541 -0
  3. package/{lib → dist}/types/domain/Contact.d.ts +3 -1
  4. package/dist/types/domain/Contact.d.ts.map +1 -0
  5. package/{lib → dist}/types/index.d.ts +13 -13
  6. package/dist/types/index.d.ts.map +1 -0
  7. package/dist/wazo-sdk.js +69378 -43
  8. package/dist/wazo-sdk.js.LICENSE.txt +684 -0
  9. package/package.json +10 -21
  10. package/esm/__tests__/api-client.test.js +0 -281
  11. package/esm/__tests__/web-rtc-client.test.js +0 -192
  12. package/esm/api/agentd.js +0 -23
  13. package/esm/api/amid.js +0 -17
  14. package/esm/api/application.js +0 -63
  15. package/esm/api/auth.js +0 -198
  16. package/esm/api/call-logd.js +0 -24
  17. package/esm/api/calld.js +0 -120
  18. package/esm/api/chatd.js +0 -50
  19. package/esm/api/confd.js +0 -77
  20. package/esm/api/ctid-ng.js +0 -96
  21. package/esm/api/dird.js +0 -110
  22. package/esm/api/webhookd.js +0 -7
  23. package/esm/api-client.js +0 -41
  24. package/esm/base-api-client.js +0 -125
  25. package/esm/checker/Checker.js +0 -54
  26. package/esm/checker/checks/aor.js +0 -28
  27. package/esm/checker/checks/api.js +0 -76
  28. package/esm/checker/checks/ice-ipv4.js +0 -69
  29. package/esm/checker/checks/index.js +0 -8
  30. package/esm/checker/checks/symmetric-nat.js +0 -59
  31. package/esm/checker/checks/wazo-websocket.js +0 -38
  32. package/esm/checker/checks/webrtc-transport.js +0 -35
  33. package/esm/checker/checks/webrtc.js +0 -40
  34. package/esm/constants.js +0 -11
  35. package/esm/domain/AdHocAPIConference.js +0 -102
  36. package/esm/domain/Agent.js +0 -30
  37. package/esm/domain/BadResponse.js +0 -21
  38. package/esm/domain/Call.js +0 -123
  39. package/esm/domain/CallLog.js +0 -157
  40. package/esm/domain/CallSession.js +0 -253
  41. package/esm/domain/CallerID.js +0 -24
  42. package/esm/domain/ChatMessage.js +0 -55
  43. package/esm/domain/ChatRoom.js +0 -30
  44. package/esm/domain/Contact.js +0 -464
  45. package/esm/domain/Country.js +0 -19
  46. package/esm/domain/Device/DebugDevice.js +0 -32
  47. package/esm/domain/Device/Device.js +0 -1
  48. package/esm/domain/DirectorySource.js +0 -1
  49. package/esm/domain/ExternalApp.js +0 -24
  50. package/esm/domain/Features.js +0 -77
  51. package/esm/domain/ForwardOption.js +0 -37
  52. package/esm/domain/Incall.js +0 -28
  53. package/esm/domain/IndirectTransfer.js +0 -40
  54. package/esm/domain/Line.js +0 -39
  55. package/esm/domain/Meeting.js +0 -61
  56. package/esm/domain/MeetingAuthorization.js +0 -46
  57. package/esm/domain/MeetingStatus.js +0 -14
  58. package/esm/domain/NotificationOptions.js +0 -45
  59. package/esm/domain/Phone/CTIPhone.js +0 -288
  60. package/esm/domain/Phone/Phone.js +0 -1
  61. package/esm/domain/Phone/WebRTCPhone.js +0 -1482
  62. package/esm/domain/Profile.js +0 -128
  63. package/esm/domain/Recording.js +0 -30
  64. package/esm/domain/Relocation.js +0 -20
  65. package/esm/domain/Room.js +0 -97
  66. package/esm/domain/SFUNotAvailableError.js +0 -6
  67. package/esm/domain/ServerError.js +0 -9
  68. package/esm/domain/Session.js +0 -174
  69. package/esm/domain/SipLine.js +0 -82
  70. package/esm/domain/Subscription.js +0 -42
  71. package/esm/domain/SwitchboardCall.js +0 -56
  72. package/esm/domain/Voicemail.js +0 -76
  73. package/esm/domain/__tests__/Agent.test.js +0 -37
  74. package/esm/domain/__tests__/Call.test.js +0 -25
  75. package/esm/domain/__tests__/CallLog.test.js +0 -181
  76. package/esm/domain/__tests__/CallSession.test.js +0 -78
  77. package/esm/domain/__tests__/Contact.test.js +0 -393
  78. package/esm/domain/__tests__/IndirectTransfer.test.js +0 -67
  79. package/esm/domain/__tests__/Line.test.js +0 -52
  80. package/esm/domain/__tests__/Meeting.test.js +0 -77
  81. package/esm/domain/__tests__/MeetingAuthorization.test.js +0 -49
  82. package/esm/domain/__tests__/Profile.test.js +0 -169
  83. package/esm/domain/__tests__/Room.test.js +0 -206
  84. package/esm/domain/__tests__/Session.test.js +0 -382
  85. package/esm/domain/__tests__/SipLine.test.js +0 -27
  86. package/esm/domain/__tests__/Voicemail.test.js +0 -90
  87. package/esm/domain/types.js +0 -2
  88. package/esm/index.js +0 -51
  89. package/esm/lib/WazoSessionDescriptionHandler.js +0 -429
  90. package/esm/pubkey.js +0 -10
  91. package/esm/service/CallApi.js +0 -61
  92. package/esm/service/IssueReporter.js +0 -331
  93. package/esm/service/__tests__/IssueReporter.test.js +0 -112
  94. package/esm/service/__tests__/getApiclient.test.js +0 -37
  95. package/esm/service/getApiClient.js +0 -94
  96. package/esm/simple/Auth.js +0 -384
  97. package/esm/simple/Configuration.js +0 -13
  98. package/esm/simple/Directory.js +0 -11
  99. package/esm/simple/Phone.js +0 -389
  100. package/esm/simple/Websocket.js +0 -81
  101. package/esm/simple/__tests__/Auth.test.js +0 -144
  102. package/esm/simple/index.js +0 -137
  103. package/esm/simple/room/LocalParticipant.js +0 -4
  104. package/esm/simple/room/Participant.js +0 -315
  105. package/esm/simple/room/RemoteParticipant.js +0 -10
  106. package/esm/simple/room/Room.js +0 -714
  107. package/esm/simple/room/SipRoom.js +0 -121
  108. package/esm/simple/room/Stream.js +0 -47
  109. package/esm/simple/room/__tests__/Participant.test.js +0 -71
  110. package/esm/simple/room/__tests__/RemoteParticipant.test.js +0 -12
  111. package/esm/simple/utils.js +0 -10
  112. package/esm/types/WebSocketMessage.js +0 -1
  113. package/esm/types/domain/Contact.d.ts +0 -332
  114. package/esm/types/domain/Contact.d.ts.map +0 -1
  115. package/esm/types/index.d.ts +0 -59
  116. package/esm/types/index.d.ts.map +0 -1
  117. package/esm/utils/Emitter.js +0 -19
  118. package/esm/utils/Heartbeat.js +0 -73
  119. package/esm/utils/PhoneNumberUtil.js +0 -67
  120. package/esm/utils/__tests__/Heartbeat.test.js +0 -65
  121. package/esm/utils/__tests__/PhoneNumberUtil.test.js +0 -70
  122. package/esm/utils/__tests__/api-requester.test.js +0 -166
  123. package/esm/utils/__tests__/array.test.js +0 -18
  124. package/esm/utils/__tests__/compare-version.test.js +0 -10
  125. package/esm/utils/__tests__/object.test.js +0 -76
  126. package/esm/utils/__tests__/sdp.test.js +0 -172
  127. package/esm/utils/__tests__/string.test.js +0 -49
  128. package/esm/utils/api-requester.js +0 -213
  129. package/esm/utils/array.js +0 -9
  130. package/esm/utils/compare-version.js +0 -17
  131. package/esm/utils/isMobile.js +0 -3
  132. package/esm/utils/new-from.js +0 -7
  133. package/esm/utils/object.js +0 -10
  134. package/esm/utils/once.js +0 -15
  135. package/esm/utils/sdp.js +0 -104
  136. package/esm/utils/string.js +0 -12
  137. package/esm/utils/update-from.js +0 -10
  138. package/esm/utils/webrtc.js +0 -37
  139. package/esm/web-rtc-client.js +0 -2200
  140. package/esm/websocket-client.js +0 -385
  141. package/index.js +0 -1
  142. package/lib/__tests__/api-client.test.js +0 -295
  143. package/lib/__tests__/web-rtc-client.test.js +0 -210
  144. package/lib/api/agentd.js +0 -28
  145. package/lib/api/amid.js +0 -28
  146. package/lib/api/application.js +0 -68
  147. package/lib/api/auth.js +0 -210
  148. package/lib/api/call-logd.js +0 -29
  149. package/lib/api/calld.js +0 -134
  150. package/lib/api/chatd.js +0 -68
  151. package/lib/api/confd.js +0 -91
  152. package/lib/api/ctid-ng.js +0 -101
  153. package/lib/api/dird.js +0 -124
  154. package/lib/api/webhookd.js +0 -12
  155. package/lib/api-client.js +0 -37
  156. package/lib/base-api-client.js +0 -133
  157. package/lib/checker/Checker.js +0 -68
  158. package/lib/checker/checks/aor.js +0 -42
  159. package/lib/checker/checks/api.js +0 -90
  160. package/lib/checker/checks/ice-ipv4.js +0 -73
  161. package/lib/checker/checks/index.js +0 -13
  162. package/lib/checker/checks/symmetric-nat.js +0 -61
  163. package/lib/checker/checks/wazo-websocket.js +0 -63
  164. package/lib/checker/checks/webrtc-transport.js +0 -49
  165. package/lib/checker/checks/webrtc.js +0 -54
  166. package/lib/constants.js +0 -14
  167. package/lib/domain/AdHocAPIConference.js +0 -101
  168. package/lib/domain/Agent.js +0 -25
  169. package/lib/domain/BadResponse.js +0 -19
  170. package/lib/domain/Call.js +0 -112
  171. package/lib/domain/CallLog.js +0 -151
  172. package/lib/domain/CallSession.js +0 -224
  173. package/lib/domain/CallerID.js +0 -27
  174. package/lib/domain/ChatMessage.js +0 -53
  175. package/lib/domain/ChatRoom.js +0 -32
  176. package/lib/domain/Contact.js +0 -439
  177. package/lib/domain/Country.js +0 -21
  178. package/lib/domain/Device/DebugDevice.js +0 -35
  179. package/lib/domain/Device/Device.js +0 -2
  180. package/lib/domain/DirectorySource.js +0 -2
  181. package/lib/domain/ExternalApp.js +0 -27
  182. package/lib/domain/Features.js +0 -87
  183. package/lib/domain/ForwardOption.js +0 -41
  184. package/lib/domain/Incall.js +0 -32
  185. package/lib/domain/IndirectTransfer.js +0 -42
  186. package/lib/domain/Line.js +0 -39
  187. package/lib/domain/Meeting.js +0 -55
  188. package/lib/domain/MeetingAuthorization.js +0 -45
  189. package/lib/domain/MeetingStatus.js +0 -15
  190. package/lib/domain/NotificationOptions.js +0 -49
  191. package/lib/domain/Phone/CTIPhone.js +0 -324
  192. package/lib/domain/Phone/Phone.js +0 -2
  193. package/lib/domain/Phone/WebRTCPhone.js +0 -1492
  194. package/lib/domain/Profile.js +0 -138
  195. package/lib/domain/Recording.js +0 -31
  196. package/lib/domain/Relocation.js +0 -18
  197. package/lib/domain/Room.js +0 -81
  198. package/lib/domain/SFUNotAvailableError.js +0 -9
  199. package/lib/domain/ServerError.js +0 -15
  200. package/lib/domain/Session.js +0 -166
  201. package/lib/domain/SipLine.js +0 -76
  202. package/lib/domain/Subscription.js +0 -34
  203. package/lib/domain/SwitchboardCall.js +0 -50
  204. package/lib/domain/Voicemail.js +0 -77
  205. package/lib/domain/__tests__/Agent.test.js +0 -42
  206. package/lib/domain/__tests__/Call.test.js +0 -30
  207. package/lib/domain/__tests__/CallLog.test.js +0 -166
  208. package/lib/domain/__tests__/CallSession.test.js +0 -83
  209. package/lib/domain/__tests__/Contact.test.js +0 -371
  210. package/lib/domain/__tests__/IndirectTransfer.test.js +0 -81
  211. package/lib/domain/__tests__/Line.test.js +0 -57
  212. package/lib/domain/__tests__/Meeting.test.js +0 -82
  213. package/lib/domain/__tests__/MeetingAuthorization.test.js +0 -54
  214. package/lib/domain/__tests__/Profile.test.js +0 -197
  215. package/lib/domain/__tests__/Room.test.js +0 -220
  216. package/lib/domain/__tests__/Session.test.js +0 -378
  217. package/lib/domain/__tests__/SipLine.test.js +0 -32
  218. package/lib/domain/__tests__/Voicemail.test.js +0 -95
  219. package/lib/domain/types.js +0 -38
  220. package/lib/index.js +0 -127
  221. package/lib/lib/WazoSessionDescriptionHandler.js +0 -434
  222. package/lib/pubkey.js +0 -12
  223. package/lib/service/CallApi.js +0 -112
  224. package/lib/service/IssueReporter.js +0 -317
  225. package/lib/service/__tests__/IssueReporter.test.js +0 -117
  226. package/lib/service/__tests__/getApiclient.test.js +0 -42
  227. package/lib/service/getApiClient.js +0 -114
  228. package/lib/simple/Auth.js +0 -433
  229. package/lib/simple/Configuration.js +0 -31
  230. package/lib/simple/Directory.js +0 -29
  231. package/lib/simple/Phone.js +0 -418
  232. package/lib/simple/Websocket.js +0 -116
  233. package/lib/simple/__tests__/Auth.test.js +0 -181
  234. package/lib/simple/index.js +0 -165
  235. package/lib/simple/room/LocalParticipant.js +0 -9
  236. package/lib/simple/room/Participant.js +0 -302
  237. package/lib/simple/room/RemoteParticipant.js +0 -15
  238. package/lib/simple/room/Room.js +0 -711
  239. package/lib/simple/room/SipRoom.js +0 -141
  240. package/lib/simple/room/Stream.js +0 -50
  241. package/lib/simple/room/__tests__/Participant.test.js +0 -85
  242. package/lib/simple/room/__tests__/RemoteParticipant.test.js +0 -17
  243. package/lib/simple/utils.js +0 -27
  244. package/lib/types/WebSocketMessage.js +0 -2
  245. package/lib/types/__tests__/api-client.test.d.ts +0 -2
  246. package/lib/types/__tests__/api-client.test.d.ts.map +0 -1
  247. package/lib/types/__tests__/web-rtc-client.test.d.ts +0 -2
  248. package/lib/types/__tests__/web-rtc-client.test.d.ts.map +0 -1
  249. package/lib/types/api/agentd.d.ts +0 -17
  250. package/lib/types/api/agentd.d.ts.map +0 -1
  251. package/lib/types/api/amid.d.ts +0 -8
  252. package/lib/types/api/amid.d.ts.map +0 -1
  253. package/lib/types/api/application.d.ts +0 -34
  254. package/lib/types/api/application.d.ts.map +0 -1
  255. package/lib/types/api/auth.d.ts +0 -69
  256. package/lib/types/api/auth.d.ts.map +0 -1
  257. package/lib/types/api/call-logd.d.ts +0 -12
  258. package/lib/types/api/call-logd.d.ts.map +0 -1
  259. package/lib/types/api/calld.d.ts +0 -52
  260. package/lib/types/api/calld.d.ts.map +0 -1
  261. package/lib/types/api/chatd.d.ts +0 -29
  262. package/lib/types/api/chatd.d.ts.map +0 -1
  263. package/lib/types/api/confd.d.ts +0 -46
  264. package/lib/types/api/confd.d.ts.map +0 -1
  265. package/lib/types/api/ctid-ng.d.ts +0 -36
  266. package/lib/types/api/ctid-ng.d.ts.map +0 -1
  267. package/lib/types/api/dird.d.ts +0 -33
  268. package/lib/types/api/dird.d.ts.map +0 -1
  269. package/lib/types/api/webhookd.d.ts +0 -24
  270. package/lib/types/api/webhookd.d.ts.map +0 -1
  271. package/lib/types/api-client.d.ts +0 -26
  272. package/lib/types/api-client.d.ts.map +0 -1
  273. package/lib/types/base-api-client.d.ts +0 -43
  274. package/lib/types/base-api-client.d.ts.map +0 -1
  275. package/lib/types/checker/Checker.d.ts +0 -13
  276. package/lib/types/checker/Checker.d.ts.map +0 -1
  277. package/lib/types/checker/checks/aor.d.ts +0 -6
  278. package/lib/types/checker/checks/aor.d.ts.map +0 -1
  279. package/lib/types/checker/checks/api.d.ts +0 -6
  280. package/lib/types/checker/checks/api.d.ts.map +0 -1
  281. package/lib/types/checker/checks/ice-ipv4.d.ts +0 -6
  282. package/lib/types/checker/checks/ice-ipv4.d.ts.map +0 -1
  283. package/lib/types/checker/checks/index.d.ts +0 -9
  284. package/lib/types/checker/checks/index.d.ts.map +0 -1
  285. package/lib/types/checker/checks/symmetric-nat.d.ts +0 -6
  286. package/lib/types/checker/checks/symmetric-nat.d.ts.map +0 -1
  287. package/lib/types/checker/checks/wazo-websocket.d.ts +0 -6
  288. package/lib/types/checker/checks/wazo-websocket.d.ts.map +0 -1
  289. package/lib/types/checker/checks/webrtc-transport.d.ts +0 -7
  290. package/lib/types/checker/checks/webrtc-transport.d.ts.map +0 -1
  291. package/lib/types/checker/checks/webrtc.d.ts +0 -6
  292. package/lib/types/checker/checks/webrtc.d.ts.map +0 -1
  293. package/lib/types/constants.d.ts +0 -12
  294. package/lib/types/constants.d.ts.map +0 -1
  295. package/lib/types/domain/AdHocAPIConference.d.ts +0 -54
  296. package/lib/types/domain/AdHocAPIConference.d.ts.map +0 -1
  297. package/lib/types/domain/Agent.d.ts +0 -31
  298. package/lib/types/domain/Agent.d.ts.map +0 -1
  299. package/lib/types/domain/BadResponse.d.ts +0 -11
  300. package/lib/types/domain/BadResponse.d.ts.map +0 -1
  301. package/lib/types/domain/Call.d.ts +0 -79
  302. package/lib/types/domain/Call.d.ts.map +0 -1
  303. package/lib/types/domain/CallLog.d.ts +0 -88
  304. package/lib/types/domain/CallLog.d.ts.map +0 -1
  305. package/lib/types/domain/CallSession.d.ts +0 -119
  306. package/lib/types/domain/CallSession.d.ts.map +0 -1
  307. package/lib/types/domain/CallerID.d.ts +0 -22
  308. package/lib/types/domain/CallerID.d.ts.map +0 -1
  309. package/lib/types/domain/ChatMessage.d.ts +0 -41
  310. package/lib/types/domain/ChatMessage.d.ts.map +0 -1
  311. package/lib/types/domain/ChatRoom.d.ts +0 -22
  312. package/lib/types/domain/ChatRoom.d.ts.map +0 -1
  313. package/lib/types/domain/Contact.d.ts.map +0 -1
  314. package/lib/types/domain/Country.d.ts +0 -21
  315. package/lib/types/domain/Country.d.ts.map +0 -1
  316. package/lib/types/domain/Device/DebugDevice.d.ts +0 -14
  317. package/lib/types/domain/Device/DebugDevice.d.ts.map +0 -1
  318. package/lib/types/domain/Device/Device.d.ts +0 -13
  319. package/lib/types/domain/Device/Device.d.ts.map +0 -1
  320. package/lib/types/domain/DirectorySource.d.ts +0 -13
  321. package/lib/types/domain/DirectorySource.d.ts.map +0 -1
  322. package/lib/types/domain/ExternalApp.d.ts +0 -22
  323. package/lib/types/domain/ExternalApp.d.ts.map +0 -1
  324. package/lib/types/domain/Features.d.ts +0 -26
  325. package/lib/types/domain/Features.d.ts.map +0 -1
  326. package/lib/types/domain/ForwardOption.d.ts +0 -28
  327. package/lib/types/domain/ForwardOption.d.ts.map +0 -1
  328. package/lib/types/domain/Incall.d.ts +0 -21
  329. package/lib/types/domain/Incall.d.ts.map +0 -1
  330. package/lib/types/domain/IndirectTransfer.d.ts +0 -31
  331. package/lib/types/domain/IndirectTransfer.d.ts.map +0 -1
  332. package/lib/types/domain/Line.d.ts +0 -35
  333. package/lib/types/domain/Line.d.ts.map +0 -1
  334. package/lib/types/domain/Meeting.d.ts +0 -45
  335. package/lib/types/domain/Meeting.d.ts.map +0 -1
  336. package/lib/types/domain/MeetingAuthorization.d.ts +0 -32
  337. package/lib/types/domain/MeetingAuthorization.d.ts.map +0 -1
  338. package/lib/types/domain/MeetingStatus.d.ts +0 -10
  339. package/lib/types/domain/MeetingStatus.d.ts.map +0 -1
  340. package/lib/types/domain/NotificationOptions.d.ts +0 -22
  341. package/lib/types/domain/NotificationOptions.d.ts.map +0 -1
  342. package/lib/types/domain/Phone/CTIPhone.d.ts +0 -79
  343. package/lib/types/domain/Phone/CTIPhone.d.ts.map +0 -1
  344. package/lib/types/domain/Phone/Phone.d.ts +0 -83
  345. package/lib/types/domain/Phone/Phone.d.ts.map +0 -1
  346. package/lib/types/domain/Phone/WebRTCPhone.d.ts +0 -183
  347. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +0 -1
  348. package/lib/types/domain/Profile.d.ts +0 -155
  349. package/lib/types/domain/Profile.d.ts.map +0 -1
  350. package/lib/types/domain/Recording.d.ts +0 -26
  351. package/lib/types/domain/Recording.d.ts.map +0 -1
  352. package/lib/types/domain/Relocation.d.ts +0 -23
  353. package/lib/types/domain/Relocation.d.ts.map +0 -1
  354. package/lib/types/domain/Room.d.ts +0 -33
  355. package/lib/types/domain/Room.d.ts.map +0 -1
  356. package/lib/types/domain/SFUNotAvailableError.d.ts +0 -4
  357. package/lib/types/domain/SFUNotAvailableError.d.ts.map +0 -1
  358. package/lib/types/domain/ServerError.d.ts +0 -6
  359. package/lib/types/domain/ServerError.d.ts.map +0 -1
  360. package/lib/types/domain/Session.d.ts +0 -100
  361. package/lib/types/domain/Session.d.ts.map +0 -1
  362. package/lib/types/domain/SipLine.d.ts +0 -54
  363. package/lib/types/domain/SipLine.d.ts.map +0 -1
  364. package/lib/types/domain/Subscription.d.ts +0 -43
  365. package/lib/types/domain/Subscription.d.ts.map +0 -1
  366. package/lib/types/domain/SwitchboardCall.d.ts +0 -62
  367. package/lib/types/domain/SwitchboardCall.d.ts.map +0 -1
  368. package/lib/types/domain/Voicemail.d.ts +0 -58
  369. package/lib/types/domain/Voicemail.d.ts.map +0 -1
  370. package/lib/types/domain/__tests__/Agent.test.d.ts +0 -2
  371. package/lib/types/domain/__tests__/Agent.test.d.ts.map +0 -1
  372. package/lib/types/domain/__tests__/Call.test.d.ts +0 -2
  373. package/lib/types/domain/__tests__/Call.test.d.ts.map +0 -1
  374. package/lib/types/domain/__tests__/CallLog.test.d.ts +0 -2
  375. package/lib/types/domain/__tests__/CallLog.test.d.ts.map +0 -1
  376. package/lib/types/domain/__tests__/CallSession.test.d.ts +0 -2
  377. package/lib/types/domain/__tests__/CallSession.test.d.ts.map +0 -1
  378. package/lib/types/domain/__tests__/Contact.test.d.ts +0 -2
  379. package/lib/types/domain/__tests__/Contact.test.d.ts.map +0 -1
  380. package/lib/types/domain/__tests__/IndirectTransfer.test.d.ts +0 -2
  381. package/lib/types/domain/__tests__/IndirectTransfer.test.d.ts.map +0 -1
  382. package/lib/types/domain/__tests__/Line.test.d.ts +0 -2
  383. package/lib/types/domain/__tests__/Line.test.d.ts.map +0 -1
  384. package/lib/types/domain/__tests__/Meeting.test.d.ts +0 -2
  385. package/lib/types/domain/__tests__/Meeting.test.d.ts.map +0 -1
  386. package/lib/types/domain/__tests__/MeetingAuthorization.test.d.ts +0 -2
  387. package/lib/types/domain/__tests__/MeetingAuthorization.test.d.ts.map +0 -1
  388. package/lib/types/domain/__tests__/Profile.test.d.ts +0 -2
  389. package/lib/types/domain/__tests__/Profile.test.d.ts.map +0 -1
  390. package/lib/types/domain/__tests__/Room.test.d.ts +0 -2
  391. package/lib/types/domain/__tests__/Room.test.d.ts.map +0 -1
  392. package/lib/types/domain/__tests__/Session.test.d.ts +0 -2
  393. package/lib/types/domain/__tests__/Session.test.d.ts.map +0 -1
  394. package/lib/types/domain/__tests__/SipLine.test.d.ts +0 -2
  395. package/lib/types/domain/__tests__/SipLine.test.d.ts.map +0 -1
  396. package/lib/types/domain/__tests__/Voicemail.test.d.ts +0 -2
  397. package/lib/types/domain/__tests__/Voicemail.test.d.ts.map +0 -1
  398. package/lib/types/domain/types.d.ts +0 -378
  399. package/lib/types/domain/types.d.ts.map +0 -1
  400. package/lib/types/index.d.ts.map +0 -1
  401. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +0 -31
  402. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +0 -1
  403. package/lib/types/pubkey.d.ts +0 -3
  404. package/lib/types/pubkey.d.ts.map +0 -1
  405. package/lib/types/service/CallApi.d.ts +0 -28
  406. package/lib/types/service/CallApi.d.ts.map +0 -1
  407. package/lib/types/service/IssueReporter.d.ts +0 -42
  408. package/lib/types/service/IssueReporter.d.ts.map +0 -1
  409. package/lib/types/service/__tests__/IssueReporter.test.d.ts +0 -2
  410. package/lib/types/service/__tests__/IssueReporter.test.d.ts.map +0 -1
  411. package/lib/types/service/__tests__/getApiclient.test.d.ts +0 -2
  412. package/lib/types/service/__tests__/getApiclient.test.d.ts.map +0 -1
  413. package/lib/types/service/getApiClient.d.ts +0 -21
  414. package/lib/types/service/getApiClient.d.ts.map +0 -1
  415. package/lib/types/simple/Auth.d.ts +0 -75
  416. package/lib/types/simple/Auth.d.ts.map +0 -1
  417. package/lib/types/simple/Configuration.d.ts +0 -7
  418. package/lib/types/simple/Configuration.d.ts.map +0 -1
  419. package/lib/types/simple/Directory.d.ts +0 -7
  420. package/lib/types/simple/Directory.d.ts.map +0 -1
  421. package/lib/types/simple/Phone.d.ts +0 -119
  422. package/lib/types/simple/Phone.d.ts.map +0 -1
  423. package/lib/types/simple/Websocket.d.ts +0 -21
  424. package/lib/types/simple/Websocket.d.ts.map +0 -1
  425. package/lib/types/simple/__tests__/Auth.test.d.ts +0 -2
  426. package/lib/types/simple/__tests__/Auth.test.d.ts.map +0 -1
  427. package/lib/types/simple/index.d.ts +0 -153
  428. package/lib/types/simple/index.d.ts.map +0 -1
  429. package/lib/types/simple/room/LocalParticipant.d.ts +0 -5
  430. package/lib/types/simple/room/LocalParticipant.d.ts.map +0 -1
  431. package/lib/types/simple/room/Participant.d.ts +0 -77
  432. package/lib/types/simple/room/Participant.d.ts.map +0 -1
  433. package/lib/types/simple/room/RemoteParticipant.d.ts +0 -7
  434. package/lib/types/simple/room/RemoteParticipant.d.ts.map +0 -1
  435. package/lib/types/simple/room/Room.d.ts +0 -127
  436. package/lib/types/simple/room/Room.d.ts.map +0 -1
  437. package/lib/types/simple/room/SipRoom.d.ts +0 -14
  438. package/lib/types/simple/room/SipRoom.d.ts.map +0 -1
  439. package/lib/types/simple/room/Stream.d.ts +0 -13
  440. package/lib/types/simple/room/Stream.d.ts.map +0 -1
  441. package/lib/types/simple/room/__tests__/Participant.test.d.ts +0 -2
  442. package/lib/types/simple/room/__tests__/Participant.test.d.ts.map +0 -1
  443. package/lib/types/simple/room/__tests__/RemoteParticipant.test.d.ts +0 -2
  444. package/lib/types/simple/room/__tests__/RemoteParticipant.test.d.ts.map +0 -1
  445. package/lib/types/simple/utils.d.ts +0 -3
  446. package/lib/types/simple/utils.d.ts.map +0 -1
  447. package/lib/types/types/WebSocketMessage.d.ts +0 -285
  448. package/lib/types/types/WebSocketMessage.d.ts.map +0 -1
  449. package/lib/types/utils/Emitter.d.ts +0 -18
  450. package/lib/types/utils/Emitter.d.ts.map +0 -1
  451. package/lib/types/utils/Heartbeat.d.ts +0 -22
  452. package/lib/types/utils/Heartbeat.d.ts.map +0 -1
  453. package/lib/types/utils/PhoneNumberUtil.d.ts +0 -7
  454. package/lib/types/utils/PhoneNumberUtil.d.ts.map +0 -1
  455. package/lib/types/utils/__tests__/Heartbeat.test.d.ts +0 -2
  456. package/lib/types/utils/__tests__/Heartbeat.test.d.ts.map +0 -1
  457. package/lib/types/utils/__tests__/PhoneNumberUtil.test.d.ts +0 -2
  458. package/lib/types/utils/__tests__/PhoneNumberUtil.test.d.ts.map +0 -1
  459. package/lib/types/utils/__tests__/api-requester.test.d.ts +0 -2
  460. package/lib/types/utils/__tests__/api-requester.test.d.ts.map +0 -1
  461. package/lib/types/utils/__tests__/array.test.d.ts +0 -2
  462. package/lib/types/utils/__tests__/array.test.d.ts.map +0 -1
  463. package/lib/types/utils/__tests__/compare-version.test.d.ts +0 -2
  464. package/lib/types/utils/__tests__/compare-version.test.d.ts.map +0 -1
  465. package/lib/types/utils/__tests__/object.test.d.ts +0 -2
  466. package/lib/types/utils/__tests__/object.test.d.ts.map +0 -1
  467. package/lib/types/utils/__tests__/sdp.test.d.ts +0 -2
  468. package/lib/types/utils/__tests__/sdp.test.d.ts.map +0 -1
  469. package/lib/types/utils/__tests__/string.test.d.ts +0 -2
  470. package/lib/types/utils/__tests__/string.test.d.ts.map +0 -1
  471. package/lib/types/utils/api-requester.d.ts +0 -48
  472. package/lib/types/utils/api-requester.d.ts.map +0 -1
  473. package/lib/types/utils/array.d.ts +0 -2
  474. package/lib/types/utils/array.d.ts.map +0 -1
  475. package/lib/types/utils/compare-version.d.ts +0 -3
  476. package/lib/types/utils/compare-version.d.ts.map +0 -1
  477. package/lib/types/utils/isMobile.d.ts +0 -3
  478. package/lib/types/utils/isMobile.d.ts.map +0 -1
  479. package/lib/types/utils/new-from.d.ts +0 -3
  480. package/lib/types/utils/new-from.d.ts.map +0 -1
  481. package/lib/types/utils/object.d.ts +0 -2
  482. package/lib/types/utils/object.d.ts.map +0 -1
  483. package/lib/types/utils/once.d.ts +0 -2
  484. package/lib/types/utils/once.d.ts.map +0 -1
  485. package/lib/types/utils/sdp.d.ts +0 -28
  486. package/lib/types/utils/sdp.d.ts.map +0 -1
  487. package/lib/types/utils/string.d.ts +0 -3
  488. package/lib/types/utils/string.d.ts.map +0 -1
  489. package/lib/types/utils/update-from.d.ts +0 -3
  490. package/lib/types/utils/update-from.d.ts.map +0 -1
  491. package/lib/types/utils/webrtc.d.ts +0 -15
  492. package/lib/types/utils/webrtc.d.ts.map +0 -1
  493. package/lib/types/web-rtc-client.d.ts +0 -198
  494. package/lib/types/web-rtc-client.d.ts.map +0 -1
  495. package/lib/types/websocket-client.d.ts +0 -138
  496. package/lib/types/websocket-client.d.ts.map +0 -1
  497. package/lib/utils/Emitter.js +0 -24
  498. package/lib/utils/Heartbeat.js +0 -66
  499. package/lib/utils/PhoneNumberUtil.js +0 -73
  500. package/lib/utils/__tests__/Heartbeat.test.js +0 -79
  501. package/lib/utils/__tests__/PhoneNumberUtil.test.js +0 -72
  502. package/lib/utils/__tests__/api-requester.test.js +0 -180
  503. package/lib/utils/__tests__/array.test.js +0 -20
  504. package/lib/utils/__tests__/compare-version.test.js +0 -15
  505. package/lib/utils/__tests__/object.test.js +0 -78
  506. package/lib/utils/__tests__/sdp.test.js +0 -188
  507. package/lib/utils/__tests__/string.test.js +0 -51
  508. package/lib/utils/api-requester.js +0 -200
  509. package/lib/utils/array.js +0 -13
  510. package/lib/utils/compare-version.js +0 -19
  511. package/lib/utils/isMobile.js +0 -5
  512. package/lib/utils/new-from.js +0 -9
  513. package/lib/utils/object.js +0 -14
  514. package/lib/utils/once.js +0 -18
  515. package/lib/utils/sdp.js +0 -115
  516. package/lib/utils/string.js +0 -17
  517. package/lib/utils/update-from.js +0 -12
  518. package/lib/utils/webrtc.js +0 -41
  519. package/lib/web-rtc-client.js +0 -2239
  520. package/lib/websocket-client.js +0 -390
  521. package/src/__tests__/api-client.test.ts +0 -315
  522. package/src/__tests__/web-rtc-client.test.ts +0 -198
  523. package/src/api/agentd.ts +0 -37
  524. package/src/api/amid.ts +0 -25
  525. package/src/api/application.ts +0 -96
  526. package/src/api/auth.ts +0 -305
  527. package/src/api/call-logd.ts +0 -38
  528. package/src/api/calld.ts +0 -185
  529. package/src/api/chatd.ts +0 -87
  530. package/src/api/confd.ts +0 -119
  531. package/src/api/ctid-ng.ts +0 -152
  532. package/src/api/dird.ts +0 -143
  533. package/src/api/webhookd.ts +0 -30
  534. package/src/api-client.ts +0 -65
  535. package/src/base-api-client.ts +0 -184
  536. package/src/checker/Checker.ts +0 -73
  537. package/src/checker/checks/aor.ts +0 -34
  538. package/src/checker/checks/api.ts +0 -78
  539. package/src/checker/checks/ice-ipv4.ts +0 -80
  540. package/src/checker/checks/index.ts +0 -9
  541. package/src/checker/checks/symmetric-nat.ts +0 -69
  542. package/src/checker/checks/wazo-websocket.ts +0 -41
  543. package/src/checker/checks/webrtc-transport.ts +0 -42
  544. package/src/checker/checks/webrtc.ts +0 -48
  545. package/src/constants.ts +0 -11
  546. package/src/domain/AdHocAPIConference.ts +0 -166
  547. package/src/domain/Agent.ts +0 -68
  548. package/src/domain/BadResponse.ts +0 -29
  549. package/src/domain/Call.ts +0 -217
  550. package/src/domain/CallLog.ts +0 -265
  551. package/src/domain/CallSession.ts +0 -401
  552. package/src/domain/CallerID.ts +0 -49
  553. package/src/domain/ChatMessage.ts +0 -107
  554. package/src/domain/ChatRoom.ts +0 -55
  555. package/src/domain/Contact.ts +0 -851
  556. package/src/domain/Country.ts +0 -19
  557. package/src/domain/Device/DebugDevice.ts +0 -44
  558. package/src/domain/Device/Device.ts +0 -12
  559. package/src/domain/DirectorySource.ts +0 -13
  560. package/src/domain/ExternalApp.ts +0 -46
  561. package/src/domain/Features.ts +0 -105
  562. package/src/domain/ForwardOption.ts +0 -65
  563. package/src/domain/Incall.ts +0 -50
  564. package/src/domain/IndirectTransfer.ts +0 -73
  565. package/src/domain/Line.ts +0 -79
  566. package/src/domain/Meeting.ts +0 -113
  567. package/src/domain/MeetingAuthorization.ts +0 -81
  568. package/src/domain/MeetingStatus.ts +0 -23
  569. package/src/domain/NotificationOptions.ts +0 -68
  570. package/src/domain/Phone/CTIPhone.ts +0 -381
  571. package/src/domain/Phone/Phone.ts +0 -81
  572. package/src/domain/Phone/WebRTCPhone.ts +0 -1830
  573. package/src/domain/Profile.ts +0 -289
  574. package/src/domain/Recording.ts +0 -60
  575. package/src/domain/Relocation.ts +0 -45
  576. package/src/domain/Room.ts +0 -141
  577. package/src/domain/SFUNotAvailableError.ts +0 -7
  578. package/src/domain/ServerError.ts +0 -12
  579. package/src/domain/Session.ts +0 -297
  580. package/src/domain/SipLine.ts +0 -154
  581. package/src/domain/Subscription.ts +0 -95
  582. package/src/domain/SwitchboardCall.ts +0 -127
  583. package/src/domain/Voicemail.ts +0 -138
  584. package/src/domain/__tests__/Agent.test.ts +0 -38
  585. package/src/domain/__tests__/Call.test.ts +0 -26
  586. package/src/domain/__tests__/CallLog.test.ts +0 -203
  587. package/src/domain/__tests__/CallSession.test.ts +0 -80
  588. package/src/domain/__tests__/Contact.test.ts +0 -407
  589. package/src/domain/__tests__/IndirectTransfer.test.ts +0 -68
  590. package/src/domain/__tests__/Line.test.ts +0 -53
  591. package/src/domain/__tests__/Meeting.test.ts +0 -93
  592. package/src/domain/__tests__/MeetingAuthorization.test.ts +0 -50
  593. package/src/domain/__tests__/Profile.test.ts +0 -170
  594. package/src/domain/__tests__/Room.test.ts +0 -207
  595. package/src/domain/__tests__/Session.test.ts +0 -385
  596. package/src/domain/__tests__/SipLine.test.ts +0 -30
  597. package/src/domain/__tests__/Voicemail.test.ts +0 -91
  598. package/src/domain/types.ts +0 -331
  599. package/src/index.ts +0 -60
  600. package/src/lib/WazoSessionDescriptionHandler.ts +0 -532
  601. package/src/pubkey.ts +0 -11
  602. package/src/service/CallApi.ts +0 -86
  603. package/src/service/IssueReporter.ts +0 -434
  604. package/src/service/__tests__/IssueReporter.test.ts +0 -127
  605. package/src/service/__tests__/getApiclient.test.ts +0 -46
  606. package/src/service/getApiClient.ts +0 -113
  607. package/src/simple/Auth.ts +0 -496
  608. package/src/simple/Configuration.ts +0 -18
  609. package/src/simple/Directory.ts +0 -16
  610. package/src/simple/Phone.ts +0 -531
  611. package/src/simple/Websocket.ts +0 -107
  612. package/src/simple/__tests__/Auth.test.ts +0 -168
  613. package/src/simple/index.ts +0 -153
  614. package/src/simple/room/LocalParticipant.ts +0 -5
  615. package/src/simple/room/Participant.ts +0 -409
  616. package/src/simple/room/RemoteParticipant.ts +0 -15
  617. package/src/simple/room/Room.ts +0 -942
  618. package/src/simple/room/SipRoom.ts +0 -164
  619. package/src/simple/room/Stream.ts +0 -64
  620. package/src/simple/room/__tests__/Participant.test.ts +0 -73
  621. package/src/simple/room/__tests__/RemoteParticipant.test.ts +0 -15
  622. package/src/simple/utils.ts +0 -12
  623. package/src/types/WebSocketMessage.ts +0 -335
  624. package/src/types/global.d.ts +0 -33
  625. package/src/types/wazo.d.ts +0 -1
  626. package/src/utils/Emitter.ts +0 -34
  627. package/src/utils/Heartbeat.ts +0 -102
  628. package/src/utils/PhoneNumberUtil.ts +0 -81
  629. package/src/utils/__tests__/Heartbeat.test.ts +0 -66
  630. package/src/utils/__tests__/PhoneNumberUtil.test.ts +0 -79
  631. package/src/utils/__tests__/api-requester.test.ts +0 -180
  632. package/src/utils/__tests__/array.test.ts +0 -19
  633. package/src/utils/__tests__/compare-version.test.ts +0 -11
  634. package/src/utils/__tests__/object.test.ts +0 -77
  635. package/src/utils/__tests__/sdp.test.ts +0 -173
  636. package/src/utils/__tests__/string.test.ts +0 -55
  637. package/src/utils/api-requester.ts +0 -294
  638. package/src/utils/array.ts +0 -11
  639. package/src/utils/compare-version.ts +0 -21
  640. package/src/utils/isMobile.ts +0 -4
  641. package/src/utils/new-from.ts +0 -7
  642. package/src/utils/object.ts +0 -12
  643. package/src/utils/once.ts +0 -14
  644. package/src/utils/sdp.ts +0 -140
  645. package/src/utils/string.ts +0 -15
  646. package/src/utils/update-from.ts +0 -11
  647. package/src/utils/webrtc.ts +0 -56
  648. package/src/web-rtc-client.ts +0 -2687
  649. package/src/websocket-client.ts +0 -475
  650. /package/{esm → dist}/types/__tests__/api-client.test.d.ts +0 -0
  651. /package/{esm → dist}/types/__tests__/api-client.test.d.ts.map +0 -0
  652. /package/{esm → dist}/types/__tests__/web-rtc-client.test.d.ts +0 -0
  653. /package/{esm → dist}/types/__tests__/web-rtc-client.test.d.ts.map +0 -0
  654. /package/{esm → dist}/types/api/agentd.d.ts +0 -0
  655. /package/{esm → dist}/types/api/agentd.d.ts.map +0 -0
  656. /package/{esm → dist}/types/api/amid.d.ts +0 -0
  657. /package/{esm → dist}/types/api/amid.d.ts.map +0 -0
  658. /package/{esm → dist}/types/api/application.d.ts +0 -0
  659. /package/{esm → dist}/types/api/application.d.ts.map +0 -0
  660. /package/{esm → dist}/types/api/auth.d.ts +0 -0
  661. /package/{esm → dist}/types/api/auth.d.ts.map +0 -0
  662. /package/{esm → dist}/types/api/call-logd.d.ts +0 -0
  663. /package/{esm → dist}/types/api/call-logd.d.ts.map +0 -0
  664. /package/{esm → dist}/types/api/calld.d.ts +0 -0
  665. /package/{esm → dist}/types/api/calld.d.ts.map +0 -0
  666. /package/{esm → dist}/types/api/chatd.d.ts +0 -0
  667. /package/{esm → dist}/types/api/chatd.d.ts.map +0 -0
  668. /package/{esm → dist}/types/api/confd.d.ts +0 -0
  669. /package/{esm → dist}/types/api/confd.d.ts.map +0 -0
  670. /package/{esm → dist}/types/api/ctid-ng.d.ts +0 -0
  671. /package/{esm → dist}/types/api/ctid-ng.d.ts.map +0 -0
  672. /package/{esm → dist}/types/api/dird.d.ts +0 -0
  673. /package/{esm → dist}/types/api/dird.d.ts.map +0 -0
  674. /package/{esm → dist}/types/api/webhookd.d.ts +0 -0
  675. /package/{esm → dist}/types/api/webhookd.d.ts.map +0 -0
  676. /package/{esm → dist}/types/api-client.d.ts +0 -0
  677. /package/{esm → dist}/types/api-client.d.ts.map +0 -0
  678. /package/{esm → dist}/types/base-api-client.d.ts +0 -0
  679. /package/{esm → dist}/types/base-api-client.d.ts.map +0 -0
  680. /package/{esm → dist}/types/checker/Checker.d.ts +0 -0
  681. /package/{esm → dist}/types/checker/Checker.d.ts.map +0 -0
  682. /package/{esm → dist}/types/checker/checks/aor.d.ts +0 -0
  683. /package/{esm → dist}/types/checker/checks/aor.d.ts.map +0 -0
  684. /package/{esm → dist}/types/checker/checks/api.d.ts +0 -0
  685. /package/{esm → dist}/types/checker/checks/api.d.ts.map +0 -0
  686. /package/{esm → dist}/types/checker/checks/ice-ipv4.d.ts +0 -0
  687. /package/{esm → dist}/types/checker/checks/ice-ipv4.d.ts.map +0 -0
  688. /package/{esm → dist}/types/checker/checks/index.d.ts +0 -0
  689. /package/{esm → dist}/types/checker/checks/index.d.ts.map +0 -0
  690. /package/{esm → dist}/types/checker/checks/symmetric-nat.d.ts +0 -0
  691. /package/{esm → dist}/types/checker/checks/symmetric-nat.d.ts.map +0 -0
  692. /package/{esm → dist}/types/checker/checks/wazo-websocket.d.ts +0 -0
  693. /package/{esm → dist}/types/checker/checks/wazo-websocket.d.ts.map +0 -0
  694. /package/{esm → dist}/types/checker/checks/webrtc-transport.d.ts +0 -0
  695. /package/{esm → dist}/types/checker/checks/webrtc-transport.d.ts.map +0 -0
  696. /package/{esm → dist}/types/checker/checks/webrtc.d.ts +0 -0
  697. /package/{esm → dist}/types/checker/checks/webrtc.d.ts.map +0 -0
  698. /package/{esm → dist}/types/constants.d.ts +0 -0
  699. /package/{esm → dist}/types/constants.d.ts.map +0 -0
  700. /package/{esm → dist}/types/domain/AdHocAPIConference.d.ts +0 -0
  701. /package/{esm → dist}/types/domain/AdHocAPIConference.d.ts.map +0 -0
  702. /package/{esm → dist}/types/domain/Agent.d.ts +0 -0
  703. /package/{esm → dist}/types/domain/Agent.d.ts.map +0 -0
  704. /package/{esm → dist}/types/domain/BadResponse.d.ts +0 -0
  705. /package/{esm → dist}/types/domain/BadResponse.d.ts.map +0 -0
  706. /package/{esm → dist}/types/domain/Call.d.ts +0 -0
  707. /package/{esm → dist}/types/domain/Call.d.ts.map +0 -0
  708. /package/{esm → dist}/types/domain/CallLog.d.ts +0 -0
  709. /package/{esm → dist}/types/domain/CallLog.d.ts.map +0 -0
  710. /package/{esm → dist}/types/domain/CallSession.d.ts +0 -0
  711. /package/{esm → dist}/types/domain/CallSession.d.ts.map +0 -0
  712. /package/{esm → dist}/types/domain/CallerID.d.ts +0 -0
  713. /package/{esm → dist}/types/domain/CallerID.d.ts.map +0 -0
  714. /package/{esm → dist}/types/domain/ChatMessage.d.ts +0 -0
  715. /package/{esm → dist}/types/domain/ChatMessage.d.ts.map +0 -0
  716. /package/{esm → dist}/types/domain/ChatRoom.d.ts +0 -0
  717. /package/{esm → dist}/types/domain/ChatRoom.d.ts.map +0 -0
  718. /package/{esm → dist}/types/domain/Country.d.ts +0 -0
  719. /package/{esm → dist}/types/domain/Country.d.ts.map +0 -0
  720. /package/{esm → dist}/types/domain/Device/DebugDevice.d.ts +0 -0
  721. /package/{esm → dist}/types/domain/Device/DebugDevice.d.ts.map +0 -0
  722. /package/{esm → dist}/types/domain/Device/Device.d.ts +0 -0
  723. /package/{esm → dist}/types/domain/Device/Device.d.ts.map +0 -0
  724. /package/{esm → dist}/types/domain/DirectorySource.d.ts +0 -0
  725. /package/{esm → dist}/types/domain/DirectorySource.d.ts.map +0 -0
  726. /package/{esm → dist}/types/domain/ExternalApp.d.ts +0 -0
  727. /package/{esm → dist}/types/domain/ExternalApp.d.ts.map +0 -0
  728. /package/{esm → dist}/types/domain/Features.d.ts +0 -0
  729. /package/{esm → dist}/types/domain/Features.d.ts.map +0 -0
  730. /package/{esm → dist}/types/domain/ForwardOption.d.ts +0 -0
  731. /package/{esm → dist}/types/domain/ForwardOption.d.ts.map +0 -0
  732. /package/{esm → dist}/types/domain/Incall.d.ts +0 -0
  733. /package/{esm → dist}/types/domain/Incall.d.ts.map +0 -0
  734. /package/{esm → dist}/types/domain/IndirectTransfer.d.ts +0 -0
  735. /package/{esm → dist}/types/domain/IndirectTransfer.d.ts.map +0 -0
  736. /package/{esm → dist}/types/domain/Line.d.ts +0 -0
  737. /package/{esm → dist}/types/domain/Line.d.ts.map +0 -0
  738. /package/{esm → dist}/types/domain/Meeting.d.ts +0 -0
  739. /package/{esm → dist}/types/domain/Meeting.d.ts.map +0 -0
  740. /package/{esm → dist}/types/domain/MeetingAuthorization.d.ts +0 -0
  741. /package/{esm → dist}/types/domain/MeetingAuthorization.d.ts.map +0 -0
  742. /package/{esm → dist}/types/domain/MeetingStatus.d.ts +0 -0
  743. /package/{esm → dist}/types/domain/MeetingStatus.d.ts.map +0 -0
  744. /package/{esm → dist}/types/domain/NotificationOptions.d.ts +0 -0
  745. /package/{esm → dist}/types/domain/NotificationOptions.d.ts.map +0 -0
  746. /package/{esm → dist}/types/domain/Phone/CTIPhone.d.ts +0 -0
  747. /package/{esm → dist}/types/domain/Phone/CTIPhone.d.ts.map +0 -0
  748. /package/{esm → dist}/types/domain/Phone/Phone.d.ts +0 -0
  749. /package/{esm → dist}/types/domain/Phone/Phone.d.ts.map +0 -0
  750. /package/{esm → dist}/types/domain/Phone/WebRTCPhone.d.ts +0 -0
  751. /package/{esm → dist}/types/domain/Phone/WebRTCPhone.d.ts.map +0 -0
  752. /package/{esm → dist}/types/domain/Profile.d.ts +0 -0
  753. /package/{esm → dist}/types/domain/Profile.d.ts.map +0 -0
  754. /package/{esm → dist}/types/domain/Recording.d.ts +0 -0
  755. /package/{esm → dist}/types/domain/Recording.d.ts.map +0 -0
  756. /package/{esm → dist}/types/domain/Relocation.d.ts +0 -0
  757. /package/{esm → dist}/types/domain/Relocation.d.ts.map +0 -0
  758. /package/{esm → dist}/types/domain/Room.d.ts +0 -0
  759. /package/{esm → dist}/types/domain/Room.d.ts.map +0 -0
  760. /package/{esm → dist}/types/domain/SFUNotAvailableError.d.ts +0 -0
  761. /package/{esm → dist}/types/domain/SFUNotAvailableError.d.ts.map +0 -0
  762. /package/{esm → dist}/types/domain/ServerError.d.ts +0 -0
  763. /package/{esm → dist}/types/domain/ServerError.d.ts.map +0 -0
  764. /package/{esm → dist}/types/domain/Session.d.ts +0 -0
  765. /package/{esm → dist}/types/domain/Session.d.ts.map +0 -0
  766. /package/{esm → dist}/types/domain/SipLine.d.ts +0 -0
  767. /package/{esm → dist}/types/domain/SipLine.d.ts.map +0 -0
  768. /package/{esm → dist}/types/domain/Subscription.d.ts +0 -0
  769. /package/{esm → dist}/types/domain/Subscription.d.ts.map +0 -0
  770. /package/{esm → dist}/types/domain/SwitchboardCall.d.ts +0 -0
  771. /package/{esm → dist}/types/domain/SwitchboardCall.d.ts.map +0 -0
  772. /package/{esm → dist}/types/domain/Voicemail.d.ts +0 -0
  773. /package/{esm → dist}/types/domain/Voicemail.d.ts.map +0 -0
  774. /package/{esm → dist}/types/domain/__tests__/Agent.test.d.ts +0 -0
  775. /package/{esm → dist}/types/domain/__tests__/Agent.test.d.ts.map +0 -0
  776. /package/{esm → dist}/types/domain/__tests__/Call.test.d.ts +0 -0
  777. /package/{esm → dist}/types/domain/__tests__/Call.test.d.ts.map +0 -0
  778. /package/{esm → dist}/types/domain/__tests__/CallLog.test.d.ts +0 -0
  779. /package/{esm → dist}/types/domain/__tests__/CallLog.test.d.ts.map +0 -0
  780. /package/{esm → dist}/types/domain/__tests__/CallSession.test.d.ts +0 -0
  781. /package/{esm → dist}/types/domain/__tests__/CallSession.test.d.ts.map +0 -0
  782. /package/{esm → dist}/types/domain/__tests__/Contact.test.d.ts +0 -0
  783. /package/{esm → dist}/types/domain/__tests__/Contact.test.d.ts.map +0 -0
  784. /package/{esm → dist}/types/domain/__tests__/IndirectTransfer.test.d.ts +0 -0
  785. /package/{esm → dist}/types/domain/__tests__/IndirectTransfer.test.d.ts.map +0 -0
  786. /package/{esm → dist}/types/domain/__tests__/Line.test.d.ts +0 -0
  787. /package/{esm → dist}/types/domain/__tests__/Line.test.d.ts.map +0 -0
  788. /package/{esm → dist}/types/domain/__tests__/Meeting.test.d.ts +0 -0
  789. /package/{esm → dist}/types/domain/__tests__/Meeting.test.d.ts.map +0 -0
  790. /package/{esm → dist}/types/domain/__tests__/MeetingAuthorization.test.d.ts +0 -0
  791. /package/{esm → dist}/types/domain/__tests__/MeetingAuthorization.test.d.ts.map +0 -0
  792. /package/{esm → dist}/types/domain/__tests__/Profile.test.d.ts +0 -0
  793. /package/{esm → dist}/types/domain/__tests__/Profile.test.d.ts.map +0 -0
  794. /package/{esm → dist}/types/domain/__tests__/Room.test.d.ts +0 -0
  795. /package/{esm → dist}/types/domain/__tests__/Room.test.d.ts.map +0 -0
  796. /package/{esm → dist}/types/domain/__tests__/Session.test.d.ts +0 -0
  797. /package/{esm → dist}/types/domain/__tests__/Session.test.d.ts.map +0 -0
  798. /package/{esm → dist}/types/domain/__tests__/SipLine.test.d.ts +0 -0
  799. /package/{esm → dist}/types/domain/__tests__/SipLine.test.d.ts.map +0 -0
  800. /package/{esm → dist}/types/domain/__tests__/Voicemail.test.d.ts +0 -0
  801. /package/{esm → dist}/types/domain/__tests__/Voicemail.test.d.ts.map +0 -0
  802. /package/{esm → dist}/types/domain/types.d.ts +0 -0
  803. /package/{esm → dist}/types/domain/types.d.ts.map +0 -0
  804. /package/{esm → dist}/types/lib/WazoSessionDescriptionHandler.d.ts +0 -0
  805. /package/{esm → dist}/types/lib/WazoSessionDescriptionHandler.d.ts.map +0 -0
  806. /package/{esm → dist}/types/pubkey.d.ts +0 -0
  807. /package/{esm → dist}/types/pubkey.d.ts.map +0 -0
  808. /package/{esm → dist}/types/service/CallApi.d.ts +0 -0
  809. /package/{esm → dist}/types/service/CallApi.d.ts.map +0 -0
  810. /package/{esm → dist}/types/service/IssueReporter.d.ts +0 -0
  811. /package/{esm → dist}/types/service/IssueReporter.d.ts.map +0 -0
  812. /package/{esm → dist}/types/service/__tests__/IssueReporter.test.d.ts +0 -0
  813. /package/{esm → dist}/types/service/__tests__/IssueReporter.test.d.ts.map +0 -0
  814. /package/{esm → dist}/types/service/__tests__/getApiclient.test.d.ts +0 -0
  815. /package/{esm → dist}/types/service/__tests__/getApiclient.test.d.ts.map +0 -0
  816. /package/{esm → dist}/types/service/getApiClient.d.ts +0 -0
  817. /package/{esm → dist}/types/service/getApiClient.d.ts.map +0 -0
  818. /package/{esm → dist}/types/simple/Auth.d.ts +0 -0
  819. /package/{esm → dist}/types/simple/Auth.d.ts.map +0 -0
  820. /package/{esm → dist}/types/simple/Configuration.d.ts +0 -0
  821. /package/{esm → dist}/types/simple/Configuration.d.ts.map +0 -0
  822. /package/{esm → dist}/types/simple/Directory.d.ts +0 -0
  823. /package/{esm → dist}/types/simple/Directory.d.ts.map +0 -0
  824. /package/{esm → dist}/types/simple/Phone.d.ts +0 -0
  825. /package/{esm → dist}/types/simple/Phone.d.ts.map +0 -0
  826. /package/{esm → dist}/types/simple/Websocket.d.ts +0 -0
  827. /package/{esm → dist}/types/simple/Websocket.d.ts.map +0 -0
  828. /package/{esm → dist}/types/simple/__tests__/Auth.test.d.ts +0 -0
  829. /package/{esm → dist}/types/simple/__tests__/Auth.test.d.ts.map +0 -0
  830. /package/{esm → dist}/types/simple/index.d.ts +0 -0
  831. /package/{esm → dist}/types/simple/index.d.ts.map +0 -0
  832. /package/{esm → dist}/types/simple/room/LocalParticipant.d.ts +0 -0
  833. /package/{esm → dist}/types/simple/room/LocalParticipant.d.ts.map +0 -0
  834. /package/{esm → dist}/types/simple/room/Participant.d.ts +0 -0
  835. /package/{esm → dist}/types/simple/room/Participant.d.ts.map +0 -0
  836. /package/{esm → dist}/types/simple/room/RemoteParticipant.d.ts +0 -0
  837. /package/{esm → dist}/types/simple/room/RemoteParticipant.d.ts.map +0 -0
  838. /package/{esm → dist}/types/simple/room/Room.d.ts +0 -0
  839. /package/{esm → dist}/types/simple/room/Room.d.ts.map +0 -0
  840. /package/{esm → dist}/types/simple/room/SipRoom.d.ts +0 -0
  841. /package/{esm → dist}/types/simple/room/SipRoom.d.ts.map +0 -0
  842. /package/{esm → dist}/types/simple/room/Stream.d.ts +0 -0
  843. /package/{esm → dist}/types/simple/room/Stream.d.ts.map +0 -0
  844. /package/{esm → dist}/types/simple/room/__tests__/Participant.test.d.ts +0 -0
  845. /package/{esm → dist}/types/simple/room/__tests__/Participant.test.d.ts.map +0 -0
  846. /package/{esm → dist}/types/simple/room/__tests__/RemoteParticipant.test.d.ts +0 -0
  847. /package/{esm → dist}/types/simple/room/__tests__/RemoteParticipant.test.d.ts.map +0 -0
  848. /package/{esm → dist}/types/simple/utils.d.ts +0 -0
  849. /package/{esm → dist}/types/simple/utils.d.ts.map +0 -0
  850. /package/{esm → dist}/types/types/WebSocketMessage.d.ts +0 -0
  851. /package/{esm → dist}/types/types/WebSocketMessage.d.ts.map +0 -0
  852. /package/{esm → dist}/types/utils/Emitter.d.ts +0 -0
  853. /package/{esm → dist}/types/utils/Emitter.d.ts.map +0 -0
  854. /package/{esm → dist}/types/utils/Heartbeat.d.ts +0 -0
  855. /package/{esm → dist}/types/utils/Heartbeat.d.ts.map +0 -0
  856. /package/{esm → dist}/types/utils/PhoneNumberUtil.d.ts +0 -0
  857. /package/{esm → dist}/types/utils/PhoneNumberUtil.d.ts.map +0 -0
  858. /package/{esm → dist}/types/utils/__tests__/Heartbeat.test.d.ts +0 -0
  859. /package/{esm → dist}/types/utils/__tests__/Heartbeat.test.d.ts.map +0 -0
  860. /package/{esm → dist}/types/utils/__tests__/PhoneNumberUtil.test.d.ts +0 -0
  861. /package/{esm → dist}/types/utils/__tests__/PhoneNumberUtil.test.d.ts.map +0 -0
  862. /package/{esm → dist}/types/utils/__tests__/api-requester.test.d.ts +0 -0
  863. /package/{esm → dist}/types/utils/__tests__/api-requester.test.d.ts.map +0 -0
  864. /package/{esm → dist}/types/utils/__tests__/array.test.d.ts +0 -0
  865. /package/{esm → dist}/types/utils/__tests__/array.test.d.ts.map +0 -0
  866. /package/{esm → dist}/types/utils/__tests__/compare-version.test.d.ts +0 -0
  867. /package/{esm → dist}/types/utils/__tests__/compare-version.test.d.ts.map +0 -0
  868. /package/{esm → dist}/types/utils/__tests__/object.test.d.ts +0 -0
  869. /package/{esm → dist}/types/utils/__tests__/object.test.d.ts.map +0 -0
  870. /package/{esm → dist}/types/utils/__tests__/sdp.test.d.ts +0 -0
  871. /package/{esm → dist}/types/utils/__tests__/sdp.test.d.ts.map +0 -0
  872. /package/{esm → dist}/types/utils/__tests__/string.test.d.ts +0 -0
  873. /package/{esm → dist}/types/utils/__tests__/string.test.d.ts.map +0 -0
  874. /package/{esm → dist}/types/utils/api-requester.d.ts +0 -0
  875. /package/{esm → dist}/types/utils/api-requester.d.ts.map +0 -0
  876. /package/{esm → dist}/types/utils/array.d.ts +0 -0
  877. /package/{esm → dist}/types/utils/array.d.ts.map +0 -0
  878. /package/{esm → dist}/types/utils/compare-version.d.ts +0 -0
  879. /package/{esm → dist}/types/utils/compare-version.d.ts.map +0 -0
  880. /package/{esm → dist}/types/utils/isMobile.d.ts +0 -0
  881. /package/{esm → dist}/types/utils/isMobile.d.ts.map +0 -0
  882. /package/{esm → dist}/types/utils/new-from.d.ts +0 -0
  883. /package/{esm → dist}/types/utils/new-from.d.ts.map +0 -0
  884. /package/{esm → dist}/types/utils/object.d.ts +0 -0
  885. /package/{esm → dist}/types/utils/object.d.ts.map +0 -0
  886. /package/{esm → dist}/types/utils/once.d.ts +0 -0
  887. /package/{esm → dist}/types/utils/once.d.ts.map +0 -0
  888. /package/{esm → dist}/types/utils/sdp.d.ts +0 -0
  889. /package/{esm → dist}/types/utils/sdp.d.ts.map +0 -0
  890. /package/{esm → dist}/types/utils/string.d.ts +0 -0
  891. /package/{esm → dist}/types/utils/string.d.ts.map +0 -0
  892. /package/{esm → dist}/types/utils/update-from.d.ts +0 -0
  893. /package/{esm → dist}/types/utils/update-from.d.ts.map +0 -0
  894. /package/{esm → dist}/types/utils/webrtc.d.ts +0 -0
  895. /package/{esm → dist}/types/utils/webrtc.d.ts.map +0 -0
  896. /package/{esm → dist}/types/web-rtc-client.d.ts +0 -0
  897. /package/{esm → dist}/types/web-rtc-client.d.ts.map +0 -0
  898. /package/{esm → dist}/types/websocket-client.d.ts +0 -0
  899. /package/{esm → dist}/types/websocket-client.d.ts.map +0 -0
@@ -1,2687 +0,0 @@
1
- /* eslint-disable class-methods-use-this, no-param-reassign, max-classes-per-file, no-underscore-dangle */
2
-
3
- /* global window, document, navigator */
4
- import 'webrtc-adapter';
5
- import type { InviterInviteOptions } from 'sip.js/lib/api/inviter-invite-options';
6
- import type { InvitationRejectOptions } from 'sip.js/lib/api/invitation-reject-options';
7
- import type { InviterCancelOptions } from 'sip.js/lib/api/inviter-cancel-options';
8
- import type { SessionByeOptions } from 'sip.js/lib/api/session-bye-options';
9
- import type { InvitationAcceptOptions } from 'sip.js/lib/api/invitation-accept-options';
10
- import type { IncomingRequestMessage } from 'sip.js/lib/core/messages/incoming-request-message';
11
- import type { SessionDescriptionHandlerFactoryOptions } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-factory-options';
12
- import type { SessionDescriptionHandlerConfiguration } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-configuration';
13
- import type { SessionDescriptionHandler } from 'sip.js/lib/platform/web/session-description-handler/session-description-handler';
14
- import { UserAgentState } from 'sip.js/lib/api/user-agent-state';
15
- import { Parser } from 'sip.js/lib/core/messages/parser';
16
- import { C } from 'sip.js/lib/core/messages/methods/constants';
17
- import { URI } from 'sip.js/lib/grammar/uri';
18
- import { UserAgent } from 'sip.js/lib/api/user-agent';
19
- import { holdModifier, stripVideo } from 'sip.js/lib/platform/web/modifiers/modifiers';
20
- import { SessionDialog } from 'sip.js/lib/core/dialogs/session-dialog';
21
-
22
- import { Messager } from 'sip.js/lib/api/messager';
23
- import { RegistererState } from 'sip.js/lib/api/registerer-state';
24
- import { SessionState } from 'sip.js/lib/api/session-state';
25
- import { TransportState } from 'sip.js/lib/api/transport-state';
26
- import { defaultPeerConnectionConfiguration } from 'sip.js/lib/platform/web/session-description-handler/peer-connection-configuration-default';
27
- import getStats from 'getstats';
28
-
29
- import { OutgoingByeRequest, OutgoingInviteRequest, OutgoingRequest } from 'sip.js/lib/core';
30
- import { Inviter, Invitation, Registerer, Session, SessionDescriptionHandlerOptions } from 'sip.js/lib/api';
31
- import WazoSessionDescriptionHandler, { wazoMediaStreamFactory } from './lib/WazoSessionDescriptionHandler';
32
- import Emitter from './utils/Emitter';
33
- import ApiClient from './api-client';
34
- import IssueReporter from './service/IssueReporter';
35
- import Heartbeat from './utils/Heartbeat';
36
- import { getVideoDirection, hasAnActiveVideo } from './utils/sdp';
37
- import { lastIndexOf } from './utils/array';
38
- import type { MediaConfig, UserAgentConfigOverrides, WebRtcConfig, UserAgentOptions, IncomingResponse, PeerConnection, WazoSession, WazoTransport } from './domain/types';
39
-
40
- // We need to replace 0.0.0.0 to 127.0.0.1 in the sdp to avoid MOH during a createOffer.
41
- export const replaceLocalIpModifier = (description: Record<string, any>) => Promise.resolve({ // description is immutable... so we have to clone it or the `type` attribute won't be returned.
42
- ...JSON.parse(JSON.stringify(description)),
43
- sdp: description.sdp.replace('c=IN IP4 0.0.0.0', 'c=IN IP4 127.0.0.1'),
44
- });
45
- const DEFAULT_ICE_TIMEOUT = 3000;
46
- const SEND_STATS_DELAY = 5000;
47
- const states = ['STATUS_NULL', 'STATUS_NEW', 'STATUS_CONNECTING', 'STATUS_CONNECTED', 'STATUS_COMPLETED'];
48
- const logger = IssueReporter ? IssueReporter.loggerFor('webrtc-client') : console;
49
- const statsLogger = IssueReporter ? IssueReporter.loggerFor('webrtc-stats') : console;
50
- // events
51
- const REGISTERED = 'registered';
52
- const UNREGISTERED = 'unregistered';
53
- const REGISTRATION_FAILED = 'registrationFailed';
54
- const INVITE = 'invite';
55
- const CONNECTED = 'connected';
56
- const DISCONNECTED = 'disconnected';
57
- const TRANSPORT_ERROR = 'transportError';
58
- const MESSAGE = 'message';
59
- const ACCEPTED = 'accepted';
60
- const REJECTED = 'rejected';
61
- const ON_TRACK = 'onTrack';
62
- const ON_PROGRESS = 'onProgress';
63
- const ON_EARLY_MEDIA = 'onEarlyMedia';
64
- const ON_REINVITE = 'reinvite';
65
- const ON_ERROR = 'onError';
66
- const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
67
- const ON_NETWORK_STATS = 'onNetworkStats';
68
- const ON_DISCONNECTED = 'onDisconnected';
69
- export const events = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
70
- export const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
71
- export class CanceledCallError extends Error {}
72
-
73
- const MAX_REGISTER_TRIES = 5;
74
- // setting a 24hr timeout and letting the backend define the actual value
75
- const NO_ANSWER_TIMEOUT = 60 * 60 * 24; // in seconds
76
-
77
- export default class WebRTCClient extends Emitter {
78
- clientId: number;
79
-
80
- config: WebRtcConfig;
81
-
82
- uaConfigOverrides?: UserAgentConfigOverrides;
83
-
84
- userAgent: UserAgent | null;
85
-
86
- registerer: Registerer | null;
87
-
88
- hasAudio: boolean;
89
-
90
- audio: MediaTrackConstraintSet | boolean | undefined;
91
-
92
- audioElements: Record<string, HTMLAudioElement>;
93
-
94
- video: MediaTrackConstraintSet | boolean | undefined;
95
-
96
- audioStreams: Record<string, any>;
97
-
98
- audioOutputDeviceId: string | null | undefined;
99
-
100
- audioOutputVolume: number;
101
-
102
- heldSessions: Record<string, any>;
103
-
104
- connectionPromise: Promise<void> | null | undefined;
105
-
106
- _boundOnHeartbeat: (...args: Array<any>) => any;
107
-
108
- heartbeat: Heartbeat;
109
-
110
- heartbeatTimeoutCb: ((...args: Array<any>) => any) | null | undefined;
111
-
112
- heartbeatCb: ((...args: Array<any>) => any) | null | undefined;
113
-
114
- statsIntervals: Record<string, any>;
115
-
116
- sipSessions: Record<string, WazoSession>;
117
-
118
- conferences: Record<string, boolean>;
119
-
120
- skipRegister: boolean;
121
-
122
- networkMonitoringInterval: Record<string, any>;
123
-
124
- sessionNetworkStats: Record<string, Record<string, any>>;
125
-
126
- forceClosed: boolean;
127
-
128
- // sugar
129
- ON_USER_AGENT: string;
130
-
131
- REGISTERED: string;
132
-
133
- UNREGISTERED: string;
134
-
135
- REGISTRATION_FAILED: string;
136
-
137
- INVITE: string;
138
-
139
- CONNECTED: string;
140
-
141
- DISCONNECTED: string;
142
-
143
- TRANSPORT_ERROR: string;
144
-
145
- MESSAGE: string;
146
-
147
- ACCEPTED: string;
148
-
149
- REJECTED: string;
150
-
151
- ON_TRACK: string;
152
-
153
- ON_REINVITE: string;
154
-
155
- ON_ERROR: string;
156
-
157
- ON_SCREEN_SHARING_REINVITE: string;
158
-
159
- ON_NETWORK_STATS: string;
160
-
161
- ON_EARLY_MEDIA: string;
162
-
163
- ON_PROGRESS: string;
164
-
165
- ON_DISCONNECTED: string;
166
-
167
- static isAPrivateIp(ip: string): boolean {
168
- const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
169
- return regex.exec(ip) == null;
170
- }
171
-
172
- static getIceServers(ip: string): Array<{
173
- urls: Array<string>;
174
- }> {
175
- if (WebRTCClient.isAPrivateIp(ip)) {
176
- return [{
177
- urls: ['stun:stun.l.google.com:19302', 'stun:stun4.l.google.com:19302'],
178
- }];
179
- }
180
-
181
- return [];
182
- }
183
-
184
- constructor(config: WebRtcConfig, session?: WazoSession, uaConfigOverrides?: UserAgentConfigOverrides) {
185
- super();
186
-
187
- // For debug purpose
188
- this.clientId = Math.ceil(Math.random() * 1000);
189
- logger.info('sdk webrtc constructor', { clientId: this.clientId });
190
-
191
- this.uaConfigOverrides = uaConfigOverrides;
192
- this.config = config;
193
- this.skipRegister = config.skipRegister as boolean;
194
-
195
- this._buildConfig(config, session).then((newConfig: WebRtcConfig) => {
196
- this.config = newConfig;
197
- this.userAgent = this.createUserAgent(uaConfigOverrides);
198
- });
199
-
200
- this.audioOutputDeviceId = config.audioDeviceOutput;
201
- this.audioOutputVolume = config.audioOutputVolume || 1;
202
-
203
- if (config.media) {
204
- this.configureMedia(config.media);
205
- this.setMediaConstraints({
206
- audio: config.media.audio,
207
- video: config.media.video,
208
- });
209
- }
210
-
211
- this.heldSessions = {};
212
- this.statsIntervals = {};
213
- this.connectionPromise = null;
214
- this.sipSessions = {};
215
- this.conferences = {};
216
- this.networkMonitoringInterval = {};
217
- this.sessionNetworkStats = {};
218
- this.forceClosed = false;
219
- this._boundOnHeartbeat = this._onHeartbeat.bind(this);
220
- this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
221
- this.heartbeat.setSendHeartbeat(this.pingServer.bind(this));
222
- this.heartbeat.setOnHeartbeatTimeout(this._onHeartbeatTimeout.bind(this));
223
- // sugar
224
- this.REGISTERED = REGISTERED;
225
- this.UNREGISTERED = UNREGISTERED;
226
- this.REGISTRATION_FAILED = REGISTRATION_FAILED;
227
- this.INVITE = INVITE;
228
- this.CONNECTED = CONNECTED;
229
- this.DISCONNECTED = DISCONNECTED;
230
- this.TRANSPORT_ERROR = TRANSPORT_ERROR;
231
- this.MESSAGE = MESSAGE;
232
- this.ACCEPTED = ACCEPTED;
233
- this.REJECTED = REJECTED;
234
- this.ON_TRACK = ON_TRACK;
235
- this.ON_REINVITE = ON_REINVITE;
236
- this.ON_ERROR = ON_ERROR;
237
- this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
238
- this.ON_NETWORK_STATS = ON_NETWORK_STATS;
239
- this.ON_DISCONNECTED = ON_DISCONNECTED;
240
- this.ON_EARLY_MEDIA = ON_EARLY_MEDIA;
241
- this.ON_PROGRESS = ON_PROGRESS;
242
- }
243
-
244
- configureMedia(media: MediaConfig) {
245
- this.hasAudio = !!media.audio;
246
- this.audioStreams = {};
247
- this.audioElements = {};
248
- }
249
-
250
- setMediaConstraints(media: MediaStreamConstraints) {
251
- this.video = media.video;
252
- this.audio = media.audio;
253
- }
254
-
255
- createUserAgent(uaConfigOverrides?: UserAgentConfigOverrides): UserAgent {
256
- const uaOptions = this._createUaOptions(uaConfigOverrides);
257
-
258
- logger.info('sdk webrtc, creating UA', {
259
- uaOptions: { ...uaOptions, authorizationPassword: `${uaOptions?.authorizationPassword?.slice(0, 5)}xxxx` },
260
- clientId: this.clientId,
261
- });
262
-
263
- uaOptions.delegate = {
264
- onConnect: this.onConnect.bind(this),
265
- onDisconnect: this.onDisconnect.bind(this),
266
- onInvite: (invitation: Invitation) => {
267
- logger.info('sdk webrtc on invite', {
268
- method: 'delegate.onInvite',
269
- clientId: this.clientId,
270
- id: this.getSipSessionId(invitation),
271
- remoteURI: (invitation as any).remoteURI,
272
- });
273
-
274
- this._setupSession(invitation);
275
-
276
- const shouldAutoAnswer = !!invitation.request.getHeader('alert-info');
277
- this.eventEmitter.emit(INVITE, invitation, this.sessionWantsToDoVideo(invitation), shouldAutoAnswer);
278
- },
279
- };
280
- const ua = new UserAgent(uaOptions);
281
- ua.start();
282
-
283
- if (ua.transport && (ua.transport as WazoTransport).connectPromise) {
284
- (ua.transport as WazoTransport).connectPromise.catch((e: any) => {
285
- logger.warn('Transport connect error', e);
286
- });
287
- }
288
-
289
- ua.transport.onMessage = (rawMessage: string) => {
290
- const message = Parser.parseMessage(rawMessage, (ua.transport as any).logger);
291
- // We have to re-sent the message to the UA ...
292
- // @ts-ignore: private
293
- ua.onTransportMessage(rawMessage);
294
- // And now do what we want with the message
295
- this.eventEmitter.emit(MESSAGE, message);
296
-
297
- if (message && message.method === C.MESSAGE) {
298
- // We have to manually reply to MESSAGE with a 200 OK or Asterisk will hangup.
299
- ua.userAgentCore.replyStateless(message as any, {
300
- statusCode: 200,
301
- });
302
- }
303
- };
304
-
305
- return ua;
306
- }
307
-
308
- isConnected(): boolean {
309
- return Boolean(this.userAgent?.isConnected());
310
- }
311
-
312
- isConnecting(): boolean {
313
- return this.userAgent?.transport?.state === TransportState.Connecting;
314
- }
315
-
316
- isRegistered(): boolean {
317
- return Boolean(this.registerer && this.registerer.state === RegistererState.Registered);
318
- }
319
-
320
- onConnect() {
321
- logger.info('sdk webrtc connected', { method: 'delegate.onConnect', clientId: this.clientId });
322
- this.eventEmitter.emit(CONNECTED);
323
-
324
- // @ts-ignore: private
325
- if (!this.isRegistered() && this.registerer?.waiting) {
326
- // @ts-ignore: private
327
- this.registerer.waitingToggle(false);
328
- }
329
-
330
- return this.register();
331
- }
332
-
333
- async onDisconnect(error?: Error) {
334
- logger.info('sdk webrtc disconnected', { method: 'delegate.onConnect', clientId: this.clientId, error });
335
- this.connectionPromise = null;
336
- // The UA will attempt to reconnect automatically when an error occurred
337
- this.eventEmitter.emit(DISCONNECTED, error);
338
-
339
- if (this.isRegistered()) {
340
- await this.unregister();
341
- // @ts-ignore: private
342
- if (this.registerer?.waiting) {
343
- // @ts-ignore: private
344
- this.registerer.waitingToggle(false);
345
- }
346
-
347
- this.eventEmitter.emit(UNREGISTERED);
348
- }
349
- }
350
-
351
- async register(tries = 0): Promise<void> {
352
- const logInfo = {
353
- clientId: this.clientId,
354
- userAgent: !!this.userAgent,
355
- registered: this.isRegistered(),
356
- connectionPromise: !!this.connectionPromise,
357
- registerer: !!this.registerer,
358
- // @ts-ignore: private
359
- waiting: this.registerer && this.registerer.waiting,
360
- tries,
361
- skipRegister: this.skipRegister,
362
- };
363
- this.forceClosed = false;
364
-
365
- if (this.skipRegister) {
366
- logger.info('sdk webrtc skip register...', logInfo);
367
- return Promise.resolve();
368
- }
369
-
370
- logger.info('sdk webrtc registering...', logInfo);
371
-
372
- if (!this.userAgent) {
373
- logger.info('sdk webrtc recreating User Agent');
374
- this.userAgent = this.createUserAgent(this.uaConfigOverrides);
375
- }
376
-
377
- if (!this.userAgent || this.isRegistered()) {
378
- logger.info('sdk webrtc registering aborted, already registered or no UA can be created');
379
- return Promise.resolve();
380
- }
381
-
382
- // @ts-ignore: private
383
- if (this.connectionPromise || this.registerer?.waiting) {
384
- logger.info('sdk webrtc registering aborted due to a registration in progress.', { clientId: this.clientId });
385
- return Promise.resolve();
386
- }
387
-
388
- const registerOptions = this._isWeb() ? {} : {
389
- extraContactHeaderParams: ['mobility=mobile'],
390
- };
391
-
392
- const onRegisterFailed = () => {
393
- logger.info('sdk webrtc registering failed', {
394
- tries,
395
- clientId: this.clientId,
396
- registerer: !!this.registerer,
397
- forceClosed: this.forceClosed,
398
- });
399
-
400
- if (this.forceClosed) {
401
- return;
402
- }
403
-
404
- this.connectionPromise = null;
405
-
406
- // @ts-ignore: private
407
- if (this.registerer && this.registerer.waiting) {
408
- // @ts-ignore: private
409
- this.registerer.waitingToggle(false);
410
- }
411
-
412
- if (tries <= MAX_REGISTER_TRIES) {
413
- logger.info('sdk webrtc registering, retrying...', { clientId: this.clientId, tries });
414
- setTimeout(() => this.register(tries + 1), 300);
415
- }
416
- };
417
-
418
- return this._connectIfNeeded().then(() => {
419
- // Avoid race condition with the close method called just before register and setting userAgent to null
420
- // during the resolution of the promise.
421
- if (!this.userAgent) {
422
- logger.info('sdk webrtc recreating User Agent after connection');
423
- this.userAgent = this.createUserAgent(this.uaConfigOverrides);
424
- }
425
-
426
- logger.info('sdk webrtc registering, transport connected', { registerOptions, ua: !!this.userAgent, clientId: this.clientId });
427
- this.registerer = new Registerer(this.userAgent, registerOptions);
428
- this.connectionPromise = null;
429
-
430
- this._monkeyPatchRegisterer(this.registerer);
431
-
432
- // Bind registerer events
433
- this.registerer.stateChange.addListener(newState => {
434
- logger.info('sdk webrtc registering, state changed', { newState, clientId: this.clientId });
435
-
436
- if (newState === RegistererState.Registered && this.registerer && this.registerer.state === RegistererState.Registered) {
437
- this.eventEmitter.emit(REGISTERED);
438
- } else if (newState === RegistererState.Unregistered) {
439
- this.eventEmitter.emit(UNREGISTERED);
440
- }
441
- });
442
- const options = {
443
- requestDelegate: {
444
- onReject: (response: any) => {
445
- logger.error('sdk webrtc registering, rejected', { clientId: this.clientId, response });
446
- onRegisterFailed();
447
- },
448
- },
449
- };
450
- return this.registerer.register(options).catch(e => {
451
- logger.error('sdk webrtc registering, error', e);
452
- this.eventEmitter.emit(REGISTRATION_FAILED);
453
- return e;
454
- });
455
- }).catch(error => {
456
- logger.error('sdk webrtc registering, transport error', error);
457
- onRegisterFailed();
458
- });
459
- }
460
-
461
- // Monkey patching sip.js to avoid issues during register.onReject
462
- _monkeyPatchRegisterer(registerer: Registerer | null | undefined): void {
463
- if (!registerer) {
464
- return;
465
- }
466
-
467
- // @ts-ignore: private
468
- const oldWaitingToggle = registerer.waitingToggle.bind(registerer);
469
- // @ts-ignore: private
470
- const oldUnregistered = registerer.unregistered.bind(registerer);
471
-
472
- // @ts-ignore: private
473
- registerer.waitingToggle = (waiting: boolean) => {
474
- // @ts-ignore: private
475
- if (!registerer || registerer.waiting === waiting) {
476
- return;
477
- }
478
-
479
- oldWaitingToggle(waiting);
480
- };
481
-
482
- // @ts-ignore: private
483
- registerer.unregistered = () => {
484
- if (!registerer || registerer.state === RegistererState.Terminated) {
485
- return;
486
- }
487
-
488
- oldUnregistered();
489
- };
490
- }
491
-
492
- async unregister(): Promise<void> {
493
- logger.info('sdk webrtc unregistering..', {
494
- clientId: this.clientId,
495
- userAgent: !!this.userAgent,
496
- registerer: !!this.registerer,
497
- });
498
-
499
- try {
500
- return new Promise((resolve, reject) => {
501
- if (!this.registerer) {
502
- return resolve();
503
- }
504
-
505
- const onRegisterStateChange = (state: string) => {
506
- if (state === RegistererState.Unregistered) {
507
- logger.info('sdk webrtc unregistered', { clientId: this.clientId });
508
- if (this.registerer) {
509
- this.registerer.stateChange.addListener(onRegisterStateChange);
510
- }
511
- this._cleanupRegister();
512
-
513
- resolve();
514
- }
515
- };
516
-
517
- this.registerer.stateChange.addListener(onRegisterStateChange);
518
-
519
- this.registerer.unregister().then().catch(e => {
520
- logger.error('sdk webrtc unregistering, promise error', e);
521
-
522
- this._cleanupRegister();
523
- reject();
524
- });
525
- });
526
- } catch (e: any) {
527
- logger.error('sdk webrtc unregistering, error', e);
528
-
529
- // Avoid issue with `undefined is not an object (evaluating 'new.target.prototype')` when triggering a new
530
- // error when the registerer is in a bad state
531
- this._cleanupRegister();
532
- }
533
- }
534
-
535
- stop(): Promise<void> {
536
- logger.info('sdk webrtc stop', { clientId: this.clientId, userAgent: !!this.userAgent });
537
-
538
- if (!this.userAgent) {
539
- return Promise.resolve();
540
- }
541
-
542
- return this.userAgent.stop().then(() => {
543
- return this._cleanupRegister();
544
- }).catch(e => {
545
- logger.warn('sdk webrtc stop, error', {
546
- message: e.message,
547
- stack: e.stack,
548
- });
549
- });
550
- }
551
-
552
- call(number: string, enableVideo?: boolean, audioOnly = false, conference = false, options = {}): WazoSession | null {
553
- logger.info('sdk webrtc creating call', {
554
- clientId: this.clientId,
555
- number,
556
- enableVideo,
557
- audioOnly,
558
- conference,
559
- options,
560
- });
561
- const inviterOptions: Record<string, any> = {
562
- sessionDescriptionHandlerOptionsReInvite: {
563
- conference,
564
- audioOnly,
565
- },
566
- earlyMedia: true,
567
- ...options,
568
- };
569
-
570
- if (audioOnly) {
571
- inviterOptions.sessionDescriptionHandlerModifiersReInvite = [stripVideo];
572
- }
573
-
574
- const uri = this._makeURI(number);
575
- let session: WazoSession | null = null;
576
-
577
- if (uri) {
578
- session = this.userAgent ? new Inviter(this.userAgent, uri, inviterOptions) : null;
579
- } else {
580
- logger.error('Null URI');
581
- }
582
-
583
- if (session) {
584
- this.storeSipSession(session);
585
-
586
- this._setupSession(session);
587
- }
588
-
589
- if (conference) {
590
- this.conferences[this.getSipSessionId(session)] = true;
591
- }
592
-
593
- const inviteOptions: InviterInviteOptions = {
594
- requestDelegate: {
595
- onAccept: (response: IncomingResponse) => {
596
- if ((session?.sessionDescriptionHandler as any)?.peerConnection) {
597
- (session?.sessionDescriptionHandler as any).peerConnection.sfu = conference;
598
- }
599
- this._onAccepted(session as WazoSession, response.session, true);
600
- },
601
- onProgress: (payload: IncomingResponse) => {
602
- this._onProgress(payload.session, payload.message.statusCode === 183);
603
- },
604
- onReject: (response: IncomingResponse) => {
605
- logger.info('on call rejected', {
606
- id: this.getSipSessionId(session),
607
- // @ts-ignore: fromTag does not exist
608
- fromTag: session?.fromTag,
609
- });
610
-
611
- this._stopSendingStats(session as WazoSession);
612
-
613
- this.stopNetworkMonitoring(session as WazoSession);
614
- this.eventEmitter.emit(REJECTED, session, response);
615
- },
616
- },
617
- sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false, conference),
618
- };
619
-
620
- if (inviteOptions.sessionDescriptionHandlerOptions) {
621
- (inviteOptions.sessionDescriptionHandlerOptions as SessionDescriptionHandlerOptions & { audioOnly?: boolean }).audioOnly = audioOnly;
622
- }
623
- inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
624
-
625
- if (audioOnly) {
626
- inviteOptions.sessionDescriptionHandlerModifiers.push(stripVideo);
627
- }
628
-
629
- if (session) {
630
- // Do not await invite here or we'll miss the Establishing state transition
631
- // @ts-ignore: Property 'invitePromise' does not exist
632
- session.invitePromise = session.invite(inviteOptions).catch((e: Error) => {
633
- logger.warn('sdk webrtc creating call, error', e);
634
- });
635
- }
636
-
637
- return session;
638
- }
639
-
640
- answer(session: Invitation, enableVideo?: boolean): Promise<void> {
641
- logger.info('sdk webrtc answer call', {
642
- clientId: this.clientId,
643
- id: this.getSipSessionId(session),
644
- enableVideo,
645
- });
646
-
647
- if (!session || !session.accept) {
648
- const error = 'No session to answer, or not an invitation';
649
- logger.warn(error);
650
- return Promise.reject(new Error(error));
651
- }
652
-
653
- const options = {
654
- sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false),
655
- };
656
- return this._accept(session, options).then(() => {
657
- // @ts-ignore: private
658
- if (session.isCanceled) {
659
- const message = 'accepted a canceled session (or was canceled during the accept phase).';
660
- logger.error(message, {
661
- id: this.getSipSessionId(session),
662
- });
663
- this.onCallEnded(session);
664
- throw new CanceledCallError(message);
665
- }
666
-
667
- logger.info('sdk webrtc answer, accepted.');
668
-
669
- this._onAccepted(session);
670
- }).catch(e => {
671
- logger.error(`answer call error for ${this.getSipSessionId(session)}`, e);
672
- throw e;
673
- });
674
- }
675
-
676
- async hangup(session: WazoSession): Promise<OutgoingByeRequest | null> {
677
- const { state, id } = session;
678
- logger.info('sdk webrtc hangup call', { clientId: this.clientId, id, state });
679
-
680
- try {
681
- this._stopSendingStats(session);
682
-
683
- this._cleanupMedia(session);
684
-
685
- delete this.sipSessions[this.getSipSessionId(session)];
686
- // Check if Invitation or Inviter (Invitation = incoming call)
687
- const isInviter = session instanceof Inviter;
688
-
689
- // @see github.com/onsip/SIP.js/blob/f11dfd584bc9788ccfc94e03034020672b738975/src/platform/web/simple-user/simple-user.ts#L1004
690
- const actions: Record<string, any> = {
691
- [SessionState.Initial]: isInviter ? this._cancel.bind(this, session) : this._reject.bind(this, session),
692
- [SessionState.Establishing]: isInviter ? this._cancel.bind(this, session) : this._reject.bind(this, session),
693
- [SessionState.Established]: this._bye.bind(this, session),
694
- };
695
-
696
- // Handle different session status
697
- if (actions[state]) {
698
- return await actions[state]();
699
- }
700
-
701
- return await this._bye(session);
702
- } catch (error: any) {
703
- logger.warn('sdk webrtc hangup, error', error);
704
- }
705
-
706
- return Promise.resolve(null);
707
- }
708
-
709
- async getStats(session: WazoSession): Promise<RTCStatsReport | null> {
710
- const pc = (session.sessionDescriptionHandler as SessionDescriptionHandler)?.peerConnection as RTCPeerConnection;
711
-
712
- if (!pc) {
713
- return null;
714
- }
715
-
716
- return pc.getStats(null);
717
- }
718
-
719
- // Fetch and emit an event at `interval` with session network stats
720
- startNetworkMonitoring(session: WazoSession, interval = 1000): void {
721
- const sessionId = this.getSipSessionId(session);
722
- logger.info('starting network inspection', {
723
- id: sessionId,
724
- clientId: this.clientId,
725
- });
726
- this.sessionNetworkStats[sessionId] = [];
727
- this.networkMonitoringInterval[sessionId] = setInterval(() => this._fetchNetworkStats(sessionId), interval);
728
- }
729
-
730
- stopNetworkMonitoring(session: WazoSession): void {
731
- const sessionId = this.getSipSessionId(session);
732
- const exists = (sessionId in this.networkMonitoringInterval);
733
- logger.info('stopping network inspection', {
734
- clientId: this.clientId,
735
- id: sessionId,
736
- exists,
737
- });
738
-
739
- if (exists) {
740
- clearInterval(this.networkMonitoringInterval[sessionId] as string);
741
- delete this.networkMonitoringInterval[sessionId];
742
- delete this.sessionNetworkStats[sessionId];
743
- }
744
- }
745
-
746
- async reject(session: WazoSession): Promise<void> {
747
- logger.info('sdk webrtc reject call', {
748
- clientId: this.clientId,
749
- id: this.getSipSessionId(session),
750
- });
751
-
752
- try {
753
- if (session instanceof Invitation) {
754
- return this._reject(session);
755
- }
756
-
757
- if (session instanceof Inviter) {
758
- return this._cancel(session);
759
- }
760
- } catch (e: any) {
761
- logger.warn('Error when rejecting call', e.message, e.stack);
762
- }
763
- }
764
-
765
- async close(force = false): Promise<void> {
766
- logger.info('sdk webrtc closing client', {
767
- clientId: this.clientId,
768
- userAgent: !!this.userAgent,
769
- force,
770
- });
771
- this.forceClosed = force;
772
-
773
- this._cleanupMedia();
774
-
775
- this.connectionPromise = null;
776
- (Object.values(this.audioElements) as any).forEach((audioElement: HTMLAudioElement) => {
777
- // eslint-disable-next-line
778
- audioElement.srcObject = null;
779
- audioElement.pause();
780
- });
781
- this.audioElements = {};
782
-
783
- if (!this.userAgent) {
784
- return;
785
- }
786
-
787
- this.stopHeartbeat();
788
- if (this.userAgent) {
789
- this.userAgent.delegate = undefined;
790
- }
791
- // @ts-ignore: removeAllListeners does not exist
792
- this.userAgent.stateChange.removeAllListeners();
793
- await this._disconnectTransport(force);
794
-
795
- this._cleanupRegister();
796
-
797
- try {
798
- // Prevent `Connect aborted.` error when disconnecting
799
- (this.userAgent.transport as WazoTransport & { connectReject: () => void }).connectReject = () => {};
800
- // Don't wait here, It can take ~30s to stop ...
801
- this.userAgent.stop().catch(console.error);
802
- } catch (_) { // Avoid to raise exception when trying to close with hanged-up sessions remaining
803
- // eg: "INVITE not rejectable in state Completed"
804
- }
805
-
806
- this.userAgent = null;
807
- logger.info('sdk webrtc client closed', { clientId: this.clientId });
808
- }
809
-
810
- getNumber(session: Inviter): string | null | undefined {
811
- if (!session) {
812
- return null;
813
- }
814
-
815
- // @ts-ignore: private
816
- return session.remoteIdentity.uri._normal.user;
817
- }
818
-
819
- mute(session: WazoSession): void {
820
- logger.info('sdk webrtc mute', {
821
- id: this.getSipSessionId(session),
822
- });
823
-
824
- this._toggleAudio(session, true);
825
- }
826
-
827
- unmute(session: WazoSession): void {
828
- logger.info('sdk webrtc unmute', {
829
- id: this.getSipSessionId(session),
830
- });
831
-
832
- this._toggleAudio(session, false);
833
- }
834
-
835
- isAudioMuted(session: WazoSession): boolean {
836
- if (!session || !session.sessionDescriptionHandler) {
837
- return false;
838
- }
839
-
840
- let muted = true;
841
- const pc = (session.sessionDescriptionHandler as SessionDescriptionHandler).peerConnection as PeerConnection;
842
-
843
- if (!pc) {
844
- return false;
845
- }
846
-
847
- if (pc.getSenders) {
848
- if (!pc.getSenders().length) {
849
- return false;
850
- }
851
-
852
- pc.getSenders().forEach((sender) => {
853
- if (sender && sender.track && sender.track.kind === 'audio') {
854
- muted = muted && !sender.track.enabled;
855
- }
856
- });
857
- } else {
858
- if (!pc.getLocalStreams().length) {
859
- return false;
860
- }
861
-
862
- pc.getLocalStreams().forEach((stream: MediaStream) => {
863
- stream.getAudioTracks().forEach(track => {
864
- muted = muted && !track.enabled;
865
- });
866
- });
867
- }
868
-
869
- return muted;
870
- }
871
-
872
- toggleCameraOn(session: WazoSession): void {
873
- logger.info('sdk webrtc toggle camera on', {
874
- id: this.getSipSessionId(session),
875
- });
876
-
877
- this._toggleVideo(session, false);
878
- }
879
-
880
- toggleCameraOff(session: WazoSession): void {
881
- logger.info('sdk webrtc toggle camera off', {
882
- id: this.getSipSessionId(session),
883
- });
884
-
885
- this._toggleVideo(session, true);
886
- }
887
-
888
- hold(session: WazoSession, isConference = false, hadVideo = false): Promise<OutgoingInviteRequest | void> {
889
- const sessionId = this.getSipSessionId(session);
890
- const hasVideo = hadVideo || this.hasLocalVideo(sessionId);
891
- logger.info('sdk webrtc hold', {
892
- sessionId,
893
- keys: Object.keys(this.heldSessions),
894
- // @ts-ignore: private
895
- pendingReinvite: !!session.pendingReinvite,
896
- isConference,
897
- hasVideo,
898
- });
899
-
900
- if (sessionId in this.heldSessions) {
901
- return Promise.resolve();
902
- }
903
-
904
- // @ts-ignore: private
905
- if (session.pendingReinvite) {
906
- return Promise.resolve();
907
- }
908
-
909
- this.heldSessions[sessionId] = {
910
- hasVideo,
911
- isConference,
912
- };
913
-
914
- // We should also mute the call, because when holding a call during a voicemail, the audio is still sent with the
915
- // `sendonly` direction
916
- this.mute(session);
917
-
918
- session.sessionDescriptionHandlerOptionsReInvite = {
919
- hold: true,
920
- conference: isConference,
921
- } as SessionDescriptionHandlerOptions;
922
- const options = this.getMediaConfiguration(false, isConference);
923
-
924
- if (!this._isWeb()) {
925
- options.sessionDescriptionHandlerModifiers = [holdModifier];
926
- }
927
-
928
- options.sessionDescriptionHandlerOptions = {
929
- constraints: options.constraints,
930
- hold: true,
931
- conference: isConference,
932
- };
933
-
934
- // Avoid sdh to create a new stream
935
- if (session.sessionDescriptionHandler) {
936
- // @ts-ignore: private
937
- (session.sessionDescriptionHandler as SessionDescriptionHandler).localMediaStreamConstraints = options.constraints;
938
- }
939
-
940
- // Send re-INVITE
941
- return session.invite(options).catch((e: Error) => {
942
- logger.warn('sdk webrtc re-invite during hold, error', e);
943
- });
944
- }
945
-
946
- unhold(session: WazoSession, isConference = false): Promise<OutgoingInviteRequest | void> {
947
- const sessionId = this.getSipSessionId(session);
948
- const hasVideo = sessionId in this.heldSessions && this.heldSessions[sessionId].hasVideo;
949
- logger.info('sdk webrtc unhold', {
950
- sessionId,
951
- keys: Object.keys(this.heldSessions),
952
- // @ts-ignore: private
953
- pendingReinvite: !!session.pendingReinvite,
954
- isConference,
955
- hasVideo,
956
- });
957
-
958
- // @ts-ignore: private
959
- if (session.pendingReinvite) {
960
- return Promise.resolve();
961
- }
962
-
963
- this.unmute(session);
964
-
965
- delete this.heldSessions[this.getSipSessionId(session)];
966
- session.sessionDescriptionHandlerOptionsReInvite = {
967
- hold: false,
968
- conference: isConference,
969
- } as SessionDescriptionHandlerOptions;
970
- const options = this.getMediaConfiguration(false, isConference);
971
-
972
- if (!this._isWeb()) {
973
- // We should sent an empty `sessionDescriptionHandlerModifiers` or sip.js will take the last sent modifiers
974
- // (eg: holdModifier)
975
- options.sessionDescriptionHandlerModifiers = [];
976
- }
977
-
978
- options.sessionDescriptionHandlerOptions = {
979
- constraints: options.constraints,
980
- hold: false,
981
- conference: isConference,
982
- };
983
- // Send re-INVITE
984
- return session.invite(options).catch((e: Error) => {
985
- logger.warn('sdk webrtc re-invite during resume, error', e);
986
- });
987
- }
988
-
989
- // Returns true if a re-INVITE is required
990
- async upgradeToVideo(session: WazoSession, constraints: Record<string, any>, isConference: boolean): Promise<MediaStream | undefined> {
991
- const pc = (session.sessionDescriptionHandler as SessionDescriptionHandler)?.peerConnection;
992
- // Check if a video sender already exists
993
- let videoSender;
994
-
995
- if (isConference) {
996
- // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
997
- const transceivers = pc?.getTransceivers() || [];
998
- const transceiverIdx = lastIndexOf(transceivers, transceiver => transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
999
- videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
1000
- } else {
1001
- videoSender = pc && pc.getSenders && pc.getSenders().find((sender) => sender.track === null);
1002
- }
1003
-
1004
- if (!videoSender) {
1005
- // When no video sender found, it means that we're in the first video upgrade in 1:1
1006
- return;
1007
- }
1008
-
1009
- // Reuse bidirectional video stream
1010
- const newStream = await this.getStreamFromConstraints(constraints);
1011
-
1012
- if (!newStream) {
1013
- console.warn(`Can't create media stream with: ${JSON.stringify(constraints || {})}`);
1014
- return;
1015
- }
1016
-
1017
- // Add previous local audio track
1018
- if (constraints && !constraints.audio) {
1019
- const localVideoStream: MediaStream = (session.sessionDescriptionHandler as SessionDescriptionHandler)?.localMediaStream;
1020
- const localAudioTrack = localVideoStream.getTracks().find(track => track.kind === 'audio');
1021
-
1022
- if (localAudioTrack) {
1023
- newStream.addTrack(localAudioTrack);
1024
- }
1025
- }
1026
-
1027
- const videoTrack = newStream.getVideoTracks()[0];
1028
-
1029
- if (videoTrack) {
1030
- videoSender.replaceTrack(videoTrack);
1031
- }
1032
-
1033
- this.setLocalMediaStream(this.getSipSessionId(session), newStream);
1034
- return newStream;
1035
- }
1036
-
1037
- downgradeToAudio(session: WazoSession): void {
1038
- // Release local video stream when downgrading to audio
1039
- const sessionDescriptionHandler = session.sessionDescriptionHandler as SessionDescriptionHandler;
1040
- const localStream = sessionDescriptionHandler?.localMediaStream;
1041
- const pc = sessionDescriptionHandler?.peerConnection;
1042
- const videoTracks = localStream.getVideoTracks();
1043
-
1044
- // Remove video senders
1045
- if (pc?.getSenders) {
1046
- pc.getSenders().filter((sender) => sender.track && sender.track.kind === 'video').forEach((videoSender) => {
1047
- videoSender.replaceTrack(null);
1048
- });
1049
- }
1050
-
1051
- videoTracks.forEach((videoTrack: MediaStreamTrack) => {
1052
- videoTrack.enabled = false;
1053
- videoTrack.stop();
1054
- localStream.removeTrack(videoTrack);
1055
- });
1056
- }
1057
-
1058
- async getStreamFromConstraints(constraints: Record<string, any>, conference = false): Promise<MediaStream | null | undefined> {
1059
- const video = constraints && constraints.video;
1060
- const {
1061
- constraints: newConstraints,
1062
- } = this.getMediaConfiguration(video, conference, constraints);
1063
- let newStream: MediaStream & { local?: boolean } | null = null;
1064
-
1065
- try {
1066
- newStream = await wazoMediaStreamFactory(newConstraints);
1067
- } catch (e: any) { // Nothing to do when the user cancel the screensharing prompt
1068
- }
1069
-
1070
- if (!newStream) {
1071
- return null;
1072
- }
1073
-
1074
- newStream.local = true;
1075
- return newStream;
1076
- }
1077
-
1078
- getHeldSession(sessionId: string) {
1079
- return this.heldSessions[sessionId];
1080
- }
1081
-
1082
- isCallHeld(session: WazoSession): boolean {
1083
- return this.getSipSessionId(session) in this.heldSessions;
1084
- }
1085
-
1086
- isVideoRemotelyHeld(sessionId: string): boolean {
1087
- const pc = this.getPeerConnection(sessionId);
1088
- const sdp = pc && pc.remoteDescription ? pc.remoteDescription.sdp : null;
1089
-
1090
- if (!sdp) {
1091
- return false;
1092
- }
1093
-
1094
- const videoDirection = getVideoDirection(sdp);
1095
- return videoDirection === 'sendonly';
1096
- }
1097
-
1098
- sendDTMF(session: WazoSession, tone: string): boolean {
1099
- if (!session.sessionDescriptionHandler) {
1100
- return false;
1101
- }
1102
-
1103
- logger.info('Sending DTMF', {
1104
- id: this.getSipSessionId(session),
1105
- tone,
1106
- });
1107
- return session.sessionDescriptionHandler.sendDtmf(tone);
1108
- }
1109
-
1110
- message(destination: string, message: string): void {
1111
- const uri = this._makeURI(destination);
1112
- if (!this.userAgent || !uri) {
1113
- logger.warn('Null value on message', { uri, userAgent: this.userAgent });
1114
- return;
1115
- }
1116
- const messager = new Messager(this.userAgent, uri, message);
1117
- messager.message();
1118
- }
1119
-
1120
- transfer(session: WazoSession, target: string): void {
1121
- this.hold(session);
1122
- logger.info('Transfering a session', {
1123
- id: this.getSipSessionId(session),
1124
- target,
1125
- });
1126
- const options = {
1127
- requestDelegate: {
1128
- onAccept: () => {
1129
- this.hangup(session);
1130
- },
1131
- },
1132
- };
1133
- setTimeout(() => {
1134
- const uri = this._makeURI(target);
1135
- if (!uri) {
1136
- logger.warn('transfer timeout: null URI');
1137
- return;
1138
- }
1139
- session.refer(uri, options);
1140
- }, 50);
1141
- }
1142
-
1143
- // check https://sipjs.com/api/0.12.0/refer/referClientContext/
1144
- atxfer(session: WazoSession): Record<string, any> {
1145
- this.hold(session);
1146
- logger.info('webrtc transfer started', {
1147
- id: this.getSipSessionId(session),
1148
- });
1149
- const result: Record<string, any> = {
1150
- newSession: null,
1151
- init: async (target: string) => {
1152
- logger.info('webrtc transfer initialized', {
1153
- id: this.getSipSessionId(session),
1154
- target,
1155
- });
1156
- result.newSession = await this.call(target);
1157
- },
1158
- complete: () => {
1159
- logger.info('webrtc transfer completed', {
1160
- id: this.getSipSessionId(session),
1161
- referId: this.getSipSessionId(result.newSession),
1162
- });
1163
- session.refer(result.newSession);
1164
- },
1165
- cancel: () => {
1166
- this.hangup(result.newSession);
1167
- this.unhold(session);
1168
- },
1169
- };
1170
- return result;
1171
- }
1172
-
1173
- // eslint-disable-next-line @typescript-eslint/default-param-last
1174
- sendMessage(sipSession: WazoSession | null = null, body: string, contentType = 'text/plain'): void {
1175
- if (!sipSession) {
1176
- return;
1177
- }
1178
-
1179
- logger.info('send WebRTC message', {
1180
- sipId: this.getSipSessionId(sipSession),
1181
- contentType,
1182
- });
1183
-
1184
- try {
1185
- sipSession.message({
1186
- requestOptions: {
1187
- body: {
1188
- content: body,
1189
- contentType,
1190
- // @HEADSUP: contentDisposition is a required string, setting it to '' arbitrarily
1191
- contentDisposition: '',
1192
- },
1193
- },
1194
- });
1195
- } catch (e: any) {
1196
- console.warn(e);
1197
- }
1198
- }
1199
-
1200
- pingServer(): OutgoingRequest | void {
1201
- if (!this.isConnected()) {
1202
- return;
1203
- }
1204
-
1205
- const core = this.userAgent?.userAgentCore;
1206
-
1207
- const fromURI = this._makeURI(this.config.authorizationUser || '');
1208
-
1209
- const toURI = new URI('sip', '', this.config.host);
1210
- if (fromURI) {
1211
- const message = core?.makeOutgoingRequestMessage('OPTIONS', toURI, fromURI, toURI, {});
1212
-
1213
- if (message) {
1214
- return core?.request(message);
1215
- }
1216
-
1217
- logger.warn('pingServer: null message');
1218
- }
1219
- logger.warn('pingServer: null fromURI');
1220
- }
1221
-
1222
- getState(): UserAgentState {
1223
- // @ts-ignore: something fishy here: `states` content doesn't match UserAgentState at all
1224
- return this.userAgent ? states[this.userAgent.state] as UserAgentState : UserAgentState.Stopped;
1225
- }
1226
-
1227
- getContactIdentifier(): string | null {
1228
- return this.userAgent ? `${this.userAgent.configuration.contactName}/${this.userAgent.contact.uri}` : null;
1229
- }
1230
-
1231
- isFirefox(): boolean {
1232
- return this._isWeb() && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
1233
- }
1234
-
1235
- changeAudioOutputVolume(volume: number): void {
1236
- logger.info('Changing audio output volume', {
1237
- volume,
1238
- });
1239
- Object.values(this.audioElements).forEach(audioElement => {
1240
- if (audioElement instanceof HTMLAudioElement) {
1241
- // eslint-disable-next-line no-param-reassign
1242
- audioElement.volume = volume;
1243
- }
1244
- });
1245
- this.audioOutputVolume = volume;
1246
- }
1247
-
1248
- async changeAudioOutputDevice(id: string) {
1249
- logger.info('Changing audio output device', {
1250
- id,
1251
- });
1252
- this.audioOutputDeviceId = id;
1253
- const promises: Promise<void>[] = [];
1254
- Object.values(this.audioElements).forEach(audioElement => promises.push(audioElement.setSinkId(id)));
1255
- await Promise.allSettled(promises);
1256
- }
1257
-
1258
- async changeAudioInputDevice(id: string, session: WazoSession | null | undefined, force?: boolean): Promise<MediaStream | null> {
1259
- const currentId = this.getAudioDeviceId();
1260
- logger.info('setting audio input device', {
1261
- id,
1262
- currentId,
1263
- session: !!session,
1264
- });
1265
-
1266
- if (!force && id === currentId) {
1267
- return null;
1268
- }
1269
-
1270
- // in order to handle an audio track change for default devices
1271
- // we need the actual id of the device (not 'default')
1272
- let deviceId = id;
1273
-
1274
- if (id === 'default' && navigator.mediaDevices) {
1275
- const devices = await navigator.mediaDevices.enumerateDevices();
1276
- const defaultDevice = devices.find(device => device.deviceId === 'default');
1277
-
1278
- if (defaultDevice) {
1279
- const deviceLabel = defaultDevice.label.replace('Default - ', '');
1280
- const targetDevice = devices.find(device => device.label === deviceLabel);
1281
-
1282
- if (targetDevice) {
1283
- deviceId = targetDevice.deviceId;
1284
-
1285
- if (!force && deviceId === currentId) {
1286
- return null;
1287
- }
1288
- }
1289
- }
1290
- }
1291
-
1292
- // let's update the local audio value
1293
- if (this.audio) {
1294
- this.audio = {
1295
- deviceId: {
1296
- exact: deviceId,
1297
- },
1298
- };
1299
- }
1300
-
1301
- if (session && navigator.mediaDevices) {
1302
- const sdh = session.sessionDescriptionHandler as SessionDescriptionHandler;
1303
- const pc = sdh?.peerConnection;
1304
- const constraints = {
1305
- audio: {
1306
- deviceId: {
1307
- exact: deviceId,
1308
- },
1309
- },
1310
- };
1311
- const stream = await navigator.mediaDevices.getUserMedia(constraints);
1312
- const audioTrack = stream.getAudioTracks()[0];
1313
- const sender = pc && pc.getSenders && pc.getSenders().find((s) => audioTrack && s && s.track && s.track.kind === audioTrack.kind);
1314
-
1315
- if (sender) {
1316
- if (sender.track) {
1317
- audioTrack.enabled = sender.track.enabled;
1318
- }
1319
-
1320
- sender.replaceTrack(audioTrack);
1321
- }
1322
-
1323
- return stream;
1324
- }
1325
-
1326
- return null;
1327
- }
1328
-
1329
- async changeVideoInputDevice(id: string, session?: WazoSession): Promise<MediaStream | void> {
1330
- this.setVideoInputDevice(id);
1331
-
1332
- if (session) {
1333
- return this.changeSessionVideoInputDevice(id, session);
1334
- }
1335
- }
1336
-
1337
- setVideoInputDevice(id: string) {
1338
- const currentId = this.getVideoDeviceId();
1339
- logger.info('setting video input device', {
1340
- id,
1341
- currentId,
1342
- });
1343
-
1344
- if (id === currentId) {
1345
- return null;
1346
- }
1347
-
1348
- // let's make sure we don't lose other video constraints settings -- width, height, frameRate...
1349
- const videoObject = typeof this.video === 'object' ? this.video : {};
1350
- this.video = { ...videoObject,
1351
- deviceId: {
1352
- exact: id,
1353
- },
1354
- };
1355
- }
1356
-
1357
- changeSessionVideoInputDevice(id: string | null | undefined, session: WazoSession): Promise<MediaStream | void> {
1358
- if (!this.sessionWantsToDoVideo(session)) {
1359
- return Promise.resolve();
1360
- }
1361
-
1362
- const sdh = session.sessionDescriptionHandler as SessionDescriptionHandler;
1363
- const pc = sdh.peerConnection;
1364
- const sessionId = this.getSipSessionId(session);
1365
- const localStream = this.getLocalStream(sessionId);
1366
- logger.info('changing video input device', {
1367
- id,
1368
- sessionId,
1369
- });
1370
-
1371
- // Release old video stream
1372
- if (localStream) {
1373
- localStream.getVideoTracks()
1374
- .filter((track: MediaStreamTrack) => track.enabled)
1375
- .forEach((track: MediaStreamTrack) => track.stop());
1376
- }
1377
-
1378
- const constraints = {
1379
- video: id ? {
1380
- deviceId: {
1381
- exact: id,
1382
- },
1383
- } : true,
1384
- };
1385
- return navigator.mediaDevices.getUserMedia(constraints).then(async stream => {
1386
- const videoTrack = stream.getVideoTracks()[0];
1387
- let sender = pc && pc.getSenders && pc.getSenders().find((s) => videoTrack && s && s.track && s.track.kind === videoTrack.kind);
1388
- let wasTrackEnabled = false;
1389
-
1390
- if (!sender) {
1391
- sender = pc && pc.getSenders && pc.getSenders().find((s: any) => !s.track);
1392
- }
1393
-
1394
- if (sender) {
1395
- // No video track means video not enabled
1396
- wasTrackEnabled = sender.track ? sender.track.enabled : false;
1397
- videoTrack.enabled = wasTrackEnabled;
1398
-
1399
- if (!wasTrackEnabled) {
1400
- videoTrack.stop();
1401
- }
1402
-
1403
- sender.replaceTrack(wasTrackEnabled ? videoTrack : null);
1404
- }
1405
-
1406
- // let's update the local stream
1407
- this.eventEmitter.emit('onVideoInputChange', stream);
1408
- this.setLocalMediaStream(sessionId, stream);
1409
- return stream;
1410
- });
1411
- }
1412
-
1413
- getAudioDeviceId(): string | null | undefined {
1414
- return this.audio && typeof this.audio === 'object' && 'deviceId' in this.audio ? (this.audio.deviceId as any)?.exact : undefined;
1415
- }
1416
-
1417
- getVideoDeviceId(): string | null {
1418
- return this.video && typeof this.video === 'object' && 'deviceId' in this.video ? (this.video.deviceId as any)?.exact : undefined;
1419
- }
1420
-
1421
- reinvite(sipSession: WazoSession, newConstraints: Record<string, any> | null | undefined = null, conference = false, audioOnly = false, iceRestart = false): Promise<OutgoingInviteRequest | void> {
1422
- if (!sipSession) {
1423
- return Promise.resolve();
1424
- }
1425
-
1426
- // @ts-ignore: private
1427
- if (sipSession.pendingReinvite) {
1428
- return Promise.resolve();
1429
- }
1430
-
1431
- const wasMuted = this.isAudioMuted(sipSession);
1432
- const shouldDoVideo = newConstraints ? newConstraints.video : this.sessionWantsToDoVideo(sipSession);
1433
- const shouldDoScreenSharing = newConstraints && newConstraints.screen;
1434
- const desktop = newConstraints && newConstraints.desktop;
1435
- logger.info('Sending reinvite', {
1436
- clientId: this.clientId,
1437
- id: this.getSipSessionId(sipSession),
1438
- newConstraints,
1439
- conference,
1440
- audioOnly,
1441
- wasMuted,
1442
- shouldDoVideo,
1443
- shouldDoScreenSharing,
1444
- desktop,
1445
- });
1446
-
1447
- // When upgrading to video, remove the `stripVideo` modifiers
1448
- if (newConstraints && newConstraints.video) {
1449
- const modifiers = sipSession.sessionDescriptionHandlerModifiersReInvite;
1450
- sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier => modifier !== stripVideo);
1451
- }
1452
-
1453
- sipSession.sessionDescriptionHandlerOptionsReInvite = { ...sipSession.sessionDescriptionHandlerOptionsReInvite,
1454
- conference,
1455
- audioOnly,
1456
- } as SessionDescriptionHandlerOptions;
1457
- const {
1458
- constraints,
1459
- } = this.getMediaConfiguration(shouldDoVideo, conference, newConstraints);
1460
- return sipSession.invite({
1461
- requestDelegate: {
1462
- onAccept: (response: IncomingResponse) => {
1463
- // Update the SDP body to be able to call sessionWantsToDoVideo correctly in `_setup[Local|Remote]Media`.
1464
- // Can't set directly sipSession.body because it's a getter.
1465
- // @ts-ignore: private
1466
- if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage.body) {
1467
- // @ts-ignore: private
1468
- sipSession.outgoingRequestMessage.body.body = response.message.body;
1469
- } else if (sipSession instanceof Invitation) {
1470
- // @ts-ignore: private
1471
- sipSession.incomingInviteRequest.message.body = response.message.body;
1472
- }
1473
-
1474
- logger.info('on re-INVITE accepted', {
1475
- id: this.getSipSessionId(sipSession),
1476
- wasMuted,
1477
- shouldDoScreenSharing,
1478
- });
1479
- this.updateRemoteStream(this.getSipSessionId(sipSession), false);
1480
-
1481
- if (wasMuted) {
1482
- this.mute(sipSession);
1483
- }
1484
-
1485
- this._onAccepted(sipSession, response.session, false, false);
1486
-
1487
- if (shouldDoScreenSharing) {
1488
- this.eventEmitter.emit(ON_SCREEN_SHARING_REINVITE, sipSession, response, desktop);
1489
- }
1490
-
1491
- return this.eventEmitter.emit(ON_REINVITE, sipSession, response);
1492
- },
1493
- },
1494
- sessionDescriptionHandlerModifiers: [replaceLocalIpModifier],
1495
- requestOptions: {
1496
- extraHeaders: [`Subject: ${shouldDoScreenSharing ? 'screenshare' : 'upgrade-video'}`],
1497
- },
1498
- sessionDescriptionHandlerOptions: {
1499
- constraints,
1500
- conference,
1501
- audioOnly,
1502
- offerOptions: {
1503
- iceRestart,
1504
- },
1505
- } as SessionDescriptionHandlerOptions,
1506
- });
1507
- }
1508
-
1509
- async getUserMedia(constraints: Record<string, any>): Promise<MediaStream> {
1510
- const newConstraints = {
1511
- audio: this._getAudioConstraints(),
1512
- video: this._getVideoConstraints(constraints.video),
1513
- };
1514
- return navigator.mediaDevices.getUserMedia(newConstraints);
1515
- }
1516
-
1517
- getPeerConnection(sessionId: string) {
1518
- const sipSession = this.sipSessions[sessionId];
1519
-
1520
- if (!sipSession) {
1521
- return null;
1522
- }
1523
-
1524
- return sipSession.sessionDescriptionHandler ? (sipSession.sessionDescriptionHandler as SessionDescriptionHandler).peerConnection : null;
1525
- }
1526
-
1527
- // Local streams
1528
- getLocalStream(sessionId: string): MediaStream | null {
1529
- const sipSession = this.sipSessions[sessionId];
1530
- return (sipSession?.sessionDescriptionHandler as SessionDescriptionHandler)?.localMediaStream || null;
1531
- }
1532
-
1533
- getLocalTracks(sessionId: string): MediaStreamTrack[] {
1534
- const localStream = this.getLocalStream(sessionId);
1535
-
1536
- if (!localStream) {
1537
- return [];
1538
- }
1539
-
1540
- return localStream.getTracks();
1541
- }
1542
-
1543
- hasLocalVideo(sessionId: string): boolean {
1544
- return this.getLocalTracks(sessionId).some(this._isVideoTrack);
1545
- }
1546
-
1547
- // Check if we have at least one video track, even muted or not live
1548
- hasALocalVideoTrack(sessionId: string): boolean {
1549
- return this.getLocalTracks(sessionId).some(track => track.kind === 'video');
1550
- }
1551
-
1552
- getLocalVideoStream(sessionId: string): MediaStream | null | undefined {
1553
- return this.hasLocalVideo(sessionId) ? this.getLocalStream(sessionId) : null;
1554
- }
1555
-
1556
- // Remote streams
1557
- getRemoteStream(sessionId: string): MediaStream | null {
1558
- const sipSession = this.sipSessions[sessionId];
1559
- return (sipSession?.sessionDescriptionHandler as SessionDescriptionHandler)?.remoteMediaStream || null;
1560
- }
1561
-
1562
- getRemoteTracks(sessionId: string): MediaStreamTrack[] {
1563
- const remoteStream = this.getRemoteStream(sessionId);
1564
-
1565
- if (!remoteStream) {
1566
- return [];
1567
- }
1568
-
1569
- return remoteStream.getTracks();
1570
- }
1571
-
1572
- hasRemoteVideo(sessionId: string): boolean {
1573
- return this.getRemoteTracks(sessionId).some(this._isVideoTrack);
1574
- }
1575
-
1576
- // Check if we have at least one video track, even muted or not live
1577
- hasARemoteVideoTrack(sessionId: string): boolean {
1578
- return this.getRemoteTracks(sessionId).some(track => track.kind === 'video');
1579
- }
1580
-
1581
- getRemoteVideoStream(sessionId: string): MediaStream | null | undefined {
1582
- if (this.isVideoRemotelyHeld(sessionId)) {
1583
- return null;
1584
- }
1585
-
1586
- return this.hasRemoteVideo(sessionId) ? this.getRemoteStream(sessionId) : null;
1587
- }
1588
-
1589
- // Useful in a react-native environment when remoteMediaStream is not updated
1590
- getRemoteVideoStreamFromPc(sessionId: string): MediaStream | null | undefined {
1591
- const pc = this.getPeerConnection(sessionId) as PeerConnection;
1592
-
1593
- if (!pc) {
1594
- return null;
1595
- }
1596
-
1597
- return pc.getRemoteStreams().find((stream: MediaStream) => !!stream.getVideoTracks().length);
1598
- }
1599
-
1600
- hasVideo(sessionId: string): boolean {
1601
- return this.hasLocalVideo(sessionId) || this.hasRemoteVideo(sessionId);
1602
- }
1603
-
1604
- hasAVideoTrack(sessionId: string): boolean {
1605
- return this.hasALocalVideoTrack(sessionId) || this.hasARemoteVideoTrack(sessionId);
1606
- }
1607
-
1608
- getSipSessionId(sipSession: WazoSession | null | undefined): string {
1609
- if (!sipSession) {
1610
- return '';
1611
- }
1612
-
1613
- // For Inviter
1614
- // @ts-ignore: private
1615
- if (sipSession instanceof Inviter && sipSession.outgoingRequestMessage) {
1616
- // @ts-ignore: private
1617
- return sipSession.outgoingRequestMessage.callId;
1618
- }
1619
-
1620
- // For Invitation
1621
- // @ts-ignore: private
1622
- if (sipSession instanceof Invitation && sipSession.incomingInviteRequest.message) {
1623
- // @ts-ignore: private
1624
- return sipSession.incomingInviteRequest.message.callId;
1625
- }
1626
-
1627
- // For EarlyMedia
1628
- // @ts-ignore: private
1629
- if (sipSession instanceof SessionDialog) {
1630
- // @ts-ignore: private
1631
- return sipSession.dialogState.callId;
1632
- }
1633
-
1634
- return '';
1635
- }
1636
-
1637
- async waitForRegister(): Promise<void> {
1638
- return new Promise(resolve => this.on(REGISTERED, resolve));
1639
- }
1640
-
1641
- // eslint-disable-next-line no-unused-vars
1642
- sessionWantsToDoVideo(session: WazoSession): boolean {
1643
- if (!session) {
1644
- return false;
1645
- }
1646
-
1647
- const {
1648
- body,
1649
- } = session.request || session;
1650
- // Sometimes with InviteClientContext the body is in the body attribute ...
1651
- const sdp = typeof body === 'object' && body ? body.body : body;
1652
- return hasAnActiveVideo(sdp);
1653
- }
1654
-
1655
- hasHeartbeat(): boolean {
1656
- return this.heartbeat.hasHeartbeat;
1657
- }
1658
-
1659
- startHeartbeat(): void {
1660
- logger.info('sdk webrtc start heartbeat', { userAgent: !!this.userAgent, clientId: this.clientId });
1661
-
1662
- if (!this.userAgent) {
1663
- this.heartbeat.stop();
1664
- return;
1665
- }
1666
-
1667
- this.eventEmitter.off(MESSAGE, this._boundOnHeartbeat);
1668
- this.eventEmitter.on(MESSAGE, this._boundOnHeartbeat);
1669
- this.heartbeat.start();
1670
- }
1671
-
1672
- stopHeartbeat(): void {
1673
- logger.info('sdk webrtc stop heartbeat', { clientId: this.clientId });
1674
- this.heartbeat.stop();
1675
- }
1676
-
1677
- setOnHeartbeatTimeout(cb: (...args: Array<any>) => any): void {
1678
- this.heartbeatTimeoutCb = cb;
1679
- }
1680
-
1681
- setOnHeartbeatCallback(cb: (...args: Array<any>) => any): void {
1682
- this.heartbeatCb = cb;
1683
- }
1684
-
1685
- onCallEnded(session: WazoSession): void {
1686
- this._cleanupMedia(session);
1687
-
1688
- delete this.sipSessions[this.getSipSessionId(session)];
1689
-
1690
- this._stopSendingStats(session);
1691
-
1692
- this.stopNetworkMonitoring(session);
1693
- }
1694
-
1695
- attemptReconnection(): void {
1696
- logger.info('attempt reconnection', { clientId: this.clientId, userAgent: !!this.userAgent });
1697
-
1698
- if (!this.userAgent) {
1699
- return;
1700
- }
1701
-
1702
- // @ts-ignore: private
1703
- this.userAgent.attemptReconnection();
1704
- }
1705
-
1706
- storeSipSession(session: WazoSession): void {
1707
- const id = this.getSipSessionId(session);
1708
- logger.info('storing sip session', { id, clientId: this.clientId });
1709
-
1710
- this.sipSessions[id] = session;
1711
- }
1712
-
1713
- getSipSession(id: string): WazoSession | null | undefined {
1714
- return id in this.sipSessions ? this.sipSessions[id] : null;
1715
- }
1716
-
1717
- getSipSessionIds(): string[] {
1718
- return Object.keys(this.sipSessions);
1719
- }
1720
-
1721
- setLocalMediaStream(sipSessionId: string, newStream: MediaStream): void {
1722
- const sipSession = this.sipSessions[sipSessionId];
1723
-
1724
- if (!sipSession) {
1725
- return;
1726
- }
1727
-
1728
- logger.info('setting local media stream', {
1729
- sipSessionId,
1730
- tracks: newStream ? newStream.getTracks() : null,
1731
- });
1732
- if (sipSession.sessionDescriptionHandler) {
1733
- // eslint-disable-next-line no-underscore-dangle
1734
- // @ts-ignore: protected
1735
- sipSession.sessionDescriptionHandler._localMediaStream = newStream;
1736
- }
1737
- }
1738
-
1739
- async updateLocalStream(sipSessionId: string, newStream: MediaStream): Promise<void> {
1740
- const sipSession = this.sipSessions[sipSessionId];
1741
-
1742
- if (!sipSession) {
1743
- return;
1744
- }
1745
-
1746
- const oldStream = this.getLocalStream(sipSessionId);
1747
- logger.info('updating local stream', {
1748
- sipSessionId,
1749
- oldStream: !!oldStream,
1750
- tracks: newStream.getTracks(),
1751
- });
1752
-
1753
- if (oldStream) {
1754
- this._cleanupStream(oldStream);
1755
- }
1756
-
1757
- this.setLocalMediaStream(sipSessionId, newStream);
1758
-
1759
- // Update the local video element
1760
- await this._setupMedias(sipSession, newStream);
1761
- }
1762
-
1763
- updateRemoteStream(sessionId: string, allTracks = true): void {
1764
- const remoteStream = this.getRemoteStream(sessionId);
1765
- const pc = this.getPeerConnection(sessionId);
1766
- logger.info('Updating remote stream', {
1767
- sessionId,
1768
- tracks: remoteStream ? remoteStream.getTracks() : null,
1769
- receiverTracks: pc && pc.getReceivers ? pc.getReceivers().map((receiver) => receiver.track) : null,
1770
- });
1771
-
1772
- if (!pc || !remoteStream) {
1773
- return;
1774
- }
1775
-
1776
- remoteStream.getTracks().forEach(track => {
1777
- if (allTracks || track.kind === 'video') {
1778
- remoteStream.removeTrack(track);
1779
- }
1780
- });
1781
-
1782
- if (pc.getReceivers) {
1783
- pc.getReceivers().forEach((receiver) => {
1784
- if (allTracks || receiver.track.kind === 'video') {
1785
- remoteStream.addTrack(receiver.track);
1786
- }
1787
- });
1788
- }
1789
- }
1790
-
1791
- getMediaConfiguration(enableVideo: boolean, conference = false, constraints: Record<string, any> | null | undefined = null): Record<string, any> {
1792
- const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
1793
- const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
1794
- const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
1795
- const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
1796
- logger.info('Retrieving media a configuration', {
1797
- enableVideo,
1798
- screenSharing,
1799
- isDesktop,
1800
- withAudio,
1801
- constraints,
1802
- });
1803
- return {
1804
- constraints: {
1805
- // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
1806
- audio: screenSharing ? !isDesktop : withAudio ? this._getAudioConstraints() : false,
1807
- video: screenSharing ? isDesktop ? {
1808
- mandatory: {
1809
- chromeMediaSource: 'desktop',
1810
- ...(mandatoryVideo || {}),
1811
- },
1812
- } : {
1813
- cursor: 'always',
1814
- } : this._getVideoConstraints(enableVideo),
1815
- screen: screenSharing,
1816
- desktop: isDesktop,
1817
- conference,
1818
- },
1819
- enableVideo,
1820
- conference,
1821
- offerOptions: {
1822
- OfferToReceiveAudio: this._hasAudio(),
1823
- OfferToReceiveVideo: enableVideo,
1824
- mandatory: {
1825
- OfferToReceiveAudio: this._hasAudio(),
1826
- OfferToReceiveVideo: enableVideo,
1827
- },
1828
- },
1829
- };
1830
- }
1831
-
1832
- isConference(sessionId: string): boolean {
1833
- return sessionId in this.conferences;
1834
- }
1835
-
1836
- async createAudioElementFor(sessionId: string): Promise<HTMLAudioElement> {
1837
- const audio: HTMLAudioElement = document.createElement('audio');
1838
- audio.setAttribute('id', `audio-${sessionId}`);
1839
-
1840
- logger.info('creating audio element', { sessionId, audioOutputDeviceId: this.audioOutputDeviceId });
1841
-
1842
- if (this.audioOutputDeviceId) {
1843
- await audio.setSinkId(this.audioOutputDeviceId);
1844
- }
1845
-
1846
- if (document.body) {
1847
- document.body.appendChild(audio);
1848
- }
1849
-
1850
- this.audioElements[sessionId] = audio;
1851
- audio.volume = this.audioOutputVolume;
1852
- audio.autoplay = true;
1853
- return audio;
1854
- }
1855
-
1856
- _onTransportError(): void {
1857
- logger.error('on transport error');
1858
- this.eventEmitter.emit(TRANSPORT_ERROR);
1859
- this.attemptReconnection();
1860
- }
1861
-
1862
- enableLogger(logConnector: (level: any, className: string, label: any, content: string) => void): void {
1863
- if (!this.userAgent) {
1864
- return;
1865
- }
1866
-
1867
- if (this.userAgent?.transport) {
1868
- (this.userAgent.transport as WazoTransport).configuration.traceSip = true;
1869
- }
1870
-
1871
- // @ts-ignore: private
1872
- this.userAgent.loggerFactory.builtinEnabled = true;
1873
- // @ts-ignore: private
1874
- this.userAgent.loggerFactory.level = 3; // debug
1875
- // @ts-ignore: private
1876
- this.userAgent.loggerFactory.connector = logConnector;
1877
- }
1878
-
1879
- _onHeartbeat(message: string | Record<string, any>): void {
1880
- const body = message && typeof message === 'object' ? message.data : message;
1881
-
1882
- if (body && body.indexOf('200 OK') !== -1) {
1883
- if (this.hasHeartbeat()) {
1884
- logger.info('on heartbeat received from Asterisk', {
1885
- hasHeartbeat: this.hasHeartbeat(),
1886
- });
1887
- this.heartbeat.onHeartbeat();
1888
-
1889
- if (this.heartbeatCb) {
1890
- this.heartbeatCb();
1891
- }
1892
- }
1893
- }
1894
- }
1895
-
1896
- async _onHeartbeatTimeout(): Promise<void> {
1897
- logger.warn('sdk webrtc heartbeat timed out', {
1898
- userAgent: !!this.userAgent,
1899
- cb: !!this.heartbeatTimeoutCb,
1900
- });
1901
-
1902
- if (this.heartbeatTimeoutCb) {
1903
- this.heartbeatTimeoutCb();
1904
- }
1905
-
1906
- if (this.userAgent && this.userAgent.transport) {
1907
- // Disconnect from WS and triggers events, but do not trigger disconnect if already disconnecting...
1908
- const transport = this.userAgent.transport as WazoTransport;
1909
- // @HEADS UP
1910
- if (!transport.transitioningState && !transport.disconnectPromise) {
1911
- try {
1912
- await this.userAgent.transport.disconnect();
1913
- } catch (e: any) {
1914
- logger.error('Transport disconnection after heartbeat timeout, error', e);
1915
- }
1916
- }
1917
-
1918
- // We can invoke disconnect() with an error that can be catcher by `onDisconnect`, so we have to trigger it here.
1919
- this._onTransportError();
1920
- }
1921
- }
1922
-
1923
- _isWeb(): boolean {
1924
- return typeof window === 'object' && typeof document === 'object';
1925
- }
1926
-
1927
- _isVideoTrack(track: MediaStreamTrack): boolean {
1928
- return track.kind === 'video' && track.readyState === 'live';
1929
- }
1930
-
1931
- _hasAudio(): boolean {
1932
- return this.hasAudio;
1933
- }
1934
-
1935
- _getAudioConstraints(): MediaTrackConstraints | boolean {
1936
- // @ts-ignore: media constraints
1937
- return this.audio?.deviceId?.exact ? this.audio : true;
1938
- }
1939
-
1940
- _getVideoConstraints(video = false): MediaTrackConstraints | boolean {
1941
- if (!video) {
1942
- return false;
1943
- }
1944
-
1945
- // @ts-ignore: media constraints
1946
- return this.video?.deviceId?.exact ? this.video : true;
1947
- }
1948
-
1949
- _connectIfNeeded(): Promise<any> {
1950
- logger.info('connect if needed, checking', { connected: this.isConnected(), clientId: this.clientId });
1951
-
1952
- if (!this.userAgent) {
1953
- logger.info('need to recreate User Agent');
1954
- this.userAgent = this.createUserAgent(this.uaConfigOverrides);
1955
- }
1956
-
1957
- if (this.isConnected()) {
1958
- logger.info('webrtc sdk, already connected');
1959
- return Promise.resolve();
1960
- }
1961
-
1962
- if (this.isConnecting()) {
1963
- logger.info('webrtc sdk, already connecting...');
1964
- this.connectionPromise = (this.userAgent.transport as WazoTransport).connectPromise;
1965
- return Promise.resolve(this.connectionPromise);
1966
- }
1967
-
1968
- if (this.connectionPromise) {
1969
- logger.info('webrtc sdk, connection promise connecting...');
1970
- return this.connectionPromise;
1971
- }
1972
-
1973
- logger.info('WebRTC UA needs to connect');
1974
-
1975
- // Force UA to reconnect
1976
- if (this.userAgent && this.userAgent.state !== UserAgentState.Stopped) {
1977
- // @ts-ignore: private
1978
- this.userAgent.transitionState(UserAgentState.Stopped);
1979
- }
1980
-
1981
- if (this.userAgent.transport && this.userAgent.transport.state !== TransportState.Disconnected) {
1982
- (this.userAgent.transport as WazoTransport).transitionState(TransportState.Disconnected);
1983
- }
1984
-
1985
- this.connectionPromise = this.userAgent.start().catch(console.error);
1986
- return this.connectionPromise;
1987
- }
1988
-
1989
- _buildConfig(config: WebRtcConfig, session: WazoSession | null | undefined): Promise<WebRtcConfig> {
1990
- // If no session provided, return the configuration directly
1991
- if (!session) {
1992
- return new Promise(resolve => resolve(config));
1993
- }
1994
-
1995
- const client = new ApiClient({
1996
- server: `${config.host}:${String(config.port || 443)}`,
1997
- });
1998
- client.setToken((session as any).token);
1999
- client.setRefreshToken((session as any).refreshToken);
2000
-
2001
- return client.confd.getUserLineSipFromToken((session as any).uuid).then(sipLine => ({
2002
- authorizationUser: sipLine.username,
2003
- password: sipLine.secret,
2004
- uri: `${sipLine.username}@${config.host}`,
2005
- ...config,
2006
- }));
2007
- }
2008
-
2009
- _createUaOptions(uaOptionsOverrides: UserAgentConfigOverrides = {}): UserAgentOptions {
2010
- let {
2011
- host,
2012
- } = this.config;
2013
- let port: number | string = this.config.port || 443;
2014
-
2015
- if (this.config.websocketSip) {
2016
- const webSocketSip = this.config.websocketSip.split(':');
2017
- [host] = webSocketSip;
2018
- port = Number(webSocketSip[1]);
2019
- }
2020
- const { userUuid } = this.config;
2021
-
2022
- const uaOptions: UserAgentOptions = {
2023
- noAnswerTimeout: NO_ANSWER_TIMEOUT,
2024
- authorizationUsername: this.config.authorizationUser,
2025
- authorizationPassword: this.config.password,
2026
- displayName: this.config.displayName,
2027
- hackIpInContact: true,
2028
- logBuiltinEnabled: this.config.log ? this.config.log.builtinEnabled : null,
2029
- logLevel: this.config.log ? this.config.log.logLevel : null,
2030
- logConnector: this.config.log ? this.config.log.connector : null,
2031
- uri: this._makeURI(this.config.authorizationUser || ''),
2032
- userAgentString: this.config.userAgentString || 'wazo-sdk',
2033
- reconnectionAttempts: 10000,
2034
- reconnectionDelay: 5,
2035
-
2036
- sessionDescriptionHandlerFactory: (session: Session, options: SessionDescriptionHandlerFactoryOptions = {}) => {
2037
- const uaLogger = session.userAgent.getLogger('sip.WazoSessionDescriptionHandler');
2038
-
2039
- const isWeb = this._isWeb();
2040
-
2041
- const iceGatheringTimeout = 'peerConnectionOptions' in options ? (options.peerConnectionOptions as any).iceGatheringTimeout || DEFAULT_ICE_TIMEOUT : DEFAULT_ICE_TIMEOUT;
2042
- const sdhOptions: SessionDescriptionHandlerConfiguration = { ...options,
2043
- iceGatheringTimeout,
2044
- peerConnectionConfiguration: { ...defaultPeerConnectionConfiguration(),
2045
- ...(options.peerConnectionConfiguration || {}),
2046
- },
2047
- };
2048
- return new WazoSessionDescriptionHandler(uaLogger, wazoMediaStreamFactory, sdhOptions, isWeb, session as WazoSession);
2049
- },
2050
- transportOptions: {
2051
- traceSip: uaOptionsOverrides?.traceSip || false,
2052
- wsServers: `wss://${host}:${port}/api/asterisk/ws${userUuid ? `?userUuid=${userUuid}` : ''}`,
2053
- },
2054
- sessionDescriptionHandlerFactoryOptions: {
2055
- modifiers: [replaceLocalIpModifier],
2056
- alwaysAcquireMediaFirst: this.isFirefox(),
2057
- constraints: {
2058
- audio: this._getAudioConstraints(),
2059
- video: this._getVideoConstraints(),
2060
- },
2061
- peerConnectionOptions: {
2062
- iceCheckingTimeout: this.config.iceCheckingTimeout || 1000,
2063
- iceGatheringTimeout: this.config.iceCheckingTimeout || 1000,
2064
- rtcConfiguration: {
2065
- rtcpMuxPolicy: 'require',
2066
- iceServers: WebRTCClient.getIceServers(this.config.host),
2067
- ...this._getRtcOptions(),
2068
- ...(uaOptionsOverrides?.peerConnectionOptions || {}),
2069
- },
2070
- },
2071
- // Configuration used in SDH to create the PeerConnection
2072
- peerConnectionConfiguration: {
2073
- rtcpMuxPolicy: 'require',
2074
- iceServers: WebRTCClient.getIceServers(this.config.host),
2075
- ...(uaOptionsOverrides?.peerConnectionOptions || {}),
2076
- },
2077
- },
2078
- };
2079
-
2080
- delete uaOptionsOverrides?.traceSip;
2081
-
2082
- return {
2083
- ...uaOptions,
2084
- ...uaOptionsOverrides,
2085
- };
2086
- }
2087
-
2088
- // eslint-disable-next-line no-unused-vars
2089
- _getRtcOptions() {
2090
- return {
2091
- mandatory: {
2092
- OfferToReceiveAudio: this._hasAudio(),
2093
- OfferToReceiveVideo: false,
2094
- },
2095
- };
2096
- }
2097
-
2098
- // Invitation and Inviter extends Session
2099
- _setupSession(session: WazoSession): void {
2100
- const sipSessionId = this.getSipSessionId(session);
2101
-
2102
- // When receiving an Invitation, the delegate is not defined.
2103
- if (!session.delegate) {
2104
- session.delegate = {};
2105
- }
2106
-
2107
- session.delegate.onSessionDescriptionHandler = (sdh: SessionDescriptionHandler & { on: (type: string, e: any) => void }) => {
2108
- sdh.on('error', (e: any) => {
2109
- this.eventEmitter.emit(ON_ERROR, e);
2110
- });
2111
- sdh.peerConnectionDelegate = {
2112
- onicecandidateerror: (error: Record<string, any>) => {
2113
- logger.error('on icecandidate error', {
2114
- address: error.address,
2115
- port: error.port,
2116
- errorCode: error.errorCode,
2117
- errorText: error.errorText,
2118
- url: error.url,
2119
- });
2120
- },
2121
- };
2122
- };
2123
-
2124
- // @ts-ignore: protected
2125
- const oldInviteRequest = session.onInviteRequest.bind(session);
2126
- let hadRemoteVideo = false;
2127
-
2128
- // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
2129
- // Because when `onInvite` is called we already got the video track
2130
- // @ts-ignore: protected
2131
- session.onInviteRequest = request => {
2132
- hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
2133
- oldInviteRequest(request);
2134
- };
2135
-
2136
- session.delegate.onInvite = async (request: IncomingRequestMessage) => {
2137
- let updatedCalleeName: string | null = null;
2138
- let updatedNumber = null;
2139
-
2140
- if (session.assertedIdentity) {
2141
- // @ts-ignore: private
2142
- updatedNumber = session.assertedIdentity.uri.normal.user;
2143
- updatedCalleeName = session.assertedIdentity.displayName || updatedNumber;
2144
- }
2145
-
2146
- logger.info('re-invite received', {
2147
- updatedCalleeName,
2148
- updatedNumber,
2149
- hadRemoteVideo,
2150
- });
2151
-
2152
- // Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
2153
- // Update SDP
2154
- // Remote video is handled by the `track` event. Here we're dealing with video stream removal.
2155
- if (session instanceof Invitation) {
2156
- // @ts-ignore: private
2157
- session.incomingInviteRequest.message.body = request.body;
2158
- // @ts-ignore: private
2159
- } else if (session instanceof Inviter && session.outgoingInviteRequest.message.body) {
2160
- // @ts-ignore: private
2161
- session.outgoingInviteRequest.message.body.body = request.body;
2162
- }
2163
-
2164
- this.updateRemoteStream(sipSessionId, false);
2165
-
2166
- await this._setupMedias(session);
2167
-
2168
- return this.eventEmitter.emit(ON_REINVITE, session, request, updatedCalleeName, updatedNumber, hadRemoteVideo);
2169
- };
2170
- }
2171
-
2172
- async _onProgress(session: WazoSession, early = false): Promise<void> {
2173
- await this._setupMedias(session);
2174
-
2175
- const sessionId = this.getSipSessionId(session);
2176
- this.updateRemoteStream(sessionId);
2177
- logger.info('progress received', {
2178
- sessionId,
2179
- early,
2180
- });
2181
- this.eventEmitter.emit(early ? ON_EARLY_MEDIA : ON_PROGRESS, session);
2182
- }
2183
-
2184
- async _onAccepted(session: WazoSession, sessionDialog?: SessionDialog, withEvent = true, initAllTracks = true): Promise<void> {
2185
- logger.info('on call accepted', {
2186
- id: this.getSipSessionId(session),
2187
- clientId: this.clientId,
2188
- remoteTag: session.remoteTag,
2189
- });
2190
- this.storeSipSession(session);
2191
-
2192
- await this._setupMedias(session);
2193
-
2194
- this.updateRemoteStream(this.getSipSessionId(session), initAllTracks);
2195
- const pc = (session.sessionDescriptionHandler as SessionDescriptionHandler)?.peerConnection;
2196
-
2197
- const onTrack = (event: RTCTrackEvent | MediaStreamTrackEvent) => {
2198
- const isAudioOnly = this._isAudioOnly(session);
2199
-
2200
- const {
2201
- kind,
2202
- label,
2203
- readyState,
2204
- id,
2205
- muted,
2206
- } = event.track;
2207
- logger.info('on track event', {
2208
- isAudioOnly,
2209
- kind,
2210
- label,
2211
- readyState,
2212
- id,
2213
- muted,
2214
- });
2215
-
2216
- // Stop video track in audio only mode
2217
- if (isAudioOnly && kind === 'video') {
2218
- event.track.stop();
2219
- }
2220
-
2221
- this.eventEmitter.emit(ON_TRACK, session, event);
2222
- };
2223
-
2224
- const sessionDescriptionHandler = session.sessionDescriptionHandler as SessionDescriptionHandler;
2225
- if (sessionDescriptionHandler?.peerConnection) {
2226
- sessionDescriptionHandler.peerConnection.addEventListener('track', onTrack);
2227
- }
2228
-
2229
- sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
2230
-
2231
- if (pc) {
2232
- pc.oniceconnectionstatechange = () => {
2233
- logger.info('on ice connection state changed', {
2234
- state: pc.iceConnectionState,
2235
- });
2236
-
2237
- if (pc.iceConnectionState === 'disconnected') {
2238
- this.eventEmitter.emit(ON_DISCONNECTED);
2239
- }
2240
- };
2241
- }
2242
-
2243
- if (withEvent) {
2244
- this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
2245
- }
2246
-
2247
- this._startSendingStats(session);
2248
- }
2249
-
2250
- _isAudioOnly(session: WazoSession): boolean {
2251
- return Boolean(session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === stripVideo));
2252
- }
2253
-
2254
- async _setupMedias(session: WazoSession, newStream: MediaStream | null | undefined = null): Promise<void> {
2255
- if (!this._isWeb()) {
2256
- logger.info('Setup media on mobile, no need to setup html element, bailing');
2257
- return;
2258
- }
2259
-
2260
- // Safari hack, because you cannot call .play() from a non user action
2261
- const sessionId = this.getSipSessionId(session);
2262
- const isConference = this.isConference(sessionId);
2263
-
2264
- if (sessionId in this.audioElements) {
2265
- logger.info('html element already exists for session', {
2266
- sessionId,
2267
- });
2268
- return;
2269
- }
2270
-
2271
- if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
2272
- await this.createAudioElementFor(sessionId);
2273
- }
2274
-
2275
- const audioElement = this.audioElements[sessionId];
2276
- const sipSession = this.sipSessions[session.callId as string];
2277
- const removeStream = this.getRemoteStream(sessionId);
2278
- const sdh = sipSession?.sessionDescriptionHandler as SessionDescriptionHandler;
2279
- const earlyStream = sdh ? sdh.remoteMediaStream : null;
2280
- const stream = newStream || removeStream || earlyStream;
2281
-
2282
- if (!stream) {
2283
- logger.info('Setup media no stream to attach, bailing');
2284
- return;
2285
- }
2286
-
2287
- const shouldPause = audioElement.currentTime > 0 && !audioElement.paused && !audioElement.ended && audioElement.readyState > 2;
2288
-
2289
- logger.info('setting up media', {
2290
- sessionId,
2291
- streams: {
2292
- new: !!newStream,
2293
- remove: !!removeStream,
2294
- early: !!earlyStream,
2295
- },
2296
- hasAudio: this._hasAudio(),
2297
- isConference,
2298
- shouldPause,
2299
- });
2300
-
2301
- if (isConference) {
2302
- // Conference local stream is handled in Room
2303
- return;
2304
- }
2305
-
2306
- if (shouldPause) {
2307
- audioElement.pause();
2308
- }
2309
-
2310
- audioElement.srcObject = stream;
2311
- audioElement.volume = this.audioOutputVolume;
2312
- audioElement.play().catch(() => {});
2313
- }
2314
-
2315
- _cleanupMedia(session?: WazoSession): void {
2316
- const sessionId = this.getSipSessionId(session);
2317
- const localStream = this.getLocalStream(sessionId);
2318
-
2319
- if (localStream) {
2320
- this._cleanupStream(localStream);
2321
- }
2322
-
2323
- const cleanLocalElement = (id: string) => {
2324
- const element = this.audioElements[id];
2325
-
2326
- if (!element) {
2327
- return;
2328
- }
2329
-
2330
- element.pause();
2331
-
2332
- if (element.parentNode) {
2333
- element.parentNode.removeChild(element);
2334
- }
2335
-
2336
- element.srcObject = null;
2337
- delete this.audioElements[id];
2338
- };
2339
-
2340
- if (this._hasAudio() && this._isWeb()) {
2341
- if (session) {
2342
- cleanLocalElement(this.getSipSessionId(session));
2343
- } else {
2344
- Object.keys(this.audioElements).forEach(id => cleanLocalElement(id));
2345
- }
2346
- }
2347
- }
2348
-
2349
- _cleanupStream(stream: MediaStream): void {
2350
- stream.getTracks().filter(track => track.enabled).forEach(track => track.stop());
2351
- }
2352
-
2353
- _toggleAudio(session: WazoSession, muteAudio: boolean): void {
2354
- const sdh = session.sessionDescriptionHandler as SessionDescriptionHandler;
2355
- const pc = (sdh?.peerConnection || null) as PeerConnection;
2356
-
2357
- if (!pc) {
2358
- return;
2359
- }
2360
-
2361
- if (pc.getSenders) {
2362
- pc.getSenders().forEach((sender) => {
2363
- if (sender && sender.track && sender.track.kind === 'audio') {
2364
- // eslint-disable-next-line
2365
- sender.track.enabled = !muteAudio;
2366
- }
2367
- });
2368
- } else {
2369
- pc.getLocalStreams().forEach((stream: MediaStream) => {
2370
- stream.getAudioTracks().forEach(track => {
2371
- // eslint-disable-next-line
2372
- track.enabled = !muteAudio;
2373
- });
2374
- });
2375
- }
2376
- }
2377
-
2378
- _toggleVideo(session: WazoSession, muteCamera: boolean): void {
2379
- const sdh = session.sessionDescriptionHandler as SessionDescriptionHandler;
2380
- const pc = sdh?.peerConnection as PeerConnection;
2381
-
2382
- if (pc?.getSenders) {
2383
- pc.getSenders().forEach((sender) => {
2384
- if (sender && sender.track && sender.track.kind === 'video') {
2385
- // eslint-disable-next-line
2386
- sender.track.enabled = !muteCamera;
2387
- }
2388
- });
2389
- } else {
2390
- pc.getLocalStreams().forEach((stream: MediaStream) => {
2391
- stream.getVideoTracks().forEach(track => {
2392
- // eslint-disable-next-line
2393
- track.enabled = !muteCamera;
2394
- });
2395
- });
2396
- }
2397
- }
2398
-
2399
- /**
2400
- * @param pc RTCPeerConnection
2401
- */
2402
- _getRemoteStream(pc: PeerConnection): MediaStream | null {
2403
- let remoteStream: MediaStream | null = null;
2404
-
2405
- if (pc && pc.getReceivers) {
2406
- remoteStream = typeof global !== 'undefined' && global.window && global.window.MediaStream ? new global.window.MediaStream() : new window.MediaStream();
2407
-
2408
- pc.getReceivers().forEach((receiver) => {
2409
- const {
2410
- track,
2411
- } = receiver;
2412
-
2413
- if (track && remoteStream) {
2414
- remoteStream.addTrack(track);
2415
- }
2416
- });
2417
- } else if (pc) {
2418
- [remoteStream] = pc.getRemoteStreams();
2419
- }
2420
-
2421
- return remoteStream;
2422
- }
2423
-
2424
- _cleanupRegister(): void {
2425
- if (this.registerer) {
2426
- // @ts-ignore: removeAllListeners does not exist
2427
- this.registerer.stateChange.removeAllListeners();
2428
- this.registerer = null;
2429
- }
2430
- }
2431
-
2432
- _startSendingStats(session: WazoSession): void {
2433
- const sdh = session.sessionDescriptionHandler as SessionDescriptionHandler;
2434
- const pc = sdh.peerConnection;
2435
-
2436
- if (!pc) {
2437
- return;
2438
- }
2439
-
2440
- const sessionId = this.getSipSessionId(session);
2441
- getStats(pc, (result: Record<string, any>) => {
2442
- const {
2443
- results,
2444
- internal,
2445
- nomore,
2446
- ...stats
2447
- } = result;
2448
- this.statsIntervals[sessionId] = nomore;
2449
- statsLogger.trace('stats', {
2450
- sessionId,
2451
- ...stats,
2452
- });
2453
- }, SEND_STATS_DELAY);
2454
- }
2455
-
2456
- _stopSendingStats(session: WazoSession): void {
2457
- const sessionId = this.getSipSessionId(session);
2458
- logger.trace('Check for stopping stats', {
2459
- sessionId,
2460
- ids: Object.keys(this.statsIntervals),
2461
- });
2462
-
2463
- if (sessionId in this.statsIntervals) {
2464
- logger.trace('Stop sending stats for call', {
2465
- sessionId,
2466
- });
2467
- this.statsIntervals[sessionId]();
2468
- delete this.statsIntervals[sessionId];
2469
- }
2470
- }
2471
-
2472
- _makeURI(target: string): URI | undefined {
2473
- return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
2474
- }
2475
-
2476
- async _disconnectTransport(force = false) {
2477
- const transport = this.userAgent?.transport as WazoTransport;
2478
-
2479
- if (force && transport) {
2480
- // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
2481
- transport.disconnectResolve = () => {};
2482
-
2483
- if (transport._ws) {
2484
- transport._ws.close(1000);
2485
- }
2486
-
2487
- return;
2488
- }
2489
-
2490
- // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
2491
- if (transport && !transport.disconnectPromise) {
2492
- try {
2493
- await transport.disconnect();
2494
- } catch (e: any) {
2495
- logger.error('WebRTC transport disconnect, error', e);
2496
- }
2497
- }
2498
- }
2499
-
2500
- async _fetchNetworkStats(sessionId: string): Promise<Record<string, any> | null | undefined> {
2501
- const session = this.getSipSession(sessionId);
2502
- const stats = session ? await this.getStats(session) : null;
2503
-
2504
- if (!stats || !(sessionId in this.sessionNetworkStats)) {
2505
- return Promise.resolve(null);
2506
- }
2507
-
2508
- const networkStats: Record<string, any> = {
2509
- audioBytesSent: 0,
2510
- videoBytesSent: 0,
2511
- videoBytesReceived: 0,
2512
- audioBytesReceived: 0,
2513
- };
2514
- const nbStats = this.sessionNetworkStats[sessionId].length;
2515
- const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
2516
- const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
2517
- const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
2518
- const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
2519
- const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
2520
- const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
2521
- const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
2522
- const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
2523
- const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
2524
- let audioBytesSent = 0; // content + header
2525
-
2526
- let audioBytesReceived = 0; // content + header
2527
-
2528
- let audioContentSent = 0; // useful to detect blank call
2529
-
2530
- let audioContentReceived = 0;
2531
- let videoBytesSent = 0;
2532
- let videoBytesReceived = 0;
2533
- let transportSent = 0;
2534
- let transportReceived = 0;
2535
- let packetsLost = 0;
2536
- stats.forEach(report => {
2537
- if (report.type === 'outbound-rtp' && report.kind === 'audio') {
2538
- audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
2539
- audioContentSent += Number(report.bytesSent);
2540
- }
2541
-
2542
- if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
2543
- audioBytesSent += Number(report.bytesSent);
2544
- }
2545
-
2546
- if (report.type === 'outbound-rtp' && report.kind === 'video') {
2547
- videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
2548
- }
2549
-
2550
- if (report.type === 'inbound-rtp' && report.kind === 'audio') {
2551
- packetsLost += Number(report.packetsLost);
2552
- networkStats.packetsReceived = Number(report.packetsReceived);
2553
- audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
2554
- audioContentReceived += Number(report.bytesReceived);
2555
- }
2556
-
2557
- if (report.type === 'inbound-rtp' && report.kind === 'video') {
2558
- videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
2559
- }
2560
-
2561
- if (report.type === 'outbound-rtp' && report.kind === 'video') {
2562
- if ('framesPerSecond' in report) {
2563
- networkStats.framesPerSecond = Number(report.framesPerSecond);
2564
- }
2565
-
2566
- if ('framerateMean' in report) {
2567
- // framerateMean is only available in FF
2568
- networkStats.framesPerSecond = Math.round(report.framerateMean);
2569
- }
2570
- }
2571
-
2572
- if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
2573
- packetsLost += Number(report.packetsLost);
2574
- networkStats.roundTripTime = Number(report.roundTripTime);
2575
- networkStats.jitter = Number(report.jitter);
2576
- }
2577
-
2578
- if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
2579
- packetsLost += Number(report.packetsLost);
2580
- }
2581
-
2582
- if (report.type === 'transport') {
2583
- transportSent += Number(report.bytesSent);
2584
- transportReceived += Number(report.bytesReceived);
2585
- }
2586
- });
2587
- networkStats.packetsLost = packetsLost;
2588
- networkStats.totalAudioBytesSent = audioBytesSent;
2589
- networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
2590
- networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
2591
- networkStats.audioBytesReceived = audioBytesReceived;
2592
- networkStats.totalAudioContentSent = audioContentSent;
2593
- networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
2594
- networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
2595
- networkStats.audioContentReceived = audioContentReceived;
2596
- networkStats.totalVideoBytesSent = videoBytesSent;
2597
- networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
2598
- networkStats.totalVideoBytesReceived = videoBytesReceived;
2599
- networkStats.videoBytesReceived = videoBytesReceived - lastVideoReceived;
2600
- networkStats.totalTransportSent = transportSent - lastTransportSent;
2601
- networkStats.transportSent = transportSent;
2602
- networkStats.totalTransportReceived = transportReceived;
2603
- networkStats.transportReceived = transportReceived - lastTransportReceived;
2604
- networkStats.bandwidth = networkStats.audioBytesSent + networkStats.audioBytesReceived + networkStats.videoBytesSent + networkStats.videoBytesReceived + networkStats.transportReceived + networkStats.transportSent;
2605
-
2606
- if (this.sessionNetworkStats[sessionId]) {
2607
- this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
2608
- if (sessionId in this.sessionNetworkStats) {
2609
- this.sessionNetworkStats[sessionId].push(networkStats);
2610
- }
2611
- }
2612
- }
2613
-
2614
- async _accept(session: Invitation, options: InvitationAcceptOptions = {}) {
2615
- if (session.state === SessionState.Terminated || session.state === SessionState.Terminating) {
2616
- const error = 'Trying to accept a terminated sipSession.';
2617
- logger.warn(error, { state: session.state, sessionId: this.getSipSessionId(session) });
2618
- throw new Error(error);
2619
- }
2620
-
2621
- if (session.state !== SessionState.Initial) {
2622
- const error = 'Trying to accept a non Initial sipSession.';
2623
- logger.warn(error, { state: session.state, sessionId: this.getSipSessionId(session) });
2624
- throw new Error(error);
2625
- }
2626
-
2627
- // @ts-ignore: private
2628
- if (!session.incomingInviteRequest.acceptable) {
2629
- const error = 'Trying to reject a non `acceptable` session';
2630
- logger.warn(error, { state: session.state, sessionId: this.getSipSessionId(session) });
2631
- throw new Error(error);
2632
- }
2633
-
2634
- try {
2635
- return await session.accept(options);
2636
- } catch (e) {
2637
- logger.warn('Session accept, error', e);
2638
- }
2639
- }
2640
-
2641
- async _reject(session: Invitation, options: InvitationRejectOptions = {}) {
2642
- if (session.state !== SessionState.Initial && session.state !== SessionState.Establishing) {
2643
- logger.warn('Trying to reject a session in a wrong state', { state: session.state, sessionId: this.getSipSessionId(session) });
2644
- return;
2645
- }
2646
-
2647
- // @ts-ignore: private
2648
- if (!session.incomingInviteRequest.rejectable) {
2649
- logger.warn('Trying to reject a non `rejectable` session', { state: session.state, sessionId: this.getSipSessionId(session) });
2650
- return;
2651
- }
2652
-
2653
- try {
2654
- return await session.reject(options);
2655
- } catch (e) {
2656
- logger.warn('Session reject, error', e);
2657
- }
2658
- }
2659
-
2660
- async _cancel(session: Inviter, options: InviterCancelOptions = {}) {
2661
- if (session.state !== SessionState.Initial && session.state !== SessionState.Establishing) {
2662
- logger.warn('Trying to cancel a session in a wrong state', { state: session.state, sessionId: this.getSipSessionId(session) });
2663
- return;
2664
- }
2665
-
2666
- try {
2667
- return await session.cancel(options);
2668
- } catch (e) {
2669
- logger.warn('Session cancel, error', e);
2670
- }
2671
- }
2672
-
2673
- async _bye(session: WazoSession, options: SessionByeOptions = {}) {
2674
- if (session.state !== SessionState.Established) {
2675
- logger.warn('Trying to end a session in a wrong state', { state: session.state, sessionId: this.getSipSessionId(session) });
2676
- return null;
2677
- }
2678
-
2679
- try {
2680
- return await session.bye(options);
2681
- } catch (e) {
2682
- logger.warn('Session bye, error', e);
2683
- }
2684
-
2685
- return null;
2686
- }
2687
- }