UNPKG

@koush/ring-client-api

Version:

Unofficial API for Ring doorbells, cameras, security alarm system and smart lighting

62 lines (61 loc) 2.78 kB
"use strict"; 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;