{"version":3,"file":"inbound.mjs","names":[],"sources":["../../src/call-session/inbound.ts"],"sourcesContent":["import type Softphone from \"../index.js\";\nimport { type InboundMessage, OutboundMessage } from \"../sip-message/index.js\";\nimport { localKey } from \"../utils.js\";\nimport CallSession from \"./index.js\";\n\nclass InboundCallSession extends CallSession {\n  public constructor(softphone: Softphone, inviteMessage: InboundMessage) {\n    super(softphone, inviteMessage);\n    this.localPeer = inviteMessage.headers.To;\n    this.remotePeer = inviteMessage.headers.From;\n    // inbound call from call queue, invite message may not have body\n    if (inviteMessage.body.length > 0) {\n      this.remoteKey = inviteMessage.body.match(\n        /AES_CM_128_HMAC_SHA1_80 inline:([\\w+/]+)/,\n      )![1];\n    }\n  }\n\n  public async answer() {\n    const { socket, port } = await CallSession.createBoundSocket();\n    this.socket = socket;\n    const answerSDP = `\nv=0\no=- ${Date.now()} 0 IN IP4 ${this.softphone.client.localAddress}\ns=rc-softphone-ts\nc=IN IP4 ${this.softphone.client.localAddress}\nt=0 0\nm=audio ${port} RTP/SAVP ${this.softphone.codec.id} 101\na=rtpmap:${this.softphone.codec.id} ${this.softphone.codec.name}\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-15\na=sendrecv\na=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:${localKey}\n`.trim();\n    this.sdp = answerSDP;\n    const newMessage = new OutboundMessage(\n      \"SIP/2.0 200 OK\",\n      {\n        Via: this.sipMessage.headers.Via,\n        \"Call-ID\": this.sipMessage.getHeader(\"Call-ID\"),\n        From: this.sipMessage.headers.From,\n        To: this.sipMessage.headers.To,\n        CSeq: this.sipMessage.headers.CSeq,\n        Contact: `<sip:${this.softphone.sipInfo.username}@${this.softphone.client.localAddress}:${this.softphone.client.localPort};transport=TLS;ob>`,\n        Allow:\n          \"PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS\",\n        Supported: \"replaces, 100rel, timer, norefersub\",\n        \"Session-Expires\": \"14400;refresher=uac\",\n        Require: \"timer\",\n        \"Content-Type\": \"application/sdp\",\n      },\n      answerSDP,\n    );\n    const ackMessage = await this.softphone.send(newMessage, true);\n\n    // for inbound call from call queue, ack message may HAVE body (while invite message has no body)\n    if (ackMessage.body.length > 0) {\n      this.remoteIP = ackMessage.body.match(/c=IN IP4 ([\\d.]+)/)![1];\n      this.remotePort = parseInt(\n        ackMessage.body.match(/m=audio (\\d+) /)![1],\n        10,\n      );\n      this.remoteKey = ackMessage.body.match(\n        /AES_CM_128_HMAC_SHA1_80 inline:([\\w+/]+)/,\n      )![1];\n    }\n\n    this.startLocalServices();\n  }\n}\n\nexport default InboundCallSession;\n"],"mappings":";;;;;AAKA,IAAM,qBAAN,cAAiC,YAAY;CAC3C,YAAmB,WAAsB,eAA+B;EACtE,MAAM,WAAW,cAAc;EAC/B,KAAK,YAAY,cAAc,QAAQ;EACvC,KAAK,aAAa,cAAc,QAAQ;EAExC,IAAI,cAAc,KAAK,SAAS,GAC9B,KAAK,YAAY,cAAc,KAAK,MAClC,2CACD,CAAE;;CAIP,MAAa,SAAS;EACpB,MAAM,EAAE,QAAQ,SAAS,MAAM,YAAY,mBAAmB;EAC9D,KAAK,SAAS;EACd,MAAM,YAAY;;MAEhB,KAAK,KAAK,CAAC,YAAY,KAAK,UAAU,OAAO,aAAa;;WAErD,KAAK,UAAU,OAAO,aAAa;;UAEpC,KAAK,YAAY,KAAK,UAAU,MAAM,GAAG;WACxC,KAAK,UAAU,MAAM,GAAG,GAAG,KAAK,UAAU,MAAM,KAAK;;;;4CAIpB,SAAS;EACnD,MAAM;EACJ,KAAK,MAAM;EACX,MAAM,aAAa,IAAI,gBACrB,kBACA;GACE,KAAK,KAAK,WAAW,QAAQ;GAC7B,WAAW,KAAK,WAAW,UAAU,UAAU;GAC/C,MAAM,KAAK,WAAW,QAAQ;GAC9B,IAAI,KAAK,WAAW,QAAQ;GAC5B,MAAM,KAAK,WAAW,QAAQ;GAC9B,SAAS,QAAQ,KAAK,UAAU,QAAQ,SAAS,GAAG,KAAK,UAAU,OAAO,aAAa,GAAG,KAAK,UAAU,OAAO,UAAU;GAC1H,OACE;GACF,WAAW;GACX,mBAAmB;GACnB,SAAS;GACT,gBAAgB;GACjB,EACD,UACD;EACD,MAAM,aAAa,MAAM,KAAK,UAAU,KAAK,YAAY,KAAK;EAG9D,IAAI,WAAW,KAAK,SAAS,GAAG;GAC9B,KAAK,WAAW,WAAW,KAAK,MAAM,oBAAoB,CAAE;GAC5D,KAAK,aAAa,SAChB,WAAW,KAAK,MAAM,iBAAiB,CAAE,IACzC,GACD;GACD,KAAK,YAAY,WAAW,KAAK,MAC/B,2CACD,CAAE;;EAGL,KAAK,oBAAoB"}