@koush/ring-client-api
Version:
Unofficial API for Ring doorbells, cameras, security alarm system and smart lighting
62 lines (61 loc) • 2.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseLiveCallSession = exports.createStunResponder = exports.sendStunBindingRequest = exports.isStunMessage = void 0;
const util_1 = require("./util");
const stun = require('stun');
const stunMagicCookie = 0x2112a442; // https://tools.ietf.org/html/rfc5389#section-6
function isStunMessage(message) {
return message.length > 8 && message.readInt32BE(4) === stunMagicCookie;
}
exports.isStunMessage = isStunMessage;
function sendStunBindingRequest({ rtpDescription, rtpSplitter, rtcpSplitter, localUfrag, type, }) {
const message = stun.createMessage(1), remoteDescription = rtpDescription[type], { address } = rtpDescription, { iceUFrag, icePwd, port, rtcpPort } = remoteDescription;
if (iceUFrag && icePwd && localUfrag) {
// Full ICE supported. Send as formal stun request
message.addUsername(iceUFrag + ':' + localUfrag);
message.addMessageIntegrity(icePwd);
stun
.request(`${address}:${port}`, {
socket: rtpSplitter.socket,
message,
})
.then(() => (0, util_1.logDebug)(`${type} stun complete`))
.catch((e) => {
(0, util_1.logError)(`${type} stun error`);
(0, util_1.logError)(e);
});
}
else {
// ICE not supported. Fire and forget the stun request for RTP and RTCP
const encodedMessage = stun.encode(message);
rtpSplitter.send(encodedMessage, { address, port }).catch(util_1.logError);
rtcpSplitter
.send(encodedMessage, { address, port: rtcpPort })
.catch(util_1.logError);
}
}
exports.sendStunBindingRequest = sendStunBindingRequest;
function createStunResponder(rtpSplitter) {
return rtpSplitter.addMessageHandler(({ message, info }) => {
if (!isStunMessage(message)) {
return null;
}
try {
const decodedMessage = stun.decode(message), response = stun.createMessage(stun.constants.STUN_BINDING_RESPONSE, decodedMessage.transactionId);
response.addXorAddress(info.address, info.port);
rtpSplitter.send(stun.encode(response), info).catch(util_1.logError);
}
catch (e) {
(0, util_1.logDebug)('Failed to Decode STUN Message');
(0, util_1.logDebug)(message.toString('hex'));
(0, util_1.logDebug)(e);
}
return null;
});
}
exports.createStunResponder = createStunResponder;
function parseLiveCallSession(sessionId) {
const encodedSession = sessionId.split('.')[1], buff = new Buffer(encodedSession, 'base64'), text = buff.toString('ascii');
return JSON.parse(text);
}
exports.parseLiveCallSession = parseLiveCallSession;