ringcentral-softphone 1.3.4 → 1.3.6

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 (118) hide show
  1. package/dist/call-session/inbound.cjs +41 -83
  2. package/dist/call-session/inbound.d.cts +2 -0
  3. package/dist/call-session/inbound.d.mts +2 -0
  4. package/dist/call-session/inbound.mjs +51 -0
  5. package/dist/call-session/index.cjs +212 -273
  6. package/dist/call-session/index.d.cts +2 -0
  7. package/dist/call-session/index.d.mts +2 -0
  8. package/dist/call-session/index.mjs +209 -0
  9. package/dist/call-session/outbound.cjs +56 -99
  10. package/dist/call-session/outbound.d.cts +2 -0
  11. package/dist/call-session/outbound.d.mts +2 -0
  12. package/dist/call-session/outbound.mjs +57 -0
  13. package/dist/call-session/streamer.cjs +66 -111
  14. package/dist/call-session/streamer.d.cts +2 -0
  15. package/dist/call-session/streamer.d.mts +2 -0
  16. package/dist/call-session/streamer.mjs +65 -0
  17. package/dist/chunk-CKQMccvm.cjs +28 -0
  18. package/dist/codec-Bh7v8J-S.d.mts +18 -0
  19. package/dist/codec-C-VrtVkq.d.cts +18 -0
  20. package/dist/codec.cjs +68 -84
  21. package/dist/codec.d.cts +2 -0
  22. package/dist/codec.d.mts +2 -0
  23. package/dist/codec.mjs +68 -0
  24. package/dist/dtmf-B13Fz2VR.d.mts +10 -0
  25. package/dist/dtmf-DcQ-5vSG.d.cts +10 -0
  26. package/dist/dtmf.cjs +37 -60
  27. package/dist/dtmf.d.cts +2 -0
  28. package/dist/dtmf.d.mts +2 -0
  29. package/dist/dtmf.mjs +42 -0
  30. package/dist/inbound--wGoGqLS.d.mts +103 -0
  31. package/dist/inbound-DquvTSj1.d.cts +103 -0
  32. package/dist/index--UjWgLK-.d.mts +8 -0
  33. package/dist/index-BhN2W8AV.d.mts +8 -0
  34. package/dist/index-CEgs-Dz2.d.cts +1 -0
  35. package/dist/index-Cf2Cev52.d.cts +8 -0
  36. package/dist/index-XMDop59x.d.cts +8 -0
  37. package/dist/index-q_LXL61M.d.mts +1 -0
  38. package/dist/index.cjs +166 -250
  39. package/dist/index.d.cts +2 -0
  40. package/dist/index.d.mts +2 -0
  41. package/dist/index.mjs +172 -0
  42. package/dist/request-B_auLSJn.d.cts +10 -0
  43. package/dist/request-pBe7_mYv.d.mts +10 -0
  44. package/dist/response-LRRpY8lX.d.mts +9 -0
  45. package/dist/response-ReKvb5x9.d.cts +9 -0
  46. package/dist/sip-message/inbound/index.cjs +16 -50
  47. package/dist/sip-message/inbound/index.d.cts +2 -0
  48. package/dist/sip-message/inbound/index.d.mts +2 -0
  49. package/dist/sip-message/inbound/index.mjs +17 -0
  50. package/dist/sip-message/index.cjs +11 -49
  51. package/dist/sip-message/index.d.cts +6 -0
  52. package/dist/sip-message/index.d.mts +6 -0
  53. package/dist/sip-message/index.mjs +6 -0
  54. package/dist/sip-message/outbound/index.cjs +10 -40
  55. package/dist/sip-message/outbound/index.d.cts +2 -0
  56. package/dist/sip-message/outbound/index.d.mts +2 -0
  57. package/dist/sip-message/outbound/index.mjs +11 -0
  58. package/dist/sip-message/outbound/request.cjs +20 -61
  59. package/dist/sip-message/outbound/request.d.cts +2 -0
  60. package/dist/sip-message/outbound/request.d.mts +2 -0
  61. package/dist/sip-message/outbound/request.mjs +21 -0
  62. package/dist/sip-message/outbound/response.cjs +25 -54
  63. package/dist/sip-message/outbound/response.d.cts +2 -0
  64. package/dist/sip-message/outbound/response.d.mts +2 -0
  65. package/dist/sip-message/outbound/response.mjs +26 -0
  66. package/dist/sip-message/response-codes.cjs +80 -100
  67. package/dist/sip-message/response-codes.d.cts +5 -0
  68. package/dist/sip-message/response-codes.d.mts +6 -0
  69. package/dist/sip-message/response-codes.mjs +82 -0
  70. package/dist/sip-message/sip-message.cjs +25 -52
  71. package/dist/sip-message/sip-message.d.cts +2 -0
  72. package/dist/sip-message/sip-message.d.mts +2 -0
  73. package/dist/sip-message/sip-message.mjs +26 -0
  74. package/dist/sip-message-B2D5MPBI.d.cts +13 -0
  75. package/dist/sip-message-PaPho4qU.d.mts +13 -0
  76. package/dist/types-DOQ9wmX6.d.mts +12 -0
  77. package/dist/types-DZxCsbZE.d.cts +12 -0
  78. package/dist/types.cjs +0 -15
  79. package/dist/types.d.cts +2 -0
  80. package/dist/types.d.mts +2 -0
  81. package/dist/types.mjs +1 -0
  82. package/dist/utils.cjs +27 -73
  83. package/dist/utils.d.cts +12 -0
  84. package/dist/utils.d.mts +12 -0
  85. package/dist/utils.mjs +25 -0
  86. package/package.json +14 -14
  87. package/dist/call-session/inbound.d.ts +0 -8
  88. package/dist/call-session/inbound.js +0 -64
  89. package/dist/call-session/index.d.ts +0 -46
  90. package/dist/call-session/index.js +0 -248
  91. package/dist/call-session/outbound.d.ts +0 -11
  92. package/dist/call-session/outbound.js +0 -71
  93. package/dist/call-session/streamer.d.ts +0 -17
  94. package/dist/call-session/streamer.js +0 -83
  95. package/dist/codec.d.ts +0 -15
  96. package/dist/codec.js +0 -66
  97. package/dist/dtmf.d.ts +0 -7
  98. package/dist/dtmf.js +0 -47
  99. package/dist/index.d.ts +0 -28
  100. package/dist/index.js +0 -242
  101. package/dist/sip-message/inbound/index.d.ts +0 -5
  102. package/dist/sip-message/inbound/index.js +0 -22
  103. package/dist/sip-message/index.d.ts +0 -5
  104. package/dist/sip-message/index.js +0 -12
  105. package/dist/sip-message/outbound/index.d.ts +0 -5
  106. package/dist/sip-message/outbound/index.js +0 -12
  107. package/dist/sip-message/outbound/request.d.ts +0 -7
  108. package/dist/sip-message/outbound/request.js +0 -33
  109. package/dist/sip-message/outbound/response.d.ts +0 -6
  110. package/dist/sip-message/outbound/response.js +0 -26
  111. package/dist/sip-message/response-codes.d.ts +0 -4
  112. package/dist/sip-message/response-codes.js +0 -83
  113. package/dist/sip-message/sip-message.d.ts +0 -11
  114. package/dist/sip-message/sip-message.js +0 -34
  115. package/dist/types.d.ts +0 -9
  116. package/dist/types.js +0 -0
  117. package/dist/utils.d.ts +0 -8
  118. package/dist/utils.js +0 -41
@@ -1,71 +0,0 @@
1
- import { RequestMessage } from "../sip-message/index.js";
2
- import { extractAddress, withoutTag } from "../utils.js";
3
- import CallSession from "./index.js";
4
- class OutboundCallSession extends CallSession {
5
- constructor(softphone, answerMessage) {
6
- super(softphone, answerMessage);
7
- this.localPeer = answerMessage.headers.From;
8
- this.remotePeer = answerMessage.headers.To;
9
- this.remoteKey = answerMessage.body.match(
10
- /AES_CM_128_HMAC_SHA1_80 inline:([\w+/]+)/
11
- )[1];
12
- this.init();
13
- }
14
- init() {
15
- const answerHandler = (message) => {
16
- if (message.headers.CSeq !== this.sipMessage.headers.CSeq) {
17
- return;
18
- }
19
- if (message.subject.startsWith("SIP/2.0 486")) {
20
- this.softphone.off("message", answerHandler);
21
- this.emit("busy");
22
- this.dispose();
23
- return;
24
- }
25
- if (message.subject.startsWith("SIP/2.0 200")) {
26
- this.softphone.off("message", answerHandler);
27
- this.emit("answered");
28
- const ackMessage = new RequestMessage(
29
- `ACK ${extractAddress(this.remotePeer)} SIP/2.0`,
30
- {
31
- "Call-ID": this.callId,
32
- From: this.localPeer,
33
- To: this.remotePeer,
34
- Via: this.sipMessage.headers.Via,
35
- CSeq: this.sipMessage.headers.CSeq.replace(" INVITE", " ACK")
36
- }
37
- );
38
- this.softphone.send(ackMessage);
39
- }
40
- };
41
- this.softphone.on("message", answerHandler);
42
- this.once("answered", () => this.startLocalServices());
43
- }
44
- async cancel() {
45
- const requestMessage = new RequestMessage(
46
- `CANCEL ${extractAddress(this.remotePeer)} SIP/2.0`,
47
- {
48
- "Call-ID": this.callId,
49
- From: this.localPeer,
50
- To: withoutTag(this.remotePeer),
51
- Via: this.sipMessage.headers.Via,
52
- CSeq: this.sipMessage.headers.CSeq.replace(" INVITE", " CANCEL")
53
- }
54
- );
55
- await this.softphone.send(requestMessage);
56
- }
57
- get sessionId() {
58
- const header = this.sipMessage.headers["p-rc-api-ids"];
59
- const match = header.match(/party-id=([^;]+);session-id=([^;]+)/);
60
- return match[2];
61
- }
62
- get partyId() {
63
- const header = this.sipMessage.headers["p-rc-api-ids"];
64
- const match = header.match(/party-id=([^;]+);session-id=([^;]+)/);
65
- return match[1];
66
- }
67
- }
68
- var outbound_default = OutboundCallSession;
69
- export {
70
- outbound_default as default
71
- };
@@ -1,17 +0,0 @@
1
- import { Buffer } from "node:buffer";
2
- import EventEmitter from "node:events";
3
- import type CallSession from "./index.js";
4
- declare class Streamer extends EventEmitter {
5
- paused: boolean;
6
- private callSession;
7
- private buffer;
8
- private originalBuffer;
9
- constructor(callSession: CallSession, buffer: Buffer);
10
- start(): void;
11
- stop(): void;
12
- pause(): void;
13
- resume(): void;
14
- get finished(): boolean;
15
- private sendPacket;
16
- }
17
- export default Streamer;
@@ -1,83 +0,0 @@
1
- import { Buffer } from "node:buffer";
2
- import EventEmitter from "node:events";
3
- import { RtpHeader, RtpPacket } from "werift-rtp";
4
- class Streamer extends EventEmitter {
5
- paused = false;
6
- callSession;
7
- buffer;
8
- originalBuffer;
9
- constructor(callSession, buffer) {
10
- super();
11
- this.callSession = callSession;
12
- this.buffer = buffer;
13
- this.originalBuffer = buffer;
14
- }
15
- start() {
16
- this.buffer = this.originalBuffer;
17
- this.paused = false;
18
- this.sendPacket();
19
- }
20
- stop() {
21
- this.buffer = Buffer.alloc(0);
22
- }
23
- pause() {
24
- this.paused = true;
25
- }
26
- resume() {
27
- this.paused = false;
28
- this.sendPacket();
29
- }
30
- get finished() {
31
- return this.callSession.disposed || this.buffer.length < this.callSession.softphone.codec.packetSize;
32
- }
33
- sendPacket() {
34
- if (!this.paused && !this.finished) {
35
- const temp = this.callSession.encoder.encode(
36
- this.buffer.subarray(0, this.callSession.softphone.codec.packetSize)
37
- );
38
- const rtpPacket = new RtpPacket(
39
- new RtpHeader({
40
- version: 2,
41
- padding: false,
42
- paddingSize: 0,
43
- extension: false,
44
- marker: false,
45
- payloadOffset: 12,
46
- payloadType: this.callSession.softphone.codec.id,
47
- sequenceNumber: this.callSession.sequenceNumber,
48
- timestamp: this.callSession.timestamp,
49
- ssrc: this.callSession.ssrc,
50
- csrcLength: 0,
51
- csrc: [],
52
- extensionProfile: 48862,
53
- extensionLength: void 0,
54
- extensions: []
55
- }),
56
- temp
57
- );
58
- this.callSession.send(
59
- this.callSession.srtpSession.encrypt(
60
- rtpPacket.payload,
61
- rtpPacket.header
62
- )
63
- );
64
- this.callSession.sequenceNumber += 1;
65
- if (this.callSession.sequenceNumber > 65535) {
66
- this.callSession.sequenceNumber = 0;
67
- }
68
- this.callSession.timestamp += this.callSession.softphone.codec.timestampInterval;
69
- this.buffer = this.buffer.subarray(
70
- this.callSession.softphone.codec.packetSize
71
- );
72
- if (this.finished) {
73
- this.emit("finished");
74
- } else {
75
- setTimeout(() => this.sendPacket(), 20);
76
- }
77
- }
78
- }
79
- }
80
- var streamer_default = Streamer;
81
- export {
82
- streamer_default as default
83
- };
package/dist/codec.d.ts DELETED
@@ -1,15 +0,0 @@
1
- import { Buffer } from "node:buffer";
2
- declare class Codec {
3
- id: number;
4
- name: "OPUS/16000" | "OPUS/48000/2" | "PCMU/8000";
5
- packetSize: number;
6
- timestampInterval: number;
7
- createEncoder: () => {
8
- encode: (pcm: Buffer) => Buffer;
9
- };
10
- createDecoder: () => {
11
- decode: (audio: Buffer) => Buffer;
12
- };
13
- constructor(name: "OPUS/16000" | "OPUS/48000/2" | "PCMU/8000");
14
- }
15
- export default Codec;
package/dist/codec.js DELETED
@@ -1,66 +0,0 @@
1
- import { Buffer } from "node:buffer";
2
- import { Decoder, Encoder } from "@evan/opus";
3
- class Codec {
4
- id;
5
- name;
6
- packetSize;
7
- timestampInterval;
8
- createEncoder;
9
- createDecoder;
10
- constructor(name) {
11
- this.name = name;
12
- switch (name) {
13
- case "OPUS/16000": {
14
- this.createEncoder = () => {
15
- const encoder = new Encoder({ channels: 1, sample_rate: 16e3 });
16
- return { encode: (pcm) => Buffer.from(encoder.encode(pcm)) };
17
- };
18
- this.createDecoder = () => {
19
- const decoder = new Decoder({ channels: 1, sample_rate: 16e3 });
20
- return {
21
- decode: (opus) => Buffer.from(decoder.decode(opus))
22
- };
23
- };
24
- this.id = 109;
25
- this.packetSize = 640;
26
- this.timestampInterval = 320;
27
- break;
28
- }
29
- case "OPUS/48000/2": {
30
- this.createEncoder = () => {
31
- const encoder = new Encoder({ channels: 2, sample_rate: 48e3 });
32
- return { encode: (pcm) => Buffer.from(encoder.encode(pcm)) };
33
- };
34
- this.createDecoder = () => {
35
- const decoder = new Decoder({ channels: 2, sample_rate: 48e3 });
36
- return {
37
- decode: (opus) => Buffer.from(decoder.decode(opus))
38
- };
39
- };
40
- this.id = 111;
41
- this.packetSize = 3840;
42
- this.timestampInterval = 960;
43
- break;
44
- }
45
- case "PCMU/8000": {
46
- this.createEncoder = () => {
47
- return { encode: (pcm) => pcm };
48
- };
49
- this.createDecoder = () => {
50
- return { decode: (audio) => audio };
51
- };
52
- this.id = 0;
53
- this.packetSize = 160;
54
- this.timestampInterval = 160;
55
- break;
56
- }
57
- default: {
58
- throw new Error(`unsupported codec: ${name}`);
59
- }
60
- }
61
- }
62
- }
63
- var codec_default = Codec;
64
- export {
65
- codec_default as default
66
- };
package/dist/dtmf.d.ts DELETED
@@ -1,7 +0,0 @@
1
- import { Buffer } from "node:buffer";
2
- declare const DTMF: {
3
- phoneChars: readonly ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "#"];
4
- charToPayloads(char: string): Buffer<ArrayBuffer>[];
5
- payloadToChar(payload: Buffer): "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "*" | "#";
6
- };
7
- export default DTMF;
package/dist/dtmf.js DELETED
@@ -1,47 +0,0 @@
1
- import { Buffer } from "node:buffer";
2
- const phoneChars = [
3
- "0",
4
- "1",
5
- "2",
6
- "3",
7
- "4",
8
- "5",
9
- "6",
10
- "7",
11
- "8",
12
- "9",
13
- "*",
14
- "#"
15
- ];
16
- const payloads = [
17
- 393216,
18
- 393376,
19
- 393536,
20
- 8782624,
21
- 8782624,
22
- 8782624
23
- ];
24
- const DTMF = {
25
- phoneChars,
26
- charToPayloads(char) {
27
- const index = phoneChars.indexOf(char[0]);
28
- if (index === -1) {
29
- throw new Error("invalid phone char");
30
- }
31
- return payloads.map((payload) => {
32
- const temp = payload + index * 16777216;
33
- const buffer = Buffer.alloc(4);
34
- buffer.writeIntBE(temp, 0, 4);
35
- return buffer;
36
- });
37
- },
38
- payloadToChar(payload) {
39
- const intBE = payload.readIntBE(0, 4);
40
- const index = (intBE - 393216) / 16777216;
41
- return phoneChars[index];
42
- }
43
- };
44
- var dtmf_default = DTMF;
45
- export {
46
- dtmf_default as default
47
- };
package/dist/index.d.ts DELETED
@@ -1,28 +0,0 @@
1
- import EventEmitter from "node:events";
2
- import { type TLSSocket } from "node:tls";
3
- import InboundCallSession from "./call-session/inbound.js";
4
- import OutboundCallSession from "./call-session/outbound.js";
5
- import Codec from "./codec.js";
6
- import { InboundMessage, OutboundMessage } from "./sip-message/index.js";
7
- import type { SoftPhoneOptions } from "./types.js";
8
- declare class Softphone extends EventEmitter {
9
- sipInfo: SoftPhoneOptions;
10
- client: TLSSocket;
11
- codec: Codec;
12
- fakeDomain: string;
13
- fakeEmail: string;
14
- private intervalHandle?;
15
- private connected;
16
- constructor(sipInfo: SoftPhoneOptions);
17
- private instanceId;
18
- private registerCallId;
19
- register(): Promise<void>;
20
- enableDebugMode(): void;
21
- revoke(): void;
22
- send(message: OutboundMessage, waitForReply?: true): Promise<InboundMessage>;
23
- send(message: OutboundMessage, waitForReply?: false): Promise<undefined>;
24
- answer(inviteMessage: InboundMessage): Promise<InboundCallSession>;
25
- decline(inviteMessage: InboundMessage): Promise<void>;
26
- call(callee: string): Promise<OutboundCallSession>;
27
- }
28
- export default Softphone;
package/dist/index.js DELETED
@@ -1,242 +0,0 @@
1
- import EventEmitter from "node:events";
2
- import tls from "node:tls";
3
- import waitFor from "wait-for-async";
4
- import InboundCallSession from "./call-session/inbound.js";
5
- import OutboundCallSession from "./call-session/outbound.js";
6
- import Codec from "./codec.js";
7
- import {
8
- InboundMessage,
9
- OutboundMessage,
10
- RequestMessage,
11
- ResponseMessage
12
- } from "./sip-message/index.js";
13
- import {
14
- branch,
15
- generateAuthorization,
16
- localKey,
17
- randomInt,
18
- uuid
19
- } from "./utils.js";
20
- class Softphone extends EventEmitter {
21
- sipInfo;
22
- client;
23
- codec;
24
- fakeDomain = `${uuid()}.invalid`;
25
- fakeEmail = `${uuid()}@${this.fakeDomain}`;
26
- intervalHandle;
27
- connected = false;
28
- constructor(sipInfo) {
29
- super();
30
- if (sipInfo.codec === void 0) {
31
- sipInfo.codec = "OPUS/16000";
32
- }
33
- this.codec = new Codec(sipInfo.codec);
34
- this.sipInfo = sipInfo;
35
- if (this.sipInfo.domain === void 0) {
36
- this.sipInfo.domain = "sip.ringcentral.com";
37
- }
38
- if (this.sipInfo.outboundProxy === void 0) {
39
- this.sipInfo.outboundProxy = "sip10.ringcentral.com:5096";
40
- }
41
- const tokens = this.sipInfo.outboundProxy.split(":");
42
- this.client = tls.connect(
43
- {
44
- host: tokens[0],
45
- port: parseInt(tokens[1], 10),
46
- rejectUnauthorized: !this.sipInfo.ignoreTlsCertErrors
47
- },
48
- () => {
49
- this.connected = true;
50
- }
51
- );
52
- let cache = "";
53
- this.client.on("data", (data) => {
54
- cache += data.toString("utf-8");
55
- if (!cache.endsWith("\r\n")) {
56
- return;
57
- }
58
- const tempMessages = cache.split("\r\nContent-Length: 0\r\n\r\n").filter((message) => message.trim() !== "");
59
- cache = "";
60
- for (let i = 0; i < tempMessages.length; i++) {
61
- if (!tempMessages[i].includes("Content-Length: ")) {
62
- tempMessages[i] = `${tempMessages[i]}\r
63
- Content-Length: 0`;
64
- }
65
- }
66
- for (const message of tempMessages) {
67
- this.emit("message", InboundMessage.fromString(message));
68
- }
69
- });
70
- }
71
- instanceId = uuid();
72
- registerCallId = uuid();
73
- async register() {
74
- if (!this.connected) {
75
- await waitFor({
76
- interval: 100,
77
- times: 100,
78
- condition: () => this.connected
79
- });
80
- if (!this.connected) {
81
- throw new Error("Failed to register: connect to TLS timeout");
82
- }
83
- }
84
- const sipRegister = async () => {
85
- const fromTag = uuid();
86
- const requestMessage = new RequestMessage(
87
- `REGISTER sip:${this.sipInfo.domain} SIP/2.0`,
88
- {
89
- Via: `SIP/2.0/TLS ${this.client.localAddress}:${this.client.localPort};rport;branch=${branch()};alias`,
90
- "Max-Forwards": "70",
91
- From: `<sip:${this.sipInfo.username}@${this.sipInfo.domain}>;tag=${fromTag}`,
92
- To: `<sip:${this.sipInfo.username}@${this.sipInfo.domain}>`,
93
- "Call-ID": this.registerCallId,
94
- Contact: `<sip:${this.sipInfo.username}@${this.client.localAddress}:${this.client.localPort};transport=TLS;ob>;reg-id=1;+sip.instance="<urn:uuid:${this.instanceId}>"`,
95
- Expires: 3600,
96
- Allow: "PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS"
97
- }
98
- );
99
- const inboundMessage = await this.send(requestMessage, true);
100
- if (inboundMessage.subject.startsWith("SIP/2.0 200 ")) {
101
- return;
102
- }
103
- const wwwAuth = inboundMessage.getHeader("Www-Authenticate");
104
- const nonce = wwwAuth.match(/, nonce="(.+?)"/)[1];
105
- const newMessage = requestMessage.fork();
106
- newMessage.headers.Authorization = generateAuthorization(
107
- this.sipInfo,
108
- nonce,
109
- "REGISTER"
110
- );
111
- const message = await this.send(newMessage, true);
112
- if (!message.subject.startsWith("SIP/2.0 200 ")) {
113
- throw new Error(`Failed to register: ${message.subject}`);
114
- }
115
- };
116
- await sipRegister();
117
- this.intervalHandle = setInterval(
118
- () => {
119
- sipRegister().catch((error) => {
120
- this.emit("registrationError", error);
121
- });
122
- },
123
- 30 * 1e3
124
- // refresh registration every 30 seconds
125
- );
126
- this.on("message", (inboundMessage) => {
127
- if (!inboundMessage.subject.startsWith("INVITE sip:")) {
128
- return;
129
- }
130
- const outboundMessage = new OutboundMessage("SIP/2.0 100 Trying", {
131
- Via: inboundMessage.headers.Via,
132
- "Call-ID": inboundMessage.getHeader("Call-ID"),
133
- From: inboundMessage.headers.From,
134
- To: inboundMessage.headers.To,
135
- CSeq: inboundMessage.headers.CSeq,
136
- "Content-Length": "0"
137
- });
138
- this.send(outboundMessage);
139
- this.emit("invite", inboundMessage);
140
- });
141
- }
142
- enableDebugMode() {
143
- this.on(
144
- "message",
145
- (message) => console.log(`Receiving...(${/* @__PURE__ */ new Date()})
146
- ${message.toString()}`)
147
- );
148
- const tlsWrite = this.client.write.bind(this.client);
149
- this.client.write = (message) => {
150
- console.log(`Sending...(${/* @__PURE__ */ new Date()})
151
- ${message}`);
152
- return tlsWrite(message);
153
- };
154
- }
155
- revoke() {
156
- clearInterval(this.intervalHandle);
157
- this.removeAllListeners();
158
- this.client.removeAllListeners();
159
- this.client.destroy();
160
- }
161
- send(message, waitForReply = false) {
162
- this.client.write(message.toString());
163
- if (!waitForReply) {
164
- return new Promise((resolve) => {
165
- resolve(void 0);
166
- });
167
- }
168
- return new Promise((resolve) => {
169
- const messageListerner = (inboundMessage) => {
170
- if (inboundMessage.headers.CSeq.trim().split(/\s+/)[0] !== message.headers.CSeq.trim().split(/\s+/)[0]) {
171
- return;
172
- }
173
- if (inboundMessage.subject.startsWith("SIP/2.0 100 ")) {
174
- return;
175
- }
176
- this.off("message", messageListerner);
177
- resolve(inboundMessage);
178
- };
179
- this.on("message", messageListerner);
180
- });
181
- }
182
- async answer(inviteMessage) {
183
- const inboundCallSession = new InboundCallSession(this, inviteMessage);
184
- await inboundCallSession.answer();
185
- return inboundCallSession;
186
- }
187
- // decline an inbound call
188
- async decline(inviteMessage) {
189
- const newMessage = new ResponseMessage(inviteMessage, 603);
190
- await this.send(newMessage);
191
- }
192
- async call(callee) {
193
- const offerSDP = `
194
- v=0
195
- o=- ${Date.now()} 0 IN IP4 ${this.client.localAddress}
196
- s=rc-softphone-ts
197
- c=IN IP4 ${this.client.localAddress}
198
- t=0 0
199
- m=audio ${randomInt()} RTP/SAVP ${this.codec.id} 101
200
- a=rtpmap:${this.codec.id} ${this.codec.name}
201
- a=rtpmap:101 telephone-event/8000
202
- a=fmtp:101 0-15
203
- a=sendrecv
204
- a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:${localKey}
205
- `.trim();
206
- const inviteMessage = new RequestMessage(
207
- `INVITE sip:${callee}@${this.sipInfo.domain} SIP/2.0`,
208
- {
209
- Via: `SIP/2.0/TLS ${this.client.localAddress}:${this.client.localPort};rport;branch=${branch()};alias`,
210
- "Max-Forwards": 70,
211
- From: `<sip:${this.sipInfo.username}@${this.sipInfo.domain}>;tag=${uuid()}`,
212
- To: `<sip:${callee}@sip.ringcentral.com>`,
213
- Contact: ` <sip:${this.sipInfo.username}@${this.client.localAddress}:${this.client.localPort};transport=TLS;ob>`,
214
- "Call-ID": uuid(),
215
- Route: `<sip:${this.sipInfo.outboundProxy};transport=tls;lr>`,
216
- Allow: `PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS`,
217
- Supported: `replaces, 100rel, timer, norefersub`,
218
- "Session-Expires": 1800,
219
- "Min-SE": 90,
220
- "Content-Type": "application/sdp"
221
- },
222
- offerSDP
223
- );
224
- const inboundMessage = await this.send(inviteMessage, true);
225
- const proxyAuthenticate = inboundMessage.getHeader("Proxy-Authenticate");
226
- const nonce = proxyAuthenticate.match(/, nonce="(.+?)"/)[1];
227
- const newMessage = inviteMessage.fork();
228
- newMessage.headers["Proxy-Authorization"] = generateAuthorization(
229
- this.sipInfo,
230
- nonce,
231
- "INVITE"
232
- );
233
- const progressMessage = await this.send(newMessage, true);
234
- const outboundCallSession = new OutboundCallSession(this, progressMessage);
235
- outboundCallSession.sdp = offerSDP;
236
- return outboundCallSession;
237
- }
238
- }
239
- var index_default = Softphone;
240
- export {
241
- index_default as default
242
- };
@@ -1,5 +0,0 @@
1
- import SipMessage from "../sip-message.js";
2
- declare class InboundMessage extends SipMessage {
3
- static fromString(str: string): SipMessage;
4
- }
5
- export default InboundMessage;
@@ -1,22 +0,0 @@
1
- import { uuid } from "../../utils.js";
2
- import SipMessage from "../sip-message.js";
3
- class InboundMessage extends SipMessage {
4
- static fromString(str) {
5
- const sipMessage = new SipMessage();
6
- const [init, ...body] = str.split("\r\n\r\n");
7
- sipMessage.body = body.join("\r\n\r\n");
8
- const [subject, ...headers] = init.split("\r\n");
9
- sipMessage.subject = subject;
10
- sipMessage.headers = Object.fromEntries(
11
- headers.map((line) => line.split(": "))
12
- );
13
- if (sipMessage.headers.To && !sipMessage.headers.To.includes(";tag=")) {
14
- sipMessage.headers.To += `;tag=${uuid()}`;
15
- }
16
- return sipMessage;
17
- }
18
- }
19
- var inbound_default = InboundMessage;
20
- export {
21
- inbound_default as default
22
- };
@@ -1,5 +0,0 @@
1
- export { default as InboundMessage } from "./inbound/index.js";
2
- export { default as OutboundMessage } from "./outbound/index.js";
3
- export { default as RequestMessage } from "./outbound/request.js";
4
- export { default as ResponseMessage } from "./outbound/response.js";
5
- export { default as SipMessage } from "./sip-message.js";
@@ -1,12 +0,0 @@
1
- import { default as default2 } from "./inbound/index.js";
2
- import { default as default3 } from "./outbound/index.js";
3
- import { default as default4 } from "./outbound/request.js";
4
- import { default as default5 } from "./outbound/response.js";
5
- import { default as default6 } from "./sip-message.js";
6
- export {
7
- default2 as InboundMessage,
8
- default3 as OutboundMessage,
9
- default4 as RequestMessage,
10
- default5 as ResponseMessage,
11
- default6 as SipMessage
12
- };
@@ -1,5 +0,0 @@
1
- import SipMessage from "../sip-message.js";
2
- declare class OutboundMessage extends SipMessage {
3
- constructor(subject?: string, headers?: {}, body?: string);
4
- }
5
- export default OutboundMessage;
@@ -1,12 +0,0 @@
1
- import SipMessage from "../sip-message.js";
2
- class OutboundMessage extends SipMessage {
3
- constructor(subject = "", headers = {}, body = "") {
4
- super(subject, headers, body);
5
- this.headers["Content-Length"] = this.body.length.toString();
6
- this.headers["User-Agent"] = "ringcentral-softphone-ts";
7
- }
8
- }
9
- var outbound_default = OutboundMessage;
10
- export {
11
- outbound_default as default
12
- };
@@ -1,7 +0,0 @@
1
- import OutboundMessage from "./index.js";
2
- declare class RequestMessage extends OutboundMessage {
3
- constructor(subject?: string, headers?: {}, body?: string);
4
- newCseq(): void;
5
- fork(): RequestMessage;
6
- }
7
- export default RequestMessage;