ringcentral-softphone 1.3.2 → 1.3.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/README.md +1 -1
- package/dist/call-session/inbound.cjs +93 -0
- package/dist/call-session/inbound.js +64 -0
- package/dist/call-session/index.cjs +274 -0
- package/dist/{esm/call-session → call-session}/index.d.ts +6 -4
- package/dist/call-session/index.js +248 -0
- package/dist/call-session/outbound.cjs +100 -0
- package/dist/call-session/outbound.js +71 -0
- package/dist/call-session/streamer.cjs +112 -0
- package/dist/{esm/call-session → call-session}/streamer.d.ts +2 -2
- package/dist/call-session/streamer.js +83 -0
- package/dist/codec.cjs +85 -0
- package/dist/codec.js +66 -0
- package/dist/dtmf.cjs +66 -0
- package/dist/dtmf.d.ts +7 -0
- package/dist/dtmf.js +47 -0
- package/dist/index.cjs +260 -0
- package/dist/{cjs/index.d.ts → index.d.ts} +3 -3
- package/dist/index.js +242 -0
- package/dist/sip-message/inbound/index.cjs +51 -0
- package/dist/sip-message/inbound/index.js +22 -0
- package/dist/sip-message/index.cjs +49 -0
- package/dist/sip-message/index.js +12 -0
- package/dist/sip-message/outbound/index.cjs +41 -0
- package/dist/sip-message/outbound/index.js +12 -0
- package/dist/sip-message/outbound/request.cjs +62 -0
- package/dist/sip-message/outbound/request.js +33 -0
- package/dist/sip-message/outbound/response.cjs +55 -0
- package/dist/sip-message/outbound/response.js +26 -0
- package/dist/sip-message/response-codes.cjs +102 -0
- package/dist/sip-message/response-codes.js +83 -0
- package/dist/sip-message/sip-message.cjs +53 -0
- package/dist/sip-message/sip-message.js +34 -0
- package/dist/types.cjs +15 -0
- package/dist/types.js +0 -0
- package/dist/utils.cjs +80 -0
- package/dist/{cjs/utils.d.ts → utils.d.ts} +2 -2
- package/dist/utils.js +41 -0
- package/package.json +19 -13
- package/dist/cjs/call-session/inbound.js +0 -57
- package/dist/cjs/call-session/index.d.ts +0 -44
- package/dist/cjs/call-session/index.js +0 -239
- package/dist/cjs/call-session/outbound.js +0 -66
- package/dist/cjs/call-session/streamer.d.ts +0 -17
- package/dist/cjs/call-session/streamer.js +0 -76
- package/dist/cjs/codec.js +0 -65
- package/dist/cjs/dtmf.d.ts +0 -8
- package/dist/cjs/dtmf.js +0 -45
- package/dist/cjs/index.js +0 -209
- package/dist/cjs/sip-message/inbound/index.js +0 -22
- package/dist/cjs/sip-message/index.d.ts +0 -5
- package/dist/cjs/sip-message/index.js +0 -16
- package/dist/cjs/sip-message/outbound/index.js +0 -14
- package/dist/cjs/sip-message/outbound/request.js +0 -28
- package/dist/cjs/sip-message/outbound/response.js +0 -25
- package/dist/cjs/sip-message/response-codes.js +0 -83
- package/dist/cjs/sip-message/sip-message.js +0 -34
- package/dist/cjs/types.js +0 -2
- package/dist/cjs/utils.js +0 -40
- package/dist/esm/call-session/inbound.d.ts +0 -8
- package/dist/esm/call-session/inbound.js +0 -52
- package/dist/esm/call-session/index.js +0 -234
- package/dist/esm/call-session/outbound.d.ts +0 -11
- package/dist/esm/call-session/outbound.js +0 -61
- package/dist/esm/call-session/streamer.js +0 -71
- package/dist/esm/codec.d.ts +0 -15
- package/dist/esm/codec.js +0 -63
- package/dist/esm/dtmf.d.ts +0 -8
- package/dist/esm/dtmf.js +0 -43
- package/dist/esm/index.d.ts +0 -28
- package/dist/esm/index.js +0 -204
- package/dist/esm/sip-message/inbound/index.d.ts +0 -5
- package/dist/esm/sip-message/inbound/index.js +0 -17
- package/dist/esm/sip-message/index.js +0 -5
- package/dist/esm/sip-message/outbound/index.d.ts +0 -5
- package/dist/esm/sip-message/outbound/index.js +0 -9
- package/dist/esm/sip-message/outbound/request.d.ts +0 -7
- package/dist/esm/sip-message/outbound/request.js +0 -23
- package/dist/esm/sip-message/outbound/response.d.ts +0 -6
- package/dist/esm/sip-message/outbound/response.js +0 -20
- package/dist/esm/sip-message/response-codes.d.ts +0 -4
- package/dist/esm/sip-message/response-codes.js +0 -81
- package/dist/esm/sip-message/sip-message.d.ts +0 -11
- package/dist/esm/sip-message/sip-message.js +0 -32
- package/dist/esm/types.d.ts +0 -9
- package/dist/esm/types.js +0 -1
- package/dist/esm/utils.d.ts +0 -8
- package/dist/esm/utils.js +0 -28
- package/dist/{cjs/call-session → call-session}/inbound.d.ts +2 -2
- package/dist/{cjs/call-session → call-session}/outbound.d.ts +2 -2
- package/dist/{cjs/codec.d.ts → codec.d.ts} +0 -0
- package/dist/{cjs/sip-message → sip-message}/inbound/index.d.ts +0 -0
- package/dist/{esm/sip-message → sip-message}/index.d.ts +2 -2
- package/dist/{cjs/sip-message → sip-message}/outbound/index.d.ts +0 -0
- package/dist/{cjs/sip-message → sip-message}/outbound/request.d.ts +0 -0
- package/dist/{cjs/sip-message → sip-message}/outbound/response.d.ts +1 -1
- /package/dist/{cjs/sip-message → sip-message}/response-codes.d.ts +0 -0
- /package/dist/{cjs/sip-message → sip-message}/sip-message.d.ts +0 -0
- /package/dist/{cjs/types.d.ts → types.d.ts} +0 -0
package/dist/esm/index.js
DELETED
|
@@ -1,204 +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 { InboundMessage, OutboundMessage, RequestMessage, ResponseMessage, } from "./sip-message/index.js";
|
|
7
|
-
import { branch, generateAuthorization, localKey, randomInt, uuid, } from "./utils.js";
|
|
8
|
-
import Codec from "./codec.js";
|
|
9
|
-
class Softphone extends EventEmitter {
|
|
10
|
-
sipInfo;
|
|
11
|
-
client;
|
|
12
|
-
codec;
|
|
13
|
-
fakeDomain = uuid() + ".invalid";
|
|
14
|
-
fakeEmail = uuid() + "@" + this.fakeDomain;
|
|
15
|
-
intervalHandle;
|
|
16
|
-
connected = false;
|
|
17
|
-
constructor(sipInfo) {
|
|
18
|
-
super();
|
|
19
|
-
if (sipInfo.codec === undefined) {
|
|
20
|
-
sipInfo.codec = "OPUS/16000";
|
|
21
|
-
}
|
|
22
|
-
this.codec = new Codec(sipInfo.codec);
|
|
23
|
-
this.sipInfo = sipInfo;
|
|
24
|
-
if (this.sipInfo.domain === undefined) {
|
|
25
|
-
this.sipInfo.domain = "sip.ringcentral.com";
|
|
26
|
-
}
|
|
27
|
-
if (this.sipInfo.outboundProxy === undefined) {
|
|
28
|
-
this.sipInfo.outboundProxy = "sip10.ringcentral.com:5096";
|
|
29
|
-
}
|
|
30
|
-
const tokens = this.sipInfo.outboundProxy.split(":");
|
|
31
|
-
this.client = tls.connect({
|
|
32
|
-
host: tokens[0],
|
|
33
|
-
port: parseInt(tokens[1], 10),
|
|
34
|
-
rejectUnauthorized: !this.sipInfo.ignoreTlsCertErrors,
|
|
35
|
-
}, () => {
|
|
36
|
-
this.connected = true;
|
|
37
|
-
});
|
|
38
|
-
let cache = "";
|
|
39
|
-
this.client.on("data", (data) => {
|
|
40
|
-
cache += data.toString("utf-8");
|
|
41
|
-
if (!cache.endsWith("\r\n")) {
|
|
42
|
-
return; // haven't received a complete message yet
|
|
43
|
-
}
|
|
44
|
-
// received two empty body messages
|
|
45
|
-
const tempMessages = cache
|
|
46
|
-
.split("\r\nContent-Length: 0\r\n\r\n")
|
|
47
|
-
.filter((message) => message.trim() !== "");
|
|
48
|
-
cache = "";
|
|
49
|
-
for (let i = 0; i < tempMessages.length; i++) {
|
|
50
|
-
if (!tempMessages[i].includes("Content-Length: ")) {
|
|
51
|
-
tempMessages[i] = tempMessages[i] + "\r\nContent-Length: 0";
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
for (const message of tempMessages) {
|
|
55
|
-
this.emit("message", InboundMessage.fromString(message));
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
instanceId = uuid();
|
|
60
|
-
registerCallId = uuid();
|
|
61
|
-
async register() {
|
|
62
|
-
if (!this.connected) {
|
|
63
|
-
await waitFor({
|
|
64
|
-
interval: 100,
|
|
65
|
-
times: 100,
|
|
66
|
-
condition: () => this.connected,
|
|
67
|
-
});
|
|
68
|
-
if (!this.connected) {
|
|
69
|
-
throw new Error("Failed to register: connect to TLS timeout");
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
const sipRegister = async () => {
|
|
73
|
-
const fromTag = uuid();
|
|
74
|
-
const requestMessage = new RequestMessage(`REGISTER sip:${this.sipInfo.domain} SIP/2.0`, {
|
|
75
|
-
Via: `SIP/2.0/TLS ${this.client.localAddress}:${this.client.localPort};rport;branch=${branch()};alias`,
|
|
76
|
-
"Max-Forwards": "70",
|
|
77
|
-
From: `<sip:${this.sipInfo.username}@${this.sipInfo.domain}>;tag=${fromTag}`,
|
|
78
|
-
To: `<sip:${this.sipInfo.username}@${this.sipInfo.domain}>`,
|
|
79
|
-
"Call-ID": this.registerCallId,
|
|
80
|
-
Contact: `<sip:${this.sipInfo.username}@${this.client.localAddress}:${this.client.localPort};transport=TLS;ob>;reg-id=1;+sip.instance="<urn:uuid:${this.instanceId}>"`,
|
|
81
|
-
Expires: 3600,
|
|
82
|
-
Allow: "PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS",
|
|
83
|
-
});
|
|
84
|
-
const inboundMessage = await this.send(requestMessage, true);
|
|
85
|
-
if (inboundMessage.subject.startsWith("SIP/2.0 200 ")) {
|
|
86
|
-
// sometimes the server will return 200 OK directly
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const wwwAuth = inboundMessage.getHeader("Www-Authenticate");
|
|
90
|
-
const nonce = wwwAuth.match(/, nonce="(.+?)"/)[1];
|
|
91
|
-
const newMessage = requestMessage.fork();
|
|
92
|
-
newMessage.headers.Authorization = generateAuthorization(this.sipInfo, nonce, "REGISTER");
|
|
93
|
-
const message = await this.send(newMessage, true);
|
|
94
|
-
if (!message.subject.startsWith("SIP/2.0 200 ")) {
|
|
95
|
-
throw new Error("Failed to register: " + message.subject);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
await sipRegister();
|
|
99
|
-
this.intervalHandle = setInterval(() => {
|
|
100
|
-
sipRegister();
|
|
101
|
-
}, 30 * 1000);
|
|
102
|
-
this.on("message", (inboundMessage) => {
|
|
103
|
-
if (!inboundMessage.subject.startsWith("INVITE sip:")) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
const outboundMessage = new OutboundMessage("SIP/2.0 100 Trying", {
|
|
107
|
-
Via: inboundMessage.headers.Via,
|
|
108
|
-
"Call-ID": inboundMessage.getHeader("Call-ID"),
|
|
109
|
-
From: inboundMessage.headers.From,
|
|
110
|
-
To: inboundMessage.headers.To,
|
|
111
|
-
CSeq: inboundMessage.headers.CSeq,
|
|
112
|
-
"Content-Length": "0",
|
|
113
|
-
});
|
|
114
|
-
this.send(outboundMessage);
|
|
115
|
-
this.emit("invite", inboundMessage);
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
enableDebugMode() {
|
|
119
|
-
this.on("message", (message) => console.log(`Receiving...(${new Date()})\n` + message.toString()));
|
|
120
|
-
const tlsWrite = this.client.write.bind(this.client);
|
|
121
|
-
this.client.write = (message) => {
|
|
122
|
-
console.log(`Sending...(${new Date()})\n` + message);
|
|
123
|
-
return tlsWrite(message);
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
revoke() {
|
|
127
|
-
clearInterval(this.intervalHandle);
|
|
128
|
-
this.removeAllListeners();
|
|
129
|
-
this.client.removeAllListeners();
|
|
130
|
-
this.client.destroy();
|
|
131
|
-
}
|
|
132
|
-
send(message, waitForReply = false) {
|
|
133
|
-
this.client.write(message.toString());
|
|
134
|
-
if (!waitForReply) {
|
|
135
|
-
return new Promise((resolve) => {
|
|
136
|
-
resolve(undefined);
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
return new Promise((resolve) => {
|
|
140
|
-
const messageListerner = (inboundMessage) => {
|
|
141
|
-
// "12563 INVITE" vs "12563 ACK"
|
|
142
|
-
if (inboundMessage.headers.CSeq.trim().split(/\s+/)[0] !==
|
|
143
|
-
message.headers.CSeq.trim().split(/\s+/)[0]) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
if (inboundMessage.subject.startsWith("SIP/2.0 100 ")) {
|
|
147
|
-
return; // ignore
|
|
148
|
-
}
|
|
149
|
-
this.off("message", messageListerner);
|
|
150
|
-
resolve(inboundMessage);
|
|
151
|
-
};
|
|
152
|
-
this.on("message", messageListerner);
|
|
153
|
-
});
|
|
154
|
-
}
|
|
155
|
-
async answer(inviteMessage) {
|
|
156
|
-
const inboundCallSession = new InboundCallSession(this, inviteMessage);
|
|
157
|
-
await inboundCallSession.answer();
|
|
158
|
-
return inboundCallSession;
|
|
159
|
-
}
|
|
160
|
-
// decline an inbound call
|
|
161
|
-
async decline(inviteMessage) {
|
|
162
|
-
const newMessage = new ResponseMessage(inviteMessage, 603);
|
|
163
|
-
await this.send(newMessage);
|
|
164
|
-
}
|
|
165
|
-
async call(callee) {
|
|
166
|
-
const offerSDP = `
|
|
167
|
-
v=0
|
|
168
|
-
o=- ${Date.now()} 0 IN IP4 ${this.client.localAddress}
|
|
169
|
-
s=rc-softphone-ts
|
|
170
|
-
c=IN IP4 ${this.client.localAddress}
|
|
171
|
-
t=0 0
|
|
172
|
-
m=audio ${randomInt()} RTP/SAVP ${this.codec.id} 101
|
|
173
|
-
a=rtpmap:${this.codec.id} ${this.codec.name}
|
|
174
|
-
a=rtpmap:101 telephone-event/8000
|
|
175
|
-
a=fmtp:101 0-15
|
|
176
|
-
a=sendrecv
|
|
177
|
-
a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:${localKey}
|
|
178
|
-
`.trim();
|
|
179
|
-
const inviteMessage = new RequestMessage(`INVITE sip:${callee}@${this.sipInfo.domain} SIP/2.0`, {
|
|
180
|
-
Via: `SIP/2.0/TLS ${this.client.localAddress}:${this.client.localPort};rport;branch=${branch()};alias`,
|
|
181
|
-
"Max-Forwards": 70,
|
|
182
|
-
From: `<sip:${this.sipInfo.username}@${this.sipInfo.domain}>;tag=${uuid()}`,
|
|
183
|
-
To: `<sip:${callee}@sip.ringcentral.com>`,
|
|
184
|
-
Contact: ` <sip:${this.sipInfo.username}@${this.client.localAddress}:${this.client.localPort};transport=TLS;ob>`,
|
|
185
|
-
"Call-ID": uuid(),
|
|
186
|
-
Route: `<sip:${this.sipInfo.outboundProxy};transport=tls;lr>`,
|
|
187
|
-
Allow: `PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS`,
|
|
188
|
-
Supported: `replaces, 100rel, timer, norefersub`,
|
|
189
|
-
"Session-Expires": 1800,
|
|
190
|
-
"Min-SE": 90,
|
|
191
|
-
"Content-Type": "application/sdp",
|
|
192
|
-
}, offerSDP);
|
|
193
|
-
const inboundMessage = await this.send(inviteMessage, true);
|
|
194
|
-
const proxyAuthenticate = inboundMessage.getHeader("Proxy-Authenticate");
|
|
195
|
-
const nonce = proxyAuthenticate.match(/, nonce="(.+?)"/)[1];
|
|
196
|
-
const newMessage = inviteMessage.fork();
|
|
197
|
-
newMessage.headers["Proxy-Authorization"] = generateAuthorization(this.sipInfo, nonce, "INVITE");
|
|
198
|
-
const progressMessage = await this.send(newMessage, true);
|
|
199
|
-
const outboundCallSession = new OutboundCallSession(this, progressMessage);
|
|
200
|
-
outboundCallSession.sdp = offerSDP;
|
|
201
|
-
return outboundCallSession;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
export default Softphone;
|
|
@@ -1,17 +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(headers.map((line) => line.split(": ")));
|
|
11
|
-
if (sipMessage.headers.To && !sipMessage.headers.To.includes(";tag=")) {
|
|
12
|
-
sipMessage.headers.To += ";tag=" + uuid(); // generate local tag
|
|
13
|
-
}
|
|
14
|
-
return sipMessage;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export default InboundMessage;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { default as RequestMessage } from "./outbound/request.js";
|
|
2
|
-
export { default as ResponseMessage } from "./outbound/response.js";
|
|
3
|
-
export { default as OutboundMessage } from "./outbound/index.js";
|
|
4
|
-
export { default as InboundMessage } from "./inbound/index.js";
|
|
5
|
-
export { default as SipMessage } from "./sip-message.js";
|
|
@@ -1,9 +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
|
-
export default OutboundMessage;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import OutboundMessage from "./index.js";
|
|
2
|
-
import { branch } from "../../utils.js";
|
|
3
|
-
let cseq = Math.floor(Math.random() * 10000);
|
|
4
|
-
class RequestMessage extends OutboundMessage {
|
|
5
|
-
constructor(subject = "", headers = {}, body = "") {
|
|
6
|
-
super(subject, headers, body);
|
|
7
|
-
if (this.headers.CSeq === undefined) {
|
|
8
|
-
this.newCseq();
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
newCseq() {
|
|
12
|
-
this.headers.CSeq = `${++cseq} ${this.subject.split(" ")[0]}`;
|
|
13
|
-
}
|
|
14
|
-
fork() {
|
|
15
|
-
const newMessage = new RequestMessage(this.subject, { ...this.headers }, this.body);
|
|
16
|
-
newMessage.newCseq();
|
|
17
|
-
if (newMessage.headers.Via) {
|
|
18
|
-
newMessage.headers.Via = newMessage.headers.Via.replace(/;branch=.+?$/, `;branch=${branch()}`);
|
|
19
|
-
}
|
|
20
|
-
return newMessage;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export default RequestMessage;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import OutboundMessage from "./index.js";
|
|
2
|
-
import type InboundMessage from "../inbound/index.js";
|
|
3
|
-
declare class ResponseMessage extends OutboundMessage {
|
|
4
|
-
constructor(inboundMessage: InboundMessage, responseCode: number, headers?: {}, body?: string);
|
|
5
|
-
}
|
|
6
|
-
export default ResponseMessage;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import OutboundMessage from "./index.js";
|
|
2
|
-
import responseCodes from "../response-codes.js";
|
|
3
|
-
class ResponseMessage extends OutboundMessage {
|
|
4
|
-
constructor(inboundMessage, responseCode, headers = {}, body = "") {
|
|
5
|
-
super(undefined, { ...headers }, body);
|
|
6
|
-
this.subject = `SIP/2.0 ${responseCode} ${responseCodes[responseCode]}`;
|
|
7
|
-
const requiredKeys = new Set(["via", "from", "to", "call-id", "cseq"]);
|
|
8
|
-
const allKeys = Object.keys(inboundMessage.headers).reduce((acc, key) => {
|
|
9
|
-
acc[key.toLowerCase()] = key;
|
|
10
|
-
return acc;
|
|
11
|
-
}, {});
|
|
12
|
-
for (const key of requiredKeys) {
|
|
13
|
-
if (allKeys[key]) {
|
|
14
|
-
const originalKey = allKeys[key];
|
|
15
|
-
this.headers[originalKey] = inboundMessage.headers[originalKey];
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
export default ResponseMessage;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
// Ref: https://en.wikipedia.org/wiki/List_of_SIP_response_codes'
|
|
2
|
-
const responseCodes = {
|
|
3
|
-
100: "Trying",
|
|
4
|
-
180: "Ringing",
|
|
5
|
-
181: "Call is Being Forwarded",
|
|
6
|
-
182: "Queued",
|
|
7
|
-
183: "Session Progress",
|
|
8
|
-
199: "Early Dialog Terminated",
|
|
9
|
-
200: "OK",
|
|
10
|
-
202: "Accepted",
|
|
11
|
-
204: "No Notification",
|
|
12
|
-
300: "Multiple Choices",
|
|
13
|
-
301: "Moved Permanently",
|
|
14
|
-
302: "Moved Temporarily",
|
|
15
|
-
305: "Use Proxy",
|
|
16
|
-
380: "Alternative Service",
|
|
17
|
-
400: "Bad Request",
|
|
18
|
-
401: "Unauthorized",
|
|
19
|
-
402: "Payment Required",
|
|
20
|
-
403: "Forbidden",
|
|
21
|
-
404: "Not Found",
|
|
22
|
-
405: "Method Not Allowed",
|
|
23
|
-
406: "Not Acceptable",
|
|
24
|
-
407: "Proxy Authentication Required",
|
|
25
|
-
408: "Request Timeout",
|
|
26
|
-
409: "Conflict",
|
|
27
|
-
410: "Gone",
|
|
28
|
-
411: "Length Required",
|
|
29
|
-
412: "Conditional Request Failed",
|
|
30
|
-
413: "Request Entity Too Large",
|
|
31
|
-
414: "Request-URI Too Long",
|
|
32
|
-
415: "Unsupported Media Type",
|
|
33
|
-
416: "Unsupported URI Scheme",
|
|
34
|
-
417: "Unknown Resource-Priority",
|
|
35
|
-
420: "Bad Extension",
|
|
36
|
-
421: "Extension Required",
|
|
37
|
-
422: "Session Interval Too Small",
|
|
38
|
-
423: "Interval Too Brief",
|
|
39
|
-
424: "Bad Location Information",
|
|
40
|
-
425: "Bad Alert Message",
|
|
41
|
-
428: "Use Identity Header",
|
|
42
|
-
429: "Provide Referrer Identity",
|
|
43
|
-
430: "Flow Failed",
|
|
44
|
-
433: "Anonymity Disallowed",
|
|
45
|
-
436: "Bad Identity-Info",
|
|
46
|
-
437: "Unsupported Certificate",
|
|
47
|
-
438: "Invalid Identity Header",
|
|
48
|
-
439: "First Hop Lacks Outbound Support",
|
|
49
|
-
440: "Max-Breadth Exceeded",
|
|
50
|
-
469: "Bad Info Package",
|
|
51
|
-
470: "Consent Needed",
|
|
52
|
-
480: "Temporarily Unavailable",
|
|
53
|
-
481: "Call/Transaction Does Not Exist",
|
|
54
|
-
482: "Loop Detected",
|
|
55
|
-
483: "Too Many Hops",
|
|
56
|
-
484: "Address Incomplete",
|
|
57
|
-
485: "Ambiguous",
|
|
58
|
-
486: "Busy Here",
|
|
59
|
-
487: "Request Terminated",
|
|
60
|
-
488: "Not Acceptable Here",
|
|
61
|
-
489: "Bad Event",
|
|
62
|
-
491: "Request Pending",
|
|
63
|
-
493: "Undecipherable",
|
|
64
|
-
494: "Security Agreement Required",
|
|
65
|
-
500: "Server Internal Error",
|
|
66
|
-
501: "Not Implemented",
|
|
67
|
-
502: "Bad Gateway",
|
|
68
|
-
503: "Service Unavailable",
|
|
69
|
-
504: "Server Time-out",
|
|
70
|
-
505: "Version Not Supported",
|
|
71
|
-
513: "Message Too Large",
|
|
72
|
-
555: "Push Notification Service Not Supported",
|
|
73
|
-
580: "Precondition Failure",
|
|
74
|
-
600: "Busy Everywhere",
|
|
75
|
-
603: "Decline",
|
|
76
|
-
604: "Does Not Exist Anywhere",
|
|
77
|
-
606: "Not Acceptable",
|
|
78
|
-
607: "Unwanted",
|
|
79
|
-
608: "Rejected",
|
|
80
|
-
};
|
|
81
|
-
export default responseCodes;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
declare class SipMessage {
|
|
2
|
-
subject: string;
|
|
3
|
-
headers: {
|
|
4
|
-
[key: string]: string;
|
|
5
|
-
};
|
|
6
|
-
body: string;
|
|
7
|
-
constructor(subject?: string, headers?: {}, body?: string);
|
|
8
|
-
toString(): string;
|
|
9
|
-
getHeader(key: string): string | undefined;
|
|
10
|
-
}
|
|
11
|
-
export default SipMessage;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
class SipMessage {
|
|
2
|
-
subject;
|
|
3
|
-
headers;
|
|
4
|
-
body;
|
|
5
|
-
constructor(subject = "", headers = {}, body = "") {
|
|
6
|
-
this.subject = subject;
|
|
7
|
-
this.headers = headers;
|
|
8
|
-
this.body = body
|
|
9
|
-
.trim()
|
|
10
|
-
.split(/[\r\n]+/)
|
|
11
|
-
.join("\r\n");
|
|
12
|
-
if (this.body.length > 0) {
|
|
13
|
-
this.body += "\r\n";
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
toString() {
|
|
17
|
-
const r = [
|
|
18
|
-
this.subject,
|
|
19
|
-
...Object.keys(this.headers).map((key) => `${key}: ${this.headers[key]}`),
|
|
20
|
-
"",
|
|
21
|
-
this.body,
|
|
22
|
-
].join("\r\n");
|
|
23
|
-
return r;
|
|
24
|
-
}
|
|
25
|
-
getHeader(key) {
|
|
26
|
-
const foundKey = Object.keys(this.headers).find((k) => k.toLowerCase() === key.toLowerCase());
|
|
27
|
-
if (foundKey) {
|
|
28
|
-
return this.headers[foundKey];
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export default SipMessage;
|
package/dist/esm/types.d.ts
DELETED
package/dist/esm/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/esm/utils.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { SoftPhoneOptions } from "./types.js";
|
|
2
|
-
export declare const generateAuthorization: (sipInfo: SoftPhoneOptions, nonce: string, method: "REGISTER" | "INVITE") => string;
|
|
3
|
-
export declare const uuid: () => `${string}-${string}-${string}-${string}-${string}`;
|
|
4
|
-
export declare const branch: () => string;
|
|
5
|
-
export declare const randomInt: () => number;
|
|
6
|
-
export declare const withoutTag: (s: string) => string;
|
|
7
|
-
export declare const extractAddress: (s: string) => string;
|
|
8
|
-
export declare const localKey: string;
|
package/dist/esm/utils.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
const md5 = (s) => crypto.createHash("md5").update(s).digest("hex");
|
|
3
|
-
const generateResponse = (sipInfo, endpoint, nonce) => {
|
|
4
|
-
const ha1 = md5(`${sipInfo.authorizationId}:${sipInfo.domain}:${sipInfo.password}`);
|
|
5
|
-
const ha2 = md5(endpoint);
|
|
6
|
-
const response = md5(`${ha1}:${nonce}:${ha2}`);
|
|
7
|
-
return response;
|
|
8
|
-
};
|
|
9
|
-
export const generateAuthorization = (sipInfo, nonce, method) => {
|
|
10
|
-
const authObj = {
|
|
11
|
-
"Digest algorithm": "MD5",
|
|
12
|
-
username: sipInfo.authorizationId,
|
|
13
|
-
realm: sipInfo.domain,
|
|
14
|
-
nonce,
|
|
15
|
-
uri: `sip:${sipInfo.domain}`,
|
|
16
|
-
response: generateResponse(sipInfo, `${method}:sip:${sipInfo.domain}`, nonce),
|
|
17
|
-
};
|
|
18
|
-
return Object.keys(authObj)
|
|
19
|
-
.map((key) => `${key}="${authObj[key]}"`)
|
|
20
|
-
.join(", ");
|
|
21
|
-
};
|
|
22
|
-
export const uuid = () => crypto.randomUUID();
|
|
23
|
-
export const branch = () => "z9hG4bK-" + uuid();
|
|
24
|
-
export const randomInt = () => Math.floor(Math.random() * (65535 - 1024 + 1)) + 1024;
|
|
25
|
-
export const withoutTag = (s) => s.replace(/;tag=.*$/, "");
|
|
26
|
-
export const extractAddress = (s) => s.match(/<(sip:.+?)>/)?.[1];
|
|
27
|
-
const keyAndSalt = crypto.randomBytes(30);
|
|
28
|
-
export const localKey = keyAndSalt.toString("base64").replace(/=+$/, "");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import CallSession from "./index.js";
|
|
2
|
-
import { type InboundMessage } from "../sip-message/index.js";
|
|
3
1
|
import type Softphone from "../index.js";
|
|
2
|
+
import { type InboundMessage } from "../sip-message/index.js";
|
|
3
|
+
import CallSession from "./index.js";
|
|
4
4
|
declare class InboundCallSession extends CallSession {
|
|
5
5
|
constructor(softphone: Softphone, inviteMessage: InboundMessage);
|
|
6
6
|
answer(): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import CallSession from "./index.js";
|
|
2
|
-
import { type InboundMessage } from "../sip-message/index.js";
|
|
3
1
|
import type Softphone from "../index.js";
|
|
2
|
+
import { type InboundMessage } from "../sip-message/index.js";
|
|
3
|
+
import CallSession from "./index.js";
|
|
4
4
|
declare class OutboundCallSession extends CallSession {
|
|
5
5
|
constructor(softphone: Softphone, answerMessage: InboundMessage);
|
|
6
6
|
init(): void;
|
|
File without changes
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
export { default as InboundMessage } from "./inbound/index.js";
|
|
2
|
+
export { default as OutboundMessage } from "./outbound/index.js";
|
|
1
3
|
export { default as RequestMessage } from "./outbound/request.js";
|
|
2
4
|
export { default as ResponseMessage } from "./outbound/response.js";
|
|
3
|
-
export { default as OutboundMessage } from "./outbound/index.js";
|
|
4
|
-
export { default as InboundMessage } from "./inbound/index.js";
|
|
5
5
|
export { default as SipMessage } from "./sip-message.js";
|
|
File without changes
|
|
File without changes
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import OutboundMessage from "./index.js";
|
|
2
1
|
import type InboundMessage from "../inbound/index.js";
|
|
2
|
+
import OutboundMessage from "./index.js";
|
|
3
3
|
declare class ResponseMessage extends OutboundMessage {
|
|
4
4
|
constructor(inboundMessage: InboundMessage, responseCode: number, headers?: {}, body?: string);
|
|
5
5
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|