ue-softphone-sdk 2.2.3 → 2.2.4
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.
- package/dist/api/bye.d.ts +16 -0
- package/dist/api/dtmf.d.ts +15 -0
- package/dist/api/emitter.d.ts +88 -0
- package/dist/api/exceptions/content-type-unsupported.d.ts +8 -0
- package/dist/api/exceptions/index.d.ts +5 -0
- package/dist/api/exceptions/request-pending.d.ts +9 -0
- package/dist/api/exceptions/session-description-handler.d.ts +8 -0
- package/dist/api/exceptions/session-terminated.d.ts +8 -0
- package/dist/api/exceptions/state-transition.d.ts +8 -0
- package/dist/api/index.d.ts +58 -0
- package/dist/api/info.d.ts +16 -0
- package/dist/api/invitation-accept-options.d.ts +19 -0
- package/dist/api/invitation-progress-options.d.ts +38 -0
- package/dist/api/invitation-reject-options.d.ts +25 -0
- package/dist/api/invitation.d.ts +179 -0
- package/dist/api/inviter-cancel-options.d.ts +9 -0
- package/dist/api/inviter-invite-options.d.ts +28 -0
- package/dist/api/inviter-options.d.ts +43 -0
- package/dist/api/inviter.d.ts +236 -0
- package/dist/api/message.d.ts +16 -0
- package/dist/api/messager-message-options.d.ts +11 -0
- package/dist/api/messager-options.d.ts +17 -0
- package/dist/api/messager.d.ts +26 -0
- package/dist/api/notification.d.ts +16 -0
- package/dist/api/notifier.d.ts +8 -0
- package/dist/api/publisher-options.d.ts +33 -0
- package/dist/api/publisher-publish-options.d.ts +6 -0
- package/dist/api/publisher-state.d.ts +21 -0
- package/dist/api/publisher-unpublish-options.d.ts +6 -0
- package/dist/api/publisher.d.ts +65 -0
- package/dist/api/referral.d.ts +38 -0
- package/dist/api/registerer-options.d.ts +46 -0
- package/dist/api/registerer-register-options.d.ts +11 -0
- package/dist/api/registerer-state.d.ts +21 -0
- package/dist/api/registerer-unregister-options.d.ts +16 -0
- package/dist/api/registerer.d.ts +144 -0
- package/dist/api/session-bye-options.d.ts +11 -0
- package/dist/api/session-delegate.d.ts +73 -0
- package/dist/api/session-description-handler-factory.d.ts +15 -0
- package/dist/api/session-description-handler.d.ts +74 -0
- package/dist/api/session-info-options.d.ts +11 -0
- package/dist/api/session-invite-options.d.ts +28 -0
- package/dist/api/session-message-options.d.ts +11 -0
- package/dist/api/session-options.d.ts +8 -0
- package/dist/api/session-refer-options.d.ts +14 -0
- package/dist/api/session-state.d.ts +45 -0
- package/dist/api/session.d.ts +359 -0
- package/dist/api/subscriber-options.d.ts +11 -0
- package/dist/api/subscriber-subscribe-options.d.ts +6 -0
- package/dist/api/subscriber.d.ts +94 -0
- package/dist/api/subscription-delegate.d.ts +12 -0
- package/dist/api/subscription-options.d.ts +8 -0
- package/dist/api/subscription-state.d.ts +19 -0
- package/dist/api/subscription-subscribe-options.d.ts +6 -0
- package/dist/api/subscription-unsubscribe-options.d.ts +6 -0
- package/dist/api/subscription.d.ts +84 -0
- package/dist/api/transport-state.d.ts +37 -0
- package/dist/api/transport.d.ts +159 -0
- package/dist/api/user-agent-delegate.d.ts +84 -0
- package/dist/api/user-agent-options.d.ts +253 -0
- package/dist/api/user-agent-state.d.ts +14 -0
- package/dist/api/user-agent.d.ts +200 -0
- package/dist/core/dialogs/dialog-state.d.ts +34 -0
- package/dist/core/dialogs/dialog.d.ts +161 -0
- package/dist/core/dialogs/index.d.ts +4 -0
- package/dist/core/dialogs/session-dialog.d.ts +196 -0
- package/dist/core/dialogs/subscription-dialog.d.ts +120 -0
- package/dist/core/exceptions/exception.d.ts +8 -0
- package/dist/core/exceptions/index.d.ts +3 -0
- package/dist/core/exceptions/transaction-state-error.d.ts +8 -0
- package/dist/core/exceptions/transport-error.d.ts +8 -0
- package/dist/core/index.d.ts +15 -0
- package/dist/core/log/index.d.ts +3 -0
- package/dist/core/log/levels.d.ts +10 -0
- package/dist/core/log/logger-factory.d.ts +21 -0
- package/dist/core/log/logger.d.ts +19 -0
- package/dist/core/messages/body.d.ts +64 -0
- package/dist/core/messages/digest-authentication.d.ts +51 -0
- package/dist/core/messages/incoming-message.d.ts +79 -0
- package/dist/core/messages/incoming-request-message.d.ts +10 -0
- package/dist/core/messages/incoming-request.d.ts +67 -0
- package/dist/core/messages/incoming-response-message.d.ts +10 -0
- package/dist/core/messages/incoming-response.d.ts +12 -0
- package/dist/core/messages/index.d.ts +13 -0
- package/dist/core/messages/md5.d.ts +32 -0
- package/dist/core/messages/methods/ack.d.ts +18 -0
- package/dist/core/messages/methods/bye.d.ts +21 -0
- package/dist/core/messages/methods/cancel.d.ts +21 -0
- package/dist/core/messages/methods/constants.d.ts +20 -0
- package/dist/core/messages/methods/index.d.ts +13 -0
- package/dist/core/messages/methods/info.d.ts +21 -0
- package/dist/core/messages/methods/invite.d.ts +86 -0
- package/dist/core/messages/methods/message.d.ts +21 -0
- package/dist/core/messages/methods/notify.d.ts +21 -0
- package/dist/core/messages/methods/prack.d.ts +21 -0
- package/dist/core/messages/methods/publish.d.ts +21 -0
- package/dist/core/messages/methods/refer.d.ts +21 -0
- package/dist/core/messages/methods/register.d.ts +21 -0
- package/dist/core/messages/methods/subscribe.d.ts +54 -0
- package/dist/core/messages/outgoing-request-message.d.ts +94 -0
- package/dist/core/messages/outgoing-request.d.ts +67 -0
- package/dist/core/messages/outgoing-response.d.ts +42 -0
- package/dist/core/messages/parser.d.ts +14 -0
- package/dist/core/messages/utils.d.ts +24 -0
- package/dist/core/session/index.d.ts +2 -0
- package/dist/core/session/session-delegate.d.ts +70 -0
- package/dist/core/session/session.d.ts +134 -0
- package/dist/core/subscription/index.d.ts +2 -0
- package/dist/core/subscription/subscription-delegate.d.ts +27 -0
- package/dist/core/subscription/subscription.d.ts +55 -0
- package/dist/core/timers.d.ts +20 -0
- package/dist/core/transactions/client-transaction.d.ts +45 -0
- package/dist/core/transactions/index.d.ts +10 -0
- package/dist/core/transactions/invite-client-transaction.d.ts +116 -0
- package/dist/core/transactions/invite-server-transaction.d.ts +127 -0
- package/dist/core/transactions/non-invite-client-transaction.d.ts +69 -0
- package/dist/core/transactions/non-invite-server-transaction.d.ts +57 -0
- package/dist/core/transactions/server-transaction.d.ts +35 -0
- package/dist/core/transactions/transaction-state.d.ts +13 -0
- package/dist/core/transactions/transaction-user.d.ts +72 -0
- package/dist/core/transactions/transaction.d.ts +79 -0
- package/dist/core/transport.d.ts +31 -0
- package/dist/core/user-agent-core/allowed-methods.d.ts +4 -0
- package/dist/core/user-agent-core/index.d.ts +3 -0
- package/dist/core/user-agent-core/user-agent-core-configuration.d.ts +99 -0
- package/dist/core/user-agent-core/user-agent-core-delegate.d.ts +37 -0
- package/dist/core/user-agent-core/user-agent-core.d.ts +179 -0
- package/dist/core/user-agents/bye-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/bye-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/cancel-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/index.d.ts +26 -0
- package/dist/core/user-agents/info-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/info-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/invite-user-agent-client.d.ts +35 -0
- package/dist/core/user-agents/invite-user-agent-server.d.ts +77 -0
- package/dist/core/user-agents/message-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/message-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/notify-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/notify-user-agent-server.d.ts +16 -0
- package/dist/core/user-agents/prack-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/prack-user-agent-server.d.ts +16 -0
- package/dist/core/user-agents/publish-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/re-invite-user-agent-client.d.ts +18 -0
- package/dist/core/user-agents/re-invite-user-agent-server.d.ts +41 -0
- package/dist/core/user-agents/re-subscribe-user-agent-client.d.ts +17 -0
- package/dist/core/user-agents/re-subscribe-user-agent-server.d.ts +10 -0
- package/dist/core/user-agents/refer-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/refer-user-agent-server.d.ts +16 -0
- package/dist/core/user-agents/register-user-agent-client.d.ts +10 -0
- package/dist/core/user-agents/register-user-agent-server.d.ts +11 -0
- package/dist/core/user-agents/subscribe-user-agent-client.d.ts +65 -0
- package/dist/core/user-agents/subscribe-user-agent-server.d.ts +11 -0
- package/dist/core/user-agents/user-agent-client.d.ts +103 -0
- package/dist/core/user-agents/user-agent-server.d.ts +79 -0
- package/dist/grammar/grammar.d.ts +26 -0
- package/dist/grammar/index.d.ts +4 -0
- package/dist/grammar/name-addr-header.d.ts +24 -0
- package/dist/grammar/parameters.d.ts +16 -0
- package/dist/grammar/pegjs/dist/grammar.d.ts +50 -0
- package/dist/grammar/uri.d.ts +62 -0
- package/dist/{types/index.d.ts → index.d.ts} +7 -3
- package/dist/main.d.ts +9 -0
- package/dist/new-index.d.ts +199 -0
- package/dist/platform/web/index.d.ts +4 -0
- package/dist/platform/web/modifiers/index.d.ts +5 -0
- package/dist/platform/web/modifiers/modifiers.d.ts +41 -0
- package/dist/platform/web/session-description-handler/index.d.ts +14 -0
- package/dist/platform/web/session-description-handler/media-stream-factory-default.d.ts +6 -0
- package/dist/platform/web/session-description-handler/media-stream-factory.d.ts +6 -0
- package/dist/platform/web/session-description-handler/peer-connection-configuration-default.d.ts +5 -0
- package/dist/platform/web/session-description-handler/peer-connection-delegate.d.ts +63 -0
- package/dist/platform/web/session-description-handler/session-description-handler-configuration.d.ts +16 -0
- package/dist/platform/web/session-description-handler/session-description-handler-factory-default.d.ts +11 -0
- package/dist/platform/web/session-description-handler/session-description-handler-factory-options.d.ts +9 -0
- package/dist/platform/web/session-description-handler/session-description-handler-factory.d.ts +16 -0
- package/dist/platform/web/session-description-handler/session-description-handler-options.d.ts +47 -0
- package/dist/platform/web/session-description-handler/session-description-handler.d.ts +212 -0
- package/dist/platform/web/simple-user/index.d.ts +7 -0
- package/dist/platform/web/simple-user/simple-user-delegate.d.ts +72 -0
- package/dist/platform/web/simple-user/simple-user-options.d.ts +90 -0
- package/dist/platform/web/simple-user/simple-user.d.ts +226 -0
- package/dist/platform/web/transport/index.d.ts +6 -0
- package/dist/platform/web/transport/transport-options.d.ts +30 -0
- package/dist/platform/web/transport/transport.d.ts +125 -0
- package/dist/ue-softphone-sdk.js +2 -1
- package/dist/ue-softphone-sdk.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/webPhoneSdk.d.ts +24 -0
- package/dist/webrtc.d.ts +17 -0
- package/{rollup-new.config.mjs → new-rollup.config.mjs} +1 -1
- package/package.json +6 -6
- package/rollup.config.js +15 -14
- package/src/api/api-extractor.json +358 -0
- package/src/api/bye.ts +27 -0
- package/src/api/dtmf.ts +27 -0
- package/src/api/emitter.ts +110 -0
- package/src/api/exceptions/content-type-unsupported.ts +11 -0
- package/src/api/exceptions/index.ts +5 -0
- package/src/api/exceptions/request-pending.ts +12 -0
- package/src/api/exceptions/session-description-handler.ts +11 -0
- package/src/api/exceptions/session-terminated.ts +11 -0
- package/src/api/exceptions/state-transition.ts +11 -0
- package/src/api/index.ts +58 -0
- package/src/api/info.ts +27 -0
- package/src/api/invitation-accept-options.ts +20 -0
- package/src/api/invitation-progress-options.ts +36 -0
- package/src/api/invitation-reject-options.ts +22 -0
- package/src/api/invitation.ts +816 -0
- package/src/api/inviter-cancel-options.ts +9 -0
- package/src/api/inviter-invite-options.ts +29 -0
- package/src/api/inviter-options.ts +44 -0
- package/src/api/inviter.ts +1126 -0
- package/src/api/message.ts +27 -0
- package/src/api/messager-message-options.ts +12 -0
- package/src/api/messager-options.ts +18 -0
- package/src/api/messager.ts +89 -0
- package/src/api/notification.ts +27 -0
- package/src/api/notifier.ts +7 -0
- package/src/api/publisher-options.ts +34 -0
- package/src/api/publisher-publish-options.ts +6 -0
- package/src/api/publisher-state.ts +21 -0
- package/src/api/publisher-unpublish-options.ts +6 -0
- package/src/api/publisher.ts +418 -0
- package/src/api/referral.ts +89 -0
- package/src/api/registerer-options.ts +55 -0
- package/src/api/registerer-register-options.ts +12 -0
- package/src/api/registerer-state.ts +21 -0
- package/src/api/registerer-unregister-options.ts +17 -0
- package/src/api/registerer.ts +814 -0
- package/src/api/session-bye-options.ts +12 -0
- package/src/api/session-delegate.ts +80 -0
- package/src/api/session-description-handler-factory.ts +16 -0
- package/src/api/session-description-handler.ts +89 -0
- package/src/api/session-info-options.ts +12 -0
- package/src/api/session-invite-options.ts +29 -0
- package/src/api/session-message-options.ts +12 -0
- package/src/api/session-options.ts +8 -0
- package/src/api/session-refer-options.ts +15 -0
- package/src/api/session-state.ts +45 -0
- package/src/api/session.ts +1448 -0
- package/src/api/subscriber-options.ts +12 -0
- package/src/api/subscriber-subscribe-options.ts +6 -0
- package/src/api/subscriber.ts +536 -0
- package/src/api/subscription-delegate.ts +13 -0
- package/src/api/subscription-options.ts +8 -0
- package/src/api/subscription-state.ts +19 -0
- package/src/api/subscription-subscribe-options.ts +6 -0
- package/src/api/subscription-unsubscribe-options.ts +6 -0
- package/src/api/subscription.ts +161 -0
- package/src/api/transport-state.ts +37 -0
- package/src/api/transport.ts +169 -0
- package/src/api/user-agent-delegate.ts +95 -0
- package/src/api/user-agent-options.ts +322 -0
- package/src/api/user-agent-state.ts +14 -0
- package/src/api/user-agent.ts +1014 -0
- package/src/core/api-extractor.json +358 -0
- package/src/core/dialogs/dialog-state.ts +35 -0
- package/src/core/dialogs/dialog.ts +605 -0
- package/src/core/dialogs/index.ts +4 -0
- package/src/core/dialogs/session-dialog.ts +996 -0
- package/src/core/dialogs/subscription-dialog.ts +557 -0
- package/src/core/exceptions/exception.ts +11 -0
- package/src/core/exceptions/index.ts +3 -0
- package/src/core/exceptions/transaction-state-error.ts +11 -0
- package/src/core/exceptions/transport-error.ts +11 -0
- package/src/core/index.ts +19 -0
- package/src/core/log/index.ts +3 -0
- package/src/core/log/levels.ts +10 -0
- package/src/core/log/logger-factory.ts +119 -0
- package/src/core/log/logger.ts +42 -0
- package/src/core/messages/body.ts +171 -0
- package/src/core/messages/digest-authentication.ts +190 -0
- package/src/core/messages/incoming-message.ts +152 -0
- package/src/core/messages/incoming-request-message.ts +14 -0
- package/src/core/messages/incoming-request.ts +75 -0
- package/src/core/messages/incoming-response-message.ts +14 -0
- package/src/core/messages/incoming-response.ts +13 -0
- package/src/core/messages/index.ts +18 -0
- package/src/core/messages/md5.ts +437 -0
- package/src/core/messages/methods/ack.ts +22 -0
- package/src/core/messages/methods/bye.ts +22 -0
- package/src/core/messages/methods/cancel.ts +22 -0
- package/src/core/messages/methods/constants.ts +21 -0
- package/src/core/messages/methods/index.ts +13 -0
- package/src/core/messages/methods/info.ts +22 -0
- package/src/core/messages/methods/invite.ts +104 -0
- package/src/core/messages/methods/message.ts +22 -0
- package/src/core/messages/methods/notify.ts +22 -0
- package/src/core/messages/methods/prack.ts +22 -0
- package/src/core/messages/methods/publish.ts +22 -0
- package/src/core/messages/methods/refer.ts +22 -0
- package/src/core/messages/methods/register.ts +22 -0
- package/src/core/messages/methods/subscribe.ts +59 -0
- package/src/core/messages/outgoing-request-message.ts +299 -0
- package/src/core/messages/outgoing-request.ts +77 -0
- package/src/core/messages/outgoing-response.ts +174 -0
- package/src/core/messages/parser.ts +265 -0
- package/src/core/messages/utils.ts +144 -0
- package/src/core/session/index.ts +2 -0
- package/src/core/session/session-delegate.ts +88 -0
- package/src/core/session/session.ts +158 -0
- package/src/core/subscription/index.ts +2 -0
- package/src/core/subscription/subscription-delegate.ts +30 -0
- package/src/core/subscription/subscription.ts +61 -0
- package/src/core/timers.ts +24 -0
- package/src/core/transactions/client-transaction.ts +78 -0
- package/src/core/transactions/index.ts +10 -0
- package/src/core/transactions/invite-client-transaction.ts +504 -0
- package/src/core/transactions/invite-server-transaction.ts +432 -0
- package/src/core/transactions/non-invite-client-transaction.ts +257 -0
- package/src/core/transactions/non-invite-server-transaction.ts +241 -0
- package/src/core/transactions/server-transaction.ts +47 -0
- package/src/core/transactions/transaction-state.ts +13 -0
- package/src/core/transactions/transaction-user.ts +82 -0
- package/src/core/transactions/transaction.ts +149 -0
- package/src/core/transport.ts +32 -0
- package/src/core/user-agent-core/allowed-methods.ts +19 -0
- package/src/core/user-agent-core/index.ts +3 -0
- package/src/core/user-agent-core/user-agent-core-configuration.ts +111 -0
- package/src/core/user-agent-core/user-agent-core-delegate.ts +50 -0
- package/src/core/user-agent-core/user-agent-core.ts +905 -0
- package/src/core/user-agents/bye-user-agent-client.ts +16 -0
- package/src/core/user-agents/bye-user-agent-server.ts +14 -0
- package/src/core/user-agents/cancel-user-agent-client.ts +14 -0
- package/src/core/user-agents/index.ts +26 -0
- package/src/core/user-agents/info-user-agent-client.ts +15 -0
- package/src/core/user-agents/info-user-agent-server.ts +14 -0
- package/src/core/user-agents/invite-user-agent-client.ts +405 -0
- package/src/core/user-agents/invite-user-agent-server.ts +269 -0
- package/src/core/user-agents/message-user-agent-client.ts +14 -0
- package/src/core/user-agents/message-user-agent-server.ts +14 -0
- package/src/core/user-agents/notify-user-agent-client.ts +15 -0
- package/src/core/user-agents/notify-user-agent-server.ts +30 -0
- package/src/core/user-agents/prack-user-agent-client.ts +16 -0
- package/src/core/user-agents/prack-user-agent-server.ts +37 -0
- package/src/core/user-agents/publish-user-agent-client.ts +14 -0
- package/src/core/user-agents/re-invite-user-agent-client.ts +127 -0
- package/src/core/user-agents/re-invite-user-agent-server.ts +109 -0
- package/src/core/user-agents/re-subscribe-user-agent-client.ts +78 -0
- package/src/core/user-agents/re-subscribe-user-agent-server.ts +14 -0
- package/src/core/user-agents/refer-user-agent-client.ts +15 -0
- package/src/core/user-agents/refer-user-agent-server.ts +30 -0
- package/src/core/user-agents/register-user-agent-client.ts +14 -0
- package/src/core/user-agents/register-user-agent-server.ts +14 -0
- package/src/core/user-agents/subscribe-user-agent-client.ts +341 -0
- package/src/core/user-agents/subscribe-user-agent-server.ts +14 -0
- package/src/core/user-agents/user-agent-client.ts +378 -0
- package/src/core/user-agents/user-agent-server.ts +276 -0
- package/src/grammar/grammar.ts +55 -0
- package/src/grammar/index.ts +4 -0
- package/src/grammar/name-addr-header.ts +58 -0
- package/src/grammar/parameters.ts +45 -0
- package/src/grammar/pegjs/README.md +9 -0
- package/src/grammar/pegjs/dist/grammar.ts +1557 -0
- package/src/grammar/pegjs/src/grammar.pegjs +1009 -0
- package/src/grammar/uri.ts +370 -0
- package/src/index.ts +49 -26
- package/src/lib/socket.io.esm.min.js +7 -0
- package/src/main.ts +26 -0
- package/src/new-index.ts +2478 -0
- package/src/platform/react/README.md +1 -0
- package/src/platform/web/index.ts +4 -0
- package/src/platform/web/modifiers/index.ts +5 -0
- package/src/platform/web/modifiers/modifiers.ts +180 -0
- package/src/platform/web/session-description-handler/api-extractor.json +358 -0
- package/src/platform/web/session-description-handler/index.ts +14 -0
- package/src/platform/web/session-description-handler/media-stream-factory-default.ts +22 -0
- package/src/platform/web/session-description-handler/media-stream-factory.ts +10 -0
- package/src/platform/web/session-description-handler/peer-connection-configuration-default.ts +17 -0
- package/src/platform/web/session-description-handler/peer-connection-delegate.ts +72 -0
- package/src/platform/web/session-description-handler/session-description-handler-configuration.ts +17 -0
- package/src/platform/web/session-description-handler/session-description-handler-factory-default.ts +45 -0
- package/src/platform/web/session-description-handler/session-description-handler-factory-options.ts +10 -0
- package/src/platform/web/session-description-handler/session-description-handler-factory.ts +17 -0
- package/src/platform/web/session-description-handler/session-description-handler-options.ts +56 -0
- package/src/platform/web/session-description-handler/session-description-handler.ts +938 -0
- package/src/platform/web/simple-user/api-extractor.json +358 -0
- package/src/platform/web/simple-user/index.ts +7 -0
- package/src/platform/web/simple-user/simple-user-delegate.ts +82 -0
- package/src/platform/web/simple-user/simple-user-options.ts +102 -0
- package/src/platform/web/simple-user/simple-user.ts +1099 -0
- package/src/platform/web/transport/api-extractor.json +358 -0
- package/src/platform/web/transport/index.ts +6 -0
- package/src/platform/web/transport/transport-options.ts +34 -0
- package/src/platform/web/transport/transport.ts +742 -0
- package/src/version.ts +8 -0
- package/src/webPhoneSdk.ts +67 -0
- package/src/webrtc.ts +318 -0
- package/tsconfig.json +26 -10
- /package/dist/{types/config.d.ts → config.d.ts} +0 -0
|
@@ -0,0 +1,905 @@
|
|
|
1
|
+
import { Dialog } from "../dialogs";
|
|
2
|
+
import { Logger, LoggerFactory } from "../log";
|
|
3
|
+
import {
|
|
4
|
+
Body,
|
|
5
|
+
C,
|
|
6
|
+
constructOutgoingResponse,
|
|
7
|
+
IncomingRequestMessage,
|
|
8
|
+
IncomingResponseMessage,
|
|
9
|
+
OutgoingInviteRequest,
|
|
10
|
+
OutgoingInviteRequestDelegate,
|
|
11
|
+
OutgoingMessageRequest,
|
|
12
|
+
OutgoingPublishRequest,
|
|
13
|
+
OutgoingRegisterRequest,
|
|
14
|
+
OutgoingRequest,
|
|
15
|
+
OutgoingRequestDelegate,
|
|
16
|
+
OutgoingRequestMessage,
|
|
17
|
+
OutgoingRequestMessageOptions,
|
|
18
|
+
OutgoingResponse,
|
|
19
|
+
OutgoingSubscribeRequest,
|
|
20
|
+
OutgoingSubscribeRequestDelegate,
|
|
21
|
+
ResponseOptions,
|
|
22
|
+
URI
|
|
23
|
+
} from "../messages";
|
|
24
|
+
import { InviteServerTransaction, NonInviteClientTransaction, TransactionState } from "../transactions";
|
|
25
|
+
import { Transport } from "../transport";
|
|
26
|
+
import {
|
|
27
|
+
InviteUserAgentClient,
|
|
28
|
+
InviteUserAgentServer,
|
|
29
|
+
MessageUserAgentClient,
|
|
30
|
+
MessageUserAgentServer,
|
|
31
|
+
NotifyUserAgentServer,
|
|
32
|
+
PublishUserAgentClient,
|
|
33
|
+
ReferUserAgentServer,
|
|
34
|
+
RegisterUserAgentClient,
|
|
35
|
+
RegisterUserAgentServer,
|
|
36
|
+
SubscribeUserAgentClient,
|
|
37
|
+
SubscribeUserAgentServer,
|
|
38
|
+
UserAgentClient,
|
|
39
|
+
UserAgentServer
|
|
40
|
+
} from "../user-agents";
|
|
41
|
+
import { AllowedMethods } from "./allowed-methods";
|
|
42
|
+
import { UserAgentCoreConfiguration } from "./user-agent-core-configuration";
|
|
43
|
+
import { UserAgentCoreDelegate } from "./user-agent-core-delegate";
|
|
44
|
+
/**
|
|
45
|
+
* This is ported from UA.C.ACCEPTED_BODY_TYPES.
|
|
46
|
+
* FIXME: TODO: Should be configurable/variable.
|
|
47
|
+
*/
|
|
48
|
+
const acceptedBodyTypes = ["application/sdp", "application/dtmf-relay"];
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* User Agent Core.
|
|
52
|
+
* @remarks
|
|
53
|
+
* Core designates the functions specific to a particular type
|
|
54
|
+
* of SIP entity, i.e., specific to either a stateful or stateless
|
|
55
|
+
* proxy, a user agent or registrar. All cores, except those for
|
|
56
|
+
* the stateless proxy, are transaction users.
|
|
57
|
+
* https://tools.ietf.org/html/rfc3261#section-6
|
|
58
|
+
*
|
|
59
|
+
* UAC Core: The set of processing functions required of a UAC that
|
|
60
|
+
* reside above the transaction and transport layers.
|
|
61
|
+
* https://tools.ietf.org/html/rfc3261#section-6
|
|
62
|
+
*
|
|
63
|
+
* UAS Core: The set of processing functions required at a UAS that
|
|
64
|
+
* resides above the transaction and transport layers.
|
|
65
|
+
* https://tools.ietf.org/html/rfc3261#section-6
|
|
66
|
+
* @public
|
|
67
|
+
*/
|
|
68
|
+
export class UserAgentCore {
|
|
69
|
+
/** Configuration. */
|
|
70
|
+
public configuration: UserAgentCoreConfiguration;
|
|
71
|
+
/** Delegate. */
|
|
72
|
+
public delegate: UserAgentCoreDelegate;
|
|
73
|
+
/** Dialogs. */
|
|
74
|
+
public dialogs: Map<string, Dialog>;
|
|
75
|
+
/** Subscribers. */
|
|
76
|
+
public subscribers: Map<string, SubscribeUserAgentClient>;
|
|
77
|
+
/** UACs. */
|
|
78
|
+
public userAgentClients = new Map<string, UserAgentClient>();
|
|
79
|
+
/** UASs. */
|
|
80
|
+
public userAgentServers = new Map<string, UserAgentServer>();
|
|
81
|
+
|
|
82
|
+
private logger: Logger;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Constructor.
|
|
86
|
+
* @param configuration - Configuration.
|
|
87
|
+
* @param delegate - Delegate.
|
|
88
|
+
*/
|
|
89
|
+
constructor(configuration: UserAgentCoreConfiguration, delegate: UserAgentCoreDelegate = {}) {
|
|
90
|
+
this.configuration = configuration;
|
|
91
|
+
this.delegate = delegate;
|
|
92
|
+
this.dialogs = new Map<string, Dialog>();
|
|
93
|
+
this.subscribers = new Map<string, SubscribeUserAgentClient>();
|
|
94
|
+
this.logger = configuration.loggerFactory.getLogger("sip.user-agent-core");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Destructor. */
|
|
98
|
+
public dispose(): void {
|
|
99
|
+
this.reset();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Reset. */
|
|
103
|
+
public reset(): void {
|
|
104
|
+
this.dialogs.forEach((dialog) => dialog.dispose());
|
|
105
|
+
this.dialogs.clear();
|
|
106
|
+
this.subscribers.forEach((subscriber) => subscriber.dispose());
|
|
107
|
+
this.subscribers.clear();
|
|
108
|
+
this.userAgentClients.forEach((uac) => uac.dispose());
|
|
109
|
+
this.userAgentClients.clear();
|
|
110
|
+
this.userAgentServers.forEach((uac) => uac.dispose());
|
|
111
|
+
this.userAgentServers.clear();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Logger factory. */
|
|
115
|
+
get loggerFactory(): LoggerFactory {
|
|
116
|
+
return this.configuration.loggerFactory;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** Transport. */
|
|
120
|
+
get transport(): Transport {
|
|
121
|
+
const transport = this.configuration.transportAccessor();
|
|
122
|
+
if (!transport) {
|
|
123
|
+
throw new Error("Transport undefined.");
|
|
124
|
+
}
|
|
125
|
+
return transport;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Send INVITE.
|
|
130
|
+
* @param request - Outgoing request.
|
|
131
|
+
* @param delegate - Request delegate.
|
|
132
|
+
*/
|
|
133
|
+
public invite(request: OutgoingRequestMessage, delegate?: OutgoingInviteRequestDelegate): OutgoingInviteRequest {
|
|
134
|
+
return new InviteUserAgentClient(this, request, delegate);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Send MESSAGE.
|
|
139
|
+
* @param request - Outgoing request.
|
|
140
|
+
* @param delegate - Request delegate.
|
|
141
|
+
*/
|
|
142
|
+
public message(request: OutgoingRequestMessage, delegate?: OutgoingRequestDelegate): OutgoingMessageRequest {
|
|
143
|
+
return new MessageUserAgentClient(this, request, delegate);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Send PUBLISH.
|
|
148
|
+
* @param request - Outgoing request.
|
|
149
|
+
* @param delegate - Request delegate.
|
|
150
|
+
*/
|
|
151
|
+
public publish(request: OutgoingRequestMessage, delegate?: OutgoingRequestDelegate): OutgoingPublishRequest {
|
|
152
|
+
return new PublishUserAgentClient(this, request, delegate);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Send REGISTER.
|
|
157
|
+
* @param request - Outgoing request.
|
|
158
|
+
* @param delegate - Request delegate.
|
|
159
|
+
*/
|
|
160
|
+
public register(request: OutgoingRequestMessage, delegate?: OutgoingRequestDelegate): OutgoingRegisterRequest {
|
|
161
|
+
return new RegisterUserAgentClient(this, request, delegate);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Send SUBSCRIBE.
|
|
166
|
+
* @param request - Outgoing request.
|
|
167
|
+
* @param delegate - Request delegate.
|
|
168
|
+
*/
|
|
169
|
+
public subscribe(
|
|
170
|
+
request: OutgoingRequestMessage,
|
|
171
|
+
delegate?: OutgoingSubscribeRequestDelegate
|
|
172
|
+
): OutgoingSubscribeRequest {
|
|
173
|
+
return new SubscribeUserAgentClient(this, request, delegate);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Send a request.
|
|
178
|
+
* @param request - Outgoing request.
|
|
179
|
+
* @param delegate - Request delegate.
|
|
180
|
+
*/
|
|
181
|
+
public request(request: OutgoingRequestMessage, delegate?: OutgoingRequestDelegate): OutgoingRequest {
|
|
182
|
+
return new UserAgentClient(NonInviteClientTransaction, this, request, delegate);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Outgoing request message factory function.
|
|
187
|
+
* @param method - Method.
|
|
188
|
+
* @param requestURI - Request-URI.
|
|
189
|
+
* @param fromURI - From URI.
|
|
190
|
+
* @param toURI - To URI.
|
|
191
|
+
* @param options - Request options.
|
|
192
|
+
* @param extraHeaders - Extra headers to add.
|
|
193
|
+
* @param body - Message body.
|
|
194
|
+
*/
|
|
195
|
+
public makeOutgoingRequestMessage(
|
|
196
|
+
method: string,
|
|
197
|
+
requestURI: URI,
|
|
198
|
+
fromURI: URI,
|
|
199
|
+
toURI: URI,
|
|
200
|
+
options: OutgoingRequestMessageOptions,
|
|
201
|
+
extraHeaders?: Array<string>,
|
|
202
|
+
body?: Body
|
|
203
|
+
): OutgoingRequestMessage {
|
|
204
|
+
// default values from user agent configuration
|
|
205
|
+
const callIdPrefix = this.configuration.sipjsId;
|
|
206
|
+
const fromDisplayName = this.configuration.displayName;
|
|
207
|
+
const forceRport = this.configuration.viaForceRport;
|
|
208
|
+
const hackViaTcp = this.configuration.hackViaTcp;
|
|
209
|
+
const optionTags = this.configuration.supportedOptionTags.slice();
|
|
210
|
+
if (method === C.REGISTER) {
|
|
211
|
+
optionTags.push("path", "gruu");
|
|
212
|
+
}
|
|
213
|
+
if (method === C.INVITE && (this.configuration.contact.pubGruu || this.configuration.contact.tempGruu)) {
|
|
214
|
+
optionTags.push("gruu");
|
|
215
|
+
}
|
|
216
|
+
const routeSet = this.configuration.routeSet;
|
|
217
|
+
const userAgentString = this.configuration.userAgentHeaderFieldValue;
|
|
218
|
+
const viaHost = this.configuration.viaHost;
|
|
219
|
+
|
|
220
|
+
const defaultOptions: OutgoingRequestMessageOptions = {
|
|
221
|
+
callIdPrefix,
|
|
222
|
+
forceRport,
|
|
223
|
+
fromDisplayName,
|
|
224
|
+
hackViaTcp,
|
|
225
|
+
optionTags,
|
|
226
|
+
routeSet,
|
|
227
|
+
userAgentString,
|
|
228
|
+
viaHost
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// merge provided options with default options
|
|
232
|
+
const requestOptions: OutgoingRequestMessageOptions = {
|
|
233
|
+
...defaultOptions,
|
|
234
|
+
...options
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
return new OutgoingRequestMessage(method, requestURI, fromURI, toURI, requestOptions, extraHeaders, body);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Handle an incoming request message from the transport.
|
|
242
|
+
* @param message - Incoming request message from transport layer.
|
|
243
|
+
*/
|
|
244
|
+
public receiveIncomingRequestFromTransport(message: IncomingRequestMessage): void {
|
|
245
|
+
this.receiveRequestFromTransport(message);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Handle an incoming response message from the transport.
|
|
250
|
+
* @param message - Incoming response message from transport layer.
|
|
251
|
+
*/
|
|
252
|
+
public receiveIncomingResponseFromTransport(message: IncomingResponseMessage): void {
|
|
253
|
+
this.receiveResponseFromTransport(message);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* A stateless UAS is a UAS that does not maintain transaction state.
|
|
258
|
+
* It replies to requests normally, but discards any state that would
|
|
259
|
+
* ordinarily be retained by a UAS after a response has been sent. If a
|
|
260
|
+
* stateless UAS receives a retransmission of a request, it regenerates
|
|
261
|
+
* the response and re-sends it, just as if it were replying to the first
|
|
262
|
+
* instance of the request. A UAS cannot be stateless unless the request
|
|
263
|
+
* processing for that method would always result in the same response
|
|
264
|
+
* if the requests are identical. This rules out stateless registrars,
|
|
265
|
+
* for example. Stateless UASs do not use a transaction layer; they
|
|
266
|
+
* receive requests directly from the transport layer and send responses
|
|
267
|
+
* directly to the transport layer.
|
|
268
|
+
* https://tools.ietf.org/html/rfc3261#section-8.2.7
|
|
269
|
+
* @param message - Incoming request message to reply to.
|
|
270
|
+
* @param statusCode - Status code to reply with.
|
|
271
|
+
*/
|
|
272
|
+
public replyStateless(message: IncomingRequestMessage, options: ResponseOptions): OutgoingResponse {
|
|
273
|
+
const userAgent = this.configuration.userAgentHeaderFieldValue;
|
|
274
|
+
const supported = this.configuration.supportedOptionTagsResponse;
|
|
275
|
+
options = { ...options, userAgent, supported };
|
|
276
|
+
const response = constructOutgoingResponse(message, options);
|
|
277
|
+
this.transport.send(response.message).catch((error) => {
|
|
278
|
+
// If the transport rejects, it SHOULD reject with a TransportError.
|
|
279
|
+
// But the transport may be external code, so we are careful...
|
|
280
|
+
if (error instanceof Error) {
|
|
281
|
+
this.logger.error(error.message);
|
|
282
|
+
}
|
|
283
|
+
this.logger.error(`Transport error occurred sending stateless reply to ${message.method} request.`);
|
|
284
|
+
// TODO: Currently there is no hook to provide notification that a transport error occurred
|
|
285
|
+
// and throwing would result in an uncaught error (in promise), so we silently eat the error.
|
|
286
|
+
// Furthermore, silently eating stateless reply transport errors is arguably what we want to do here.
|
|
287
|
+
});
|
|
288
|
+
return response;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* In Section 18.2.1, replace the last paragraph with:
|
|
293
|
+
*
|
|
294
|
+
* Next, the server transport attempts to match the request to a
|
|
295
|
+
* server transaction. It does so using the matching rules described
|
|
296
|
+
* in Section 17.2.3. If a matching server transaction is found, the
|
|
297
|
+
* request is passed to that transaction for processing. If no match
|
|
298
|
+
* is found, the request is passed to the core, which may decide to
|
|
299
|
+
* construct a new server transaction for that request.
|
|
300
|
+
* https://tools.ietf.org/html/rfc6026#section-8.10
|
|
301
|
+
* @param message - Incoming request message from transport layer.
|
|
302
|
+
*/
|
|
303
|
+
private receiveRequestFromTransport(message: IncomingRequestMessage): void {
|
|
304
|
+
// When a request is received from the network by the server, it has to
|
|
305
|
+
// be matched to an existing transaction. This is accomplished in the
|
|
306
|
+
// following manner.
|
|
307
|
+
//
|
|
308
|
+
// The branch parameter in the topmost Via header field of the request
|
|
309
|
+
// is examined. If it is present and begins with the magic cookie
|
|
310
|
+
// "z9hG4bK", the request was generated by a client transaction
|
|
311
|
+
// compliant to this specification. Therefore, the branch parameter
|
|
312
|
+
// will be unique across all transactions sent by that client. The
|
|
313
|
+
// request matches a transaction if:
|
|
314
|
+
//
|
|
315
|
+
// 1. the branch parameter in the request is equal to the one in the
|
|
316
|
+
// top Via header field of the request that created the
|
|
317
|
+
// transaction, and
|
|
318
|
+
//
|
|
319
|
+
// 2. the sent-by value in the top Via of the request is equal to the
|
|
320
|
+
// one in the request that created the transaction, and
|
|
321
|
+
//
|
|
322
|
+
// 3. the method of the request matches the one that created the
|
|
323
|
+
// transaction, except for ACK, where the method of the request
|
|
324
|
+
// that created the transaction is INVITE.
|
|
325
|
+
//
|
|
326
|
+
// This matching rule applies to both INVITE and non-INVITE transactions
|
|
327
|
+
// alike.
|
|
328
|
+
//
|
|
329
|
+
// The sent-by value is used as part of the matching process because
|
|
330
|
+
// there could be accidental or malicious duplication of branch
|
|
331
|
+
// parameters from different clients.
|
|
332
|
+
// https://tools.ietf.org/html/rfc3261#section-17.2.3
|
|
333
|
+
const transactionId = message.viaBranch; // FIXME: Currently only using rule 1...
|
|
334
|
+
const uas = this.userAgentServers.get(transactionId);
|
|
335
|
+
|
|
336
|
+
// When receiving an ACK that matches an existing INVITE server
|
|
337
|
+
// transaction and that does not contain a branch parameter containing
|
|
338
|
+
// the magic cookie defined in RFC 3261, the matching transaction MUST
|
|
339
|
+
// be checked to see if it is in the "Accepted" state. If it is, then
|
|
340
|
+
// the ACK must be passed directly to the transaction user instead of
|
|
341
|
+
// being absorbed by the transaction state machine. This is necessary
|
|
342
|
+
// as requests from RFC 2543 clients will not include a unique branch
|
|
343
|
+
// parameter, and the mechanisms for calculating the transaction ID from
|
|
344
|
+
// such a request will be the same for both INVITE and ACKs.
|
|
345
|
+
// https://tools.ietf.org/html/rfc6026#section-6
|
|
346
|
+
|
|
347
|
+
// Any ACKs received from the network while in the "Accepted" state MUST be
|
|
348
|
+
// passed directly to the TU and not absorbed.
|
|
349
|
+
// https://tools.ietf.org/html/rfc6026#section-7.1
|
|
350
|
+
if (message.method === C.ACK) {
|
|
351
|
+
if (uas && uas.transaction.state === TransactionState.Accepted) {
|
|
352
|
+
if (uas instanceof InviteUserAgentServer) {
|
|
353
|
+
// These are ACKs matching an INVITE server transaction.
|
|
354
|
+
// These should never happen with RFC 3261 compliant user agents
|
|
355
|
+
// (would be a broken ACK to negative final response or something)
|
|
356
|
+
// but is apparently how RFC 2543 user agents do things.
|
|
357
|
+
// We are not currently supporting this case.
|
|
358
|
+
// NOTE: Not backwards compatible with RFC 2543 (no support for strict-routing).
|
|
359
|
+
this.logger.warn(`Discarding out of dialog ACK after 2xx response sent on transaction ${transactionId}.`);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// The CANCEL method requests that the TU at the server side cancel a
|
|
366
|
+
// pending transaction. The TU determines the transaction to be
|
|
367
|
+
// cancelled by taking the CANCEL request, and then assuming that the
|
|
368
|
+
// request method is anything but CANCEL or ACK and applying the
|
|
369
|
+
// transaction matching procedures of Section 17.2.3. The matching
|
|
370
|
+
// transaction is the one to be cancelled.
|
|
371
|
+
// https://tools.ietf.org/html/rfc3261#section-9.2
|
|
372
|
+
if (message.method === C.CANCEL) {
|
|
373
|
+
if (uas) {
|
|
374
|
+
// Regardless of the method of the original request, as long as the
|
|
375
|
+
// CANCEL matched an existing transaction, the UAS answers the CANCEL
|
|
376
|
+
// request itself with a 200 (OK) response.
|
|
377
|
+
// https://tools.ietf.org/html/rfc3261#section-9.2
|
|
378
|
+
this.replyStateless(message, { statusCode: 200 });
|
|
379
|
+
|
|
380
|
+
// If the transaction for the original request still exists, the behavior
|
|
381
|
+
// of the UAS on receiving a CANCEL request depends on whether it has already
|
|
382
|
+
// sent a final response for the original request. If it has, the CANCEL
|
|
383
|
+
// request has no effect on the processing of the original request, no
|
|
384
|
+
// effect on any session state, and no effect on the responses generated
|
|
385
|
+
// for the original request. If the UAS has not issued a final response
|
|
386
|
+
// for the original request, its behavior depends on the method of the
|
|
387
|
+
// original request. If the original request was an INVITE, the UAS
|
|
388
|
+
// SHOULD immediately respond to the INVITE with a 487 (Request
|
|
389
|
+
// Terminated).
|
|
390
|
+
// https://tools.ietf.org/html/rfc3261#section-9.2
|
|
391
|
+
if (
|
|
392
|
+
uas.transaction instanceof InviteServerTransaction &&
|
|
393
|
+
uas.transaction.state === TransactionState.Proceeding
|
|
394
|
+
) {
|
|
395
|
+
if (uas instanceof InviteUserAgentServer) {
|
|
396
|
+
uas.receiveCancel(message);
|
|
397
|
+
}
|
|
398
|
+
// A CANCEL request has no impact on the processing of
|
|
399
|
+
// transactions with any other method defined in this specification.
|
|
400
|
+
// https://tools.ietf.org/html/rfc3261#section-9.2
|
|
401
|
+
}
|
|
402
|
+
} else {
|
|
403
|
+
// If the UAS did not find a matching transaction for the CANCEL
|
|
404
|
+
// according to the procedure above, it SHOULD respond to the CANCEL
|
|
405
|
+
// with a 481 (Call Leg/Transaction Does Not Exist).
|
|
406
|
+
// https://tools.ietf.org/html/rfc3261#section-9.2
|
|
407
|
+
this.replyStateless(message, { statusCode: 481 });
|
|
408
|
+
}
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// If a matching server transaction is found, the request is passed to that
|
|
413
|
+
// transaction for processing.
|
|
414
|
+
// https://tools.ietf.org/html/rfc6026#section-8.10
|
|
415
|
+
if (uas) {
|
|
416
|
+
uas.transaction.receiveRequest(message);
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// If no match is found, the request is passed to the core, which may decide to
|
|
421
|
+
// construct a new server transaction for that request.
|
|
422
|
+
// https://tools.ietf.org/html/rfc6026#section-8.10
|
|
423
|
+
this.receiveRequest(message);
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* UAC and UAS procedures depend strongly on two factors. First, based
|
|
429
|
+
* on whether the request or response is inside or outside of a dialog,
|
|
430
|
+
* and second, based on the method of a request. Dialogs are discussed
|
|
431
|
+
* thoroughly in Section 12; they represent a peer-to-peer relationship
|
|
432
|
+
* between user agents and are established by specific SIP methods, such
|
|
433
|
+
* as INVITE.
|
|
434
|
+
* @param message - Incoming request message.
|
|
435
|
+
*/
|
|
436
|
+
private receiveRequest(message: IncomingRequestMessage): void {
|
|
437
|
+
// 8.2 UAS Behavior
|
|
438
|
+
// UASs SHOULD process the requests in the order of the steps that
|
|
439
|
+
// follow in this section (that is, starting with authentication, then
|
|
440
|
+
// inspecting the method, the header fields, and so on throughout the
|
|
441
|
+
// remainder of this section).
|
|
442
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2
|
|
443
|
+
|
|
444
|
+
// 8.2.1 Method Inspection
|
|
445
|
+
// Once a request is authenticated (or authentication is skipped), the
|
|
446
|
+
// UAS MUST inspect the method of the request. If the UAS recognizes
|
|
447
|
+
// but does not support the method of a request, it MUST generate a 405
|
|
448
|
+
// (Method Not Allowed) response. Procedures for generating responses
|
|
449
|
+
// are described in Section 8.2.6. The UAS MUST also add an Allow
|
|
450
|
+
// header field to the 405 (Method Not Allowed) response. The Allow
|
|
451
|
+
// header field MUST list the set of methods supported by the UAS
|
|
452
|
+
// generating the message.
|
|
453
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.1
|
|
454
|
+
if (!AllowedMethods.includes(message.method)) {
|
|
455
|
+
const allowHeader = "Allow: " + AllowedMethods.toString();
|
|
456
|
+
this.replyStateless(message, {
|
|
457
|
+
statusCode: 405,
|
|
458
|
+
extraHeaders: [allowHeader]
|
|
459
|
+
});
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// 8.2.2 Header Inspection
|
|
464
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.2
|
|
465
|
+
if (!message.ruri) {
|
|
466
|
+
// FIXME: A request message should always have an ruri
|
|
467
|
+
throw new Error("Request-URI undefined.");
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
// 8.2.2.1 To and Request-URI
|
|
471
|
+
// If the Request-URI uses a scheme not supported by the UAS, it SHOULD
|
|
472
|
+
// reject the request with a 416 (Unsupported URI Scheme) response.
|
|
473
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.2.1
|
|
474
|
+
if (message.ruri.scheme !== "sip") {
|
|
475
|
+
this.replyStateless(message, { statusCode: 416 });
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// 8.2.2.1 To and Request-URI
|
|
480
|
+
// If the Request-URI does not identify an address that the
|
|
481
|
+
// UAS is willing to accept requests for, it SHOULD reject
|
|
482
|
+
// the request with a 404 (Not Found) response.
|
|
483
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.2.1
|
|
484
|
+
const ruri = message.ruri;
|
|
485
|
+
const ruriMatches = (uri: URI | undefined): boolean => {
|
|
486
|
+
return !!uri && uri.user === ruri.user;
|
|
487
|
+
};
|
|
488
|
+
if (
|
|
489
|
+
!ruriMatches(this.configuration.aor) &&
|
|
490
|
+
!(
|
|
491
|
+
ruriMatches(this.configuration.contact.uri) ||
|
|
492
|
+
ruriMatches(this.configuration.contact.pubGruu) ||
|
|
493
|
+
ruriMatches(this.configuration.contact.tempGruu)
|
|
494
|
+
)
|
|
495
|
+
) {
|
|
496
|
+
this.logger.warn("Request-URI does not point to us.");
|
|
497
|
+
if (message.method !== C.ACK) {
|
|
498
|
+
this.replyStateless(message, { statusCode: 404 });
|
|
499
|
+
}
|
|
500
|
+
return;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// 8.2.2.1 To and Request-URI
|
|
504
|
+
// Other potential sources of received Request-URIs include
|
|
505
|
+
// the Contact header fields of requests and responses sent by the UA
|
|
506
|
+
// that establish or refresh dialogs.
|
|
507
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.2.1
|
|
508
|
+
if (message.method === C.INVITE) {
|
|
509
|
+
if (!message.hasHeader("Contact")) {
|
|
510
|
+
this.replyStateless(message, {
|
|
511
|
+
statusCode: 400,
|
|
512
|
+
reasonPhrase: "Missing Contact Header"
|
|
513
|
+
});
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// 8.2.2.2 Merged Requests
|
|
519
|
+
// If the request has no tag in the To header field, the UAS core MUST
|
|
520
|
+
// check the request against ongoing transactions. If the From tag,
|
|
521
|
+
// Call-ID, and CSeq exactly match those associated with an ongoing
|
|
522
|
+
// transaction, but the request does not match that transaction (based
|
|
523
|
+
// on the matching rules in Section 17.2.3), the UAS core SHOULD
|
|
524
|
+
// generate a 482 (Loop Detected) response and pass it to the server
|
|
525
|
+
// transaction.
|
|
526
|
+
//
|
|
527
|
+
// The same request has arrived at the UAS more than once, following
|
|
528
|
+
// different paths, most likely due to forking. The UAS processes
|
|
529
|
+
// the first such request received and responds with a 482 (Loop
|
|
530
|
+
// Detected) to the rest of them.
|
|
531
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.2.2
|
|
532
|
+
if (!message.toTag) {
|
|
533
|
+
const transactionId = message.viaBranch;
|
|
534
|
+
if (!this.userAgentServers.has(transactionId)) {
|
|
535
|
+
const mergedRequest = Array.from(this.userAgentServers.values()).some(
|
|
536
|
+
(uas) =>
|
|
537
|
+
uas.transaction.request.fromTag === message.fromTag &&
|
|
538
|
+
uas.transaction.request.callId === message.callId &&
|
|
539
|
+
uas.transaction.request.cseq === message.cseq
|
|
540
|
+
);
|
|
541
|
+
if (mergedRequest) {
|
|
542
|
+
this.replyStateless(message, { statusCode: 482 });
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
// 8.2.2.3 Require
|
|
549
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.2.3
|
|
550
|
+
// TODO
|
|
551
|
+
|
|
552
|
+
// 8.2.3 Content Processing
|
|
553
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.3
|
|
554
|
+
// TODO
|
|
555
|
+
|
|
556
|
+
// 8.2.4 Applying Extensions
|
|
557
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.4
|
|
558
|
+
// TODO
|
|
559
|
+
|
|
560
|
+
// 8.2.5 Processing the Request
|
|
561
|
+
// Assuming all of the checks in the previous subsections are passed,
|
|
562
|
+
// the UAS processing becomes method-specific.
|
|
563
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.5
|
|
564
|
+
|
|
565
|
+
// The UAS will receive the request from the transaction layer. If the
|
|
566
|
+
// request has a tag in the To header field, the UAS core computes the
|
|
567
|
+
// dialog identifier corresponding to the request and compares it with
|
|
568
|
+
// existing dialogs. If there is a match, this is a mid-dialog request.
|
|
569
|
+
// In that case, the UAS first applies the same processing rules for
|
|
570
|
+
// requests outside of a dialog, discussed in Section 8.2.
|
|
571
|
+
// https://tools.ietf.org/html/rfc3261#section-12.2.2
|
|
572
|
+
if (message.toTag) {
|
|
573
|
+
this.receiveInsideDialogRequest(message);
|
|
574
|
+
} else {
|
|
575
|
+
this.receiveOutsideDialogRequest(message);
|
|
576
|
+
}
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Once a dialog has been established between two UAs, either of them
|
|
582
|
+
* MAY initiate new transactions as needed within the dialog. The UA
|
|
583
|
+
* sending the request will take the UAC role for the transaction. The
|
|
584
|
+
* UA receiving the request will take the UAS role. Note that these may
|
|
585
|
+
* be different roles than the UAs held during the transaction that
|
|
586
|
+
* established the dialog.
|
|
587
|
+
* https://tools.ietf.org/html/rfc3261#section-12.2
|
|
588
|
+
* @param message - Incoming request message.
|
|
589
|
+
*/
|
|
590
|
+
private receiveInsideDialogRequest(message: IncomingRequestMessage): void {
|
|
591
|
+
// NOTIFY requests are matched to such SUBSCRIBE requests if they
|
|
592
|
+
// contain the same "Call-ID", a "To" header field "tag" parameter that
|
|
593
|
+
// matches the "From" header field "tag" parameter of the SUBSCRIBE
|
|
594
|
+
// request, and the same "Event" header field. Rules for comparisons of
|
|
595
|
+
// the "Event" header fields are described in Section 8.2.1.
|
|
596
|
+
// https://tools.ietf.org/html/rfc6665#section-4.4.1
|
|
597
|
+
if (message.method === C.NOTIFY) {
|
|
598
|
+
const event = message.parseHeader("Event");
|
|
599
|
+
if (!event || !event.event) {
|
|
600
|
+
this.replyStateless(message, { statusCode: 489 });
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// FIXME: Subscriber id should also matching on event id.
|
|
605
|
+
const subscriberId = message.callId + message.toTag + event.event;
|
|
606
|
+
const subscriber = this.subscribers.get(subscriberId);
|
|
607
|
+
if (subscriber) {
|
|
608
|
+
const uas = new NotifyUserAgentServer(this, message);
|
|
609
|
+
subscriber.onNotify(uas);
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// Requests sent within a dialog, as any other requests, are atomic. If
|
|
615
|
+
// a particular request is accepted by the UAS, all the state changes
|
|
616
|
+
// associated with it are performed. If the request is rejected, none
|
|
617
|
+
// of the state changes are performed.
|
|
618
|
+
//
|
|
619
|
+
// Note that some requests, such as INVITEs, affect several pieces of
|
|
620
|
+
// state.
|
|
621
|
+
//
|
|
622
|
+
// The UAS will receive the request from the transaction layer. If the
|
|
623
|
+
// request has a tag in the To header field, the UAS core computes the
|
|
624
|
+
// dialog identifier corresponding to the request and compares it with
|
|
625
|
+
// existing dialogs. If there is a match, this is a mid-dialog request.
|
|
626
|
+
// https://tools.ietf.org/html/rfc3261#section-12.2.2
|
|
627
|
+
const dialogId = message.callId + message.toTag + message.fromTag;
|
|
628
|
+
const dialog = this.dialogs.get(dialogId);
|
|
629
|
+
if (dialog) {
|
|
630
|
+
// [Sip-implementors] Reg. SIP reinvite, UPDATE and OPTIONS
|
|
631
|
+
// You got the question right.
|
|
632
|
+
//
|
|
633
|
+
// And you got the right answer too. :-)
|
|
634
|
+
//
|
|
635
|
+
// Thanks,
|
|
636
|
+
// Paul
|
|
637
|
+
//
|
|
638
|
+
// Robert Sparks wrote:
|
|
639
|
+
// > So I've lost track of the question during the musing.
|
|
640
|
+
// >
|
|
641
|
+
// > I _think_ the fundamental question being asked is this:
|
|
642
|
+
// >
|
|
643
|
+
// > Is an endpoint required to reject (with a 481) an OPTIONS request that
|
|
644
|
+
// > arrives with at to-tag but does not match any existing dialog state.
|
|
645
|
+
// > (Assuming some earlier requirement hasn't forced another error code). Or
|
|
646
|
+
// > is it OK if it just sends
|
|
647
|
+
// > a 200 OK anyhow.
|
|
648
|
+
// >
|
|
649
|
+
// > My take on the collection of specs is that its _not_ ok for it to send
|
|
650
|
+
// > the 200 OK anyhow and that it is required to send
|
|
651
|
+
// > the 481. I base this primarily on these sentences from 11.2 in 3261:
|
|
652
|
+
// >
|
|
653
|
+
// > The response to an OPTIONS is constructed using the standard rules
|
|
654
|
+
// > for a SIP response as discussed in Section 8.2.6. The response code
|
|
655
|
+
// > chosen MUST be the same that would have been chosen had the request
|
|
656
|
+
// > been an INVITE.
|
|
657
|
+
// >
|
|
658
|
+
// > Did I miss the point of the question?
|
|
659
|
+
// >
|
|
660
|
+
// > On May 15, 2008, at 12:48 PM, Paul Kyzivat wrote:
|
|
661
|
+
// >
|
|
662
|
+
// >> [Including Robert in hopes of getting his insight on this.]
|
|
663
|
+
// https://lists.cs.columbia.edu/pipermail/sip-implementors/2008-May/019178.html
|
|
664
|
+
//
|
|
665
|
+
// Requests that do not change in any way the state of a dialog may be
|
|
666
|
+
// received within a dialog (for example, an OPTIONS request). They are
|
|
667
|
+
// processed as if they had been received outside the dialog.
|
|
668
|
+
// https://tools.ietf.org/html/rfc3261#section-12.2.2
|
|
669
|
+
if (message.method === C.OPTIONS) {
|
|
670
|
+
const allowHeader = "Allow: " + AllowedMethods.toString();
|
|
671
|
+
const acceptHeader = "Accept: " + acceptedBodyTypes.toString();
|
|
672
|
+
this.replyStateless(message, {
|
|
673
|
+
statusCode: 200,
|
|
674
|
+
extraHeaders: [allowHeader, acceptHeader]
|
|
675
|
+
});
|
|
676
|
+
return;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Pass the incoming request to the dialog for further handling.
|
|
680
|
+
dialog.receiveRequest(message);
|
|
681
|
+
return;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// The most important behaviors of a stateless UAS are the following:
|
|
685
|
+
// ...
|
|
686
|
+
// o A stateless UAS MUST ignore ACK requests.
|
|
687
|
+
// ...
|
|
688
|
+
// https://tools.ietf.org/html/rfc3261#section-8.2.7
|
|
689
|
+
if (message.method === C.ACK) {
|
|
690
|
+
// If a final response to an INVITE was sent statelessly,
|
|
691
|
+
// the corresponding ACK:
|
|
692
|
+
// - will not match an existing transaction
|
|
693
|
+
// - may have tag in the To header field
|
|
694
|
+
// - not not match any existing dialogs
|
|
695
|
+
// Absorb unmatched ACKs.
|
|
696
|
+
return;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
// If the request has a tag in the To header field, but the dialog
|
|
700
|
+
// identifier does not match any existing dialogs, the UAS may have
|
|
701
|
+
// crashed and restarted, or it may have received a request for a
|
|
702
|
+
// different (possibly failed) UAS (the UASs can construct the To tags
|
|
703
|
+
// so that a UAS can identify that the tag was for a UAS for which it is
|
|
704
|
+
// providing recovery). Another possibility is that the incoming
|
|
705
|
+
// request has been simply mis-routed. Based on the To tag, the UAS MAY
|
|
706
|
+
// either accept or reject the request. Accepting the request for
|
|
707
|
+
// acceptable To tags provides robustness, so that dialogs can persist
|
|
708
|
+
// even through crashes. UAs wishing to support this capability must
|
|
709
|
+
// take into consideration some issues such as choosing monotonically
|
|
710
|
+
// increasing CSeq sequence numbers even across reboots, reconstructing
|
|
711
|
+
// the route set, and accepting out-of-range RTP timestamps and sequence
|
|
712
|
+
// numbers.
|
|
713
|
+
//
|
|
714
|
+
// If the UAS wishes to reject the request because it does not wish to
|
|
715
|
+
// recreate the dialog, it MUST respond to the request with a 481
|
|
716
|
+
// (Call/Transaction Does Not Exist) status code and pass that to the
|
|
717
|
+
// server transaction.
|
|
718
|
+
// https://tools.ietf.org/html/rfc3261#section-12.2.2
|
|
719
|
+
this.replyStateless(message, { statusCode: 481 });
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Assuming all of the checks in the previous subsections are passed,
|
|
725
|
+
* the UAS processing becomes method-specific.
|
|
726
|
+
* https://tools.ietf.org/html/rfc3261#section-8.2.5
|
|
727
|
+
* @param message - Incoming request message.
|
|
728
|
+
*/
|
|
729
|
+
private receiveOutsideDialogRequest(message: IncomingRequestMessage): void {
|
|
730
|
+
switch (message.method) {
|
|
731
|
+
case C.ACK:
|
|
732
|
+
// Absorb stray out of dialog ACKs
|
|
733
|
+
break;
|
|
734
|
+
case C.BYE:
|
|
735
|
+
// If the BYE does not match an existing dialog, the UAS core SHOULD
|
|
736
|
+
// generate a 481 (Call/Transaction Does Not Exist) response and pass
|
|
737
|
+
// that to the server transaction. This rule means that a BYE sent
|
|
738
|
+
// without tags by a UAC will be rejected.
|
|
739
|
+
// https://tools.ietf.org/html/rfc3261#section-15.1.2
|
|
740
|
+
this.replyStateless(message, { statusCode: 481 });
|
|
741
|
+
break;
|
|
742
|
+
case C.CANCEL:
|
|
743
|
+
throw new Error(`Unexpected out of dialog request method ${message.method}.`);
|
|
744
|
+
break;
|
|
745
|
+
case C.INFO:
|
|
746
|
+
// Use of the INFO method does not constitute a separate dialog usage.
|
|
747
|
+
// INFO messages are always part of, and share the fate of, an invite
|
|
748
|
+
// dialog usage [RFC5057]. INFO messages cannot be sent as part of
|
|
749
|
+
// other dialog usages, or outside an existing dialog.
|
|
750
|
+
// https://tools.ietf.org/html/rfc6086#section-1
|
|
751
|
+
this.replyStateless(message, { statusCode: 405 }); // Should never happen
|
|
752
|
+
break;
|
|
753
|
+
case C.INVITE:
|
|
754
|
+
// https://tools.ietf.org/html/rfc3261#section-13.3.1
|
|
755
|
+
{
|
|
756
|
+
const uas = new InviteUserAgentServer(this, message);
|
|
757
|
+
this.delegate.onInvite ? this.delegate.onInvite(uas) : uas.reject();
|
|
758
|
+
}
|
|
759
|
+
break;
|
|
760
|
+
case C.MESSAGE:
|
|
761
|
+
// MESSAGE requests are discouraged inside a dialog. Implementations
|
|
762
|
+
// are restricted from creating a usage for the purpose of carrying a
|
|
763
|
+
// sequence of MESSAGE requests (though some implementations use it that
|
|
764
|
+
// way, against the standard recommendation).
|
|
765
|
+
// https://tools.ietf.org/html/rfc5057#section-5.3
|
|
766
|
+
{
|
|
767
|
+
const uas = new MessageUserAgentServer(this, message);
|
|
768
|
+
this.delegate.onMessage ? this.delegate.onMessage(uas) : uas.accept();
|
|
769
|
+
}
|
|
770
|
+
break;
|
|
771
|
+
case C.NOTIFY:
|
|
772
|
+
// Obsoleted by: RFC 6665
|
|
773
|
+
// If any non-SUBSCRIBE mechanisms are defined to create subscriptions,
|
|
774
|
+
// it is the responsibility of the parties defining those mechanisms to
|
|
775
|
+
// ensure that correlation of a NOTIFY message to the corresponding
|
|
776
|
+
// subscription is possible. Designers of such mechanisms are also
|
|
777
|
+
// warned to make a distinction between sending a NOTIFY message to a
|
|
778
|
+
// subscriber who is aware of the subscription, and sending a NOTIFY
|
|
779
|
+
// message to an unsuspecting node. The latter behavior is invalid, and
|
|
780
|
+
// MUST receive a "481 Subscription does not exist" response (unless
|
|
781
|
+
// some other 400- or 500-class error code is more applicable), as
|
|
782
|
+
// described in section 3.2.4. In other words, knowledge of a
|
|
783
|
+
// subscription must exist in both the subscriber and the notifier to be
|
|
784
|
+
// valid, even if installed via a non-SUBSCRIBE mechanism.
|
|
785
|
+
// https://tools.ietf.org/html/rfc3265#section-3.2
|
|
786
|
+
//
|
|
787
|
+
// NOTIFY requests are sent to inform subscribers of changes in state to
|
|
788
|
+
// which the subscriber has a subscription. Subscriptions are created
|
|
789
|
+
// using the SUBSCRIBE method. In legacy implementations, it is
|
|
790
|
+
// possible that other means of subscription creation have been used.
|
|
791
|
+
// However, this specification does not allow the creation of
|
|
792
|
+
// subscriptions except through SUBSCRIBE requests and (for backwards-
|
|
793
|
+
// compatibility) REFER requests [RFC3515].
|
|
794
|
+
// https://tools.ietf.org/html/rfc6665#section-3.2
|
|
795
|
+
{
|
|
796
|
+
const uas = new NotifyUserAgentServer(this, message);
|
|
797
|
+
this.delegate.onNotify ? this.delegate.onNotify(uas) : uas.reject({ statusCode: 405 });
|
|
798
|
+
}
|
|
799
|
+
break;
|
|
800
|
+
case C.OPTIONS:
|
|
801
|
+
// https://tools.ietf.org/html/rfc3261#section-11.2
|
|
802
|
+
{
|
|
803
|
+
const allowHeader = "Allow: " + AllowedMethods.toString();
|
|
804
|
+
const acceptHeader = "Accept: " + acceptedBodyTypes.toString();
|
|
805
|
+
this.replyStateless(message, {
|
|
806
|
+
statusCode: 200,
|
|
807
|
+
extraHeaders: [allowHeader, acceptHeader]
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
break;
|
|
811
|
+
case C.REFER:
|
|
812
|
+
// https://tools.ietf.org/html/rfc3515#section-2.4.2
|
|
813
|
+
{
|
|
814
|
+
const uas = new ReferUserAgentServer(this, message);
|
|
815
|
+
this.delegate.onRefer ? this.delegate.onRefer(uas) : uas.reject({ statusCode: 405 });
|
|
816
|
+
}
|
|
817
|
+
break;
|
|
818
|
+
case C.REGISTER:
|
|
819
|
+
// https://tools.ietf.org/html/rfc3261#section-10.3
|
|
820
|
+
{
|
|
821
|
+
const uas = new RegisterUserAgentServer(this, message);
|
|
822
|
+
this.delegate.onRegister ? this.delegate.onRegister(uas) : uas.reject({ statusCode: 405 });
|
|
823
|
+
}
|
|
824
|
+
break;
|
|
825
|
+
case C.SUBSCRIBE:
|
|
826
|
+
// https://tools.ietf.org/html/rfc6665#section-4.2
|
|
827
|
+
{
|
|
828
|
+
const uas = new SubscribeUserAgentServer(this, message);
|
|
829
|
+
this.delegate.onSubscribe ? this.delegate.onSubscribe(uas) : uas.reject({ statusCode: 480 });
|
|
830
|
+
}
|
|
831
|
+
break;
|
|
832
|
+
default:
|
|
833
|
+
throw new Error(`Unexpected out of dialog request method ${message.method}.`);
|
|
834
|
+
}
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Responses are first processed by the transport layer and then passed
|
|
840
|
+
* up to the transaction layer. The transaction layer performs its
|
|
841
|
+
* processing and then passes the response up to the TU. The majority
|
|
842
|
+
* of response processing in the TU is method specific. However, there
|
|
843
|
+
* are some general behaviors independent of the method.
|
|
844
|
+
* https://tools.ietf.org/html/rfc3261#section-8.1.3
|
|
845
|
+
* @param message - Incoming response message from transport layer.
|
|
846
|
+
*/
|
|
847
|
+
private receiveResponseFromTransport(message: IncomingResponseMessage): void {
|
|
848
|
+
// 8.1.3.1 Transaction Layer Errors
|
|
849
|
+
// https://tools.ietf.org/html/rfc3261#section-8.1.3.1
|
|
850
|
+
// Handled by transaction layer callbacks.
|
|
851
|
+
|
|
852
|
+
// 8.1.3.2 Unrecognized Responses
|
|
853
|
+
// https://tools.ietf.org/html/rfc3261#section-8.1.3.1
|
|
854
|
+
// TODO
|
|
855
|
+
|
|
856
|
+
// 8.1.3.3 Vias
|
|
857
|
+
// https://tools.ietf.org/html/rfc3261#section-8.1.3.3
|
|
858
|
+
if (message.getHeaders("via").length > 1) {
|
|
859
|
+
this.logger.warn("More than one Via header field present in the response, dropping");
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// 8.1.3.4 Processing 3xx Responses
|
|
864
|
+
// https://tools.ietf.org/html/rfc3261#section-8.1.3.4
|
|
865
|
+
// TODO
|
|
866
|
+
|
|
867
|
+
// 8.1.3.5 Processing 4xx Responses
|
|
868
|
+
// https://tools.ietf.org/html/rfc3261#section-8.1.3.5
|
|
869
|
+
// TODO
|
|
870
|
+
|
|
871
|
+
// When the transport layer in the client receives a response, it has to
|
|
872
|
+
// determine which client transaction will handle the response, so that
|
|
873
|
+
// the processing of Sections 17.1.1 and 17.1.2 can take place. The
|
|
874
|
+
// branch parameter in the top Via header field is used for this
|
|
875
|
+
// purpose. A response matches a client transaction under two
|
|
876
|
+
// conditions:
|
|
877
|
+
//
|
|
878
|
+
// 1. If the response has the same value of the branch parameter in
|
|
879
|
+
// the top Via header field as the branch parameter in the top
|
|
880
|
+
// Via header field of the request that created the transaction.
|
|
881
|
+
//
|
|
882
|
+
// 2. If the method parameter in the CSeq header field matches the
|
|
883
|
+
// method of the request that created the transaction. The
|
|
884
|
+
// method is needed since a CANCEL request constitutes a
|
|
885
|
+
// different transaction, but shares the same value of the branch
|
|
886
|
+
// parameter.
|
|
887
|
+
// https://tools.ietf.org/html/rfc3261#section-17.1.3
|
|
888
|
+
const userAgentClientId = message.viaBranch + message.method;
|
|
889
|
+
const userAgentClient = this.userAgentClients.get(userAgentClientId);
|
|
890
|
+
|
|
891
|
+
// The client transport uses the matching procedures of Section
|
|
892
|
+
// 17.1.3 to attempt to match the response to an existing
|
|
893
|
+
// transaction. If there is a match, the response MUST be passed to
|
|
894
|
+
// that transaction. Otherwise, any element other than a stateless
|
|
895
|
+
// proxy MUST silently discard the response.
|
|
896
|
+
// https://tools.ietf.org/html/rfc6026#section-8.9
|
|
897
|
+
if (userAgentClient) {
|
|
898
|
+
userAgentClient.transaction.receiveResponse(message);
|
|
899
|
+
} else {
|
|
900
|
+
this.logger.warn(
|
|
901
|
+
`Discarding unmatched ${message.statusCode} response to ${message.method} ${userAgentClientId}.`
|
|
902
|
+
);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|