### Install tsip Library Source: https://github.com/tomgie/tsip/blob/main/README.md Installs the tsip library using npm. This is the first step to using the library in your project. ```bash npm install @tomgiee/tsip ``` -------------------------------- ### Install and Build tsip Project Dependencies Source: https://github.com/tomgie/tsip/blob/main/CONTRIBUTING.md Commands to install project dependencies, run tests, build the project, and run tests in watch mode using pnpm. These commands are essential for setting up the development environment and maintaining code quality. ```bash # Install dependencies pnpm install # Run tests pnpm test # Run tests in watch mode pnpm test:watch # Build the project pnpm build ``` -------------------------------- ### Example Commit Message for tsip Source: https://github.com/tomgie/tsip/blob/main/CONTRIBUTING.md An example of a well-formatted commit message for the tsip project, following the recommended structure. It includes a concise subject line and a detailed body explaining the changes and referencing associated issues. ```git Add Via header branch parameter validation - Validate branch parameter starts with z9hG4bK - Add error message with RFC 3261 reference - Add unit tests for edge cases Fixes #123 ``` -------------------------------- ### Handle SIP Registration with TypeScript Source: https://github.com/tomgie/tsip/blob/main/README.md Illustrates how to use the `RegistrationManager` to handle SIP registration. It shows the initialization with registrar details, address of record (AOR), contact information, and expiry, followed by initiating the registration process. ```typescript import { RegistrationManager } from '@tomgiee/tsip'; const registration = new RegistrationManager(transport, { registrar: 'sip:registrar.example.com', aor: 'sip:alice@example.com', contact: 'sip:alice@192.168.1.100:5060', expires: 3600, }); await registration.register(); ``` -------------------------------- ### Manage SIP Dialogs with DialogManager Source: https://context7.com/tomgie/tsip/llms.txt Demonstrates how to create and manage SIP dialogs using the DialogManager. This involves setting up transport and transaction managers, listening for dialog creation and termination events, and handling UAC/UAS dialog creation based on SIP responses. It also shows how to retrieve dialog statistics. ```typescript import { DialogManager, TransactionManager, TransportManager } from '@tomgiee/tsip'; const transportManager = new TransportManager(); await transportManager.createMandatoryTransports('0.0.0.0', 5060); const transactionManager = new TransactionManager(transportManager); const dialogManager = new DialogManager(transactionManager); // Listen for dialog events dialogManager.on('dialogCreated', (dialog) => { console.log('Dialog created:', dialog.id); console.log('State:', dialog.state); // 'EARLY' or 'CONFIRMED' console.log('Role:', dialog.role); // 'UAC' or 'UAS' console.log('Local URI:', dialog.data.localUri); console.log('Remote URI:', dialog.data.remoteUri); }); dialogManager.on('dialogTerminated', (dialog, reason) => { console.log('Dialog terminated:', dialog.id); console.log('Reason:', reason); }); // Create dialog as UAC when receiving 1xx-2xx response to INVITE const inviteRequest = buildInitialInvite({ to: 'sip:bob@example.com', from: 'sip:alice@example.com', contact: 'sip:alice@192.168.1.100:5060' }); // When receiving 180 Ringing or 200 OK const responseWith180 = parseMessage(/* 180 response */); const dialog = dialogManager.createDialogAsUAC(inviteRequest, responseWith180); // Create dialog as UAS when sending 2xx response transactionManager.on('request', (request, source, transaction) => { if (request.method === 'INVITE' && transaction) { // Send 200 OK const response = buildResponse(request, 200, 'OK'); transaction.send(response); // Create dialog const dialog = dialogManager.createDialogAsUAS(request, response); } }); // Get dialog statistics const stats = dialogManager.getStats(); console.log('Dialogs:', stats.early, 'early,', stats.confirmed, 'confirmed'); ``` -------------------------------- ### Manage SIP Sessions with SessionManager Source: https://context7.com/tomgie/tsip/llms.txt Illustrates how to manage complete SIP call sessions, including INVITE, ACK, and BYE handling. It covers listening for session events like creation, incoming invites, answering, and termination, as well as initiating outgoing calls with specific invite options. Session statistics can also be retrieved. ```typescript import { SessionManager, InviteOptions } from '@tomgiee/tsip'; const sessionManager = new SessionManager(); // Listen for session events sessionManager.on('sessionCreated', (session) => { console.log('Session created:', session.id); console.log('Role:', session.role); // 'UAC' or 'UAS' console.log('State:', session.state); }); sessionManager.on('invite', (session) => { console.log('Incoming call from:', session.data.remoteUri); // Ring session.sendProgress(180, 'Ringing'); // Answer after delay setTimeout(async () => { try { await session.accept({ body: 'v=0\r\no=- 123 456 IN IP4 192.168.1.100\r\n...', contentType: 'application/sdp' }); console.log('Call answered'); } catch (error) { console.error('Failed to answer:', error); } }, 2000); }); sessionManager.on('sessionAnswered', (session, dialog) => { console.log('Session answered!'); console.log('Dialog ID:', dialog.id); console.log('Media session established'); }); sessionManager.on('sessionTerminated', (session, reason) => { console.log('Session ended:', reason); }); // Initiate outgoing call (UAC) const inviteOptions: InviteOptions = { to: 'sip:bob@example.com', from: 'sip:alice@example.com', contact: 'sip:alice@192.168.1.100:5060', body: 'v=0\r\no=- 123 456 IN IP4 192.168.1.100\r\ns=SIP Call\r\n...', contentType: 'application/sdp' }; const session = await sessionManager.sendInvite(inviteOptions); // Session will progress through states: CALLING -> PROCEEDING -> ANSWERED // Terminate session setTimeout(async () => { await session.terminate(); }, 30000); // Get session statistics const stats = sessionManager.getStats(); console.log('Total sessions:', stats.totalSessions); console.log('Active:', stats.activeSessions); console.log('Answered:', stats.answeredSessions); ``` -------------------------------- ### SIP URI Parsing and Building Source: https://context7.com/tomgie/tsip/llms.txt Parses and constructs SIP URIs, supporting full parameter and header configurations. Functions `parseURI` and `buildURI` handle general URIs, while `parseSIPURI` and `buildSIPURI` are specific to SIP. Supports schemes like 'sip' and 'sips', and can parse URIs within angle brackets. ```typescript import { parseURI, buildURI, parseSIPURI, buildSIPURI } from '@tomgiee/tsip'; // Parse SIP URI const uri = parseURI('sip:alice@example.com:5060;transport=tcp?subject=meeting'); console.log(uri.scheme); // 'sip' console.log(uri.user); // 'alice' console.log(uri.host); // 'example.com' console.log(uri.port); // 5060 console.log(uri.params); // { transport: 'tcp' } console.log(uri.headers); // { subject: 'meeting' } // Build SIP URI const newUri = { scheme: 'sip', user: 'bob', host: 'example.com', port: 5060, params: { transport: 'udp' } }; const uriString = buildURI(newUri); console.log(uriString); // 'sip:bob@example.com:5060;transport=udp' // Parse with angle brackets // Assuming parseURIWithBrackets is exported from the library // const bracketUri = parseURIWithBrackets(''); // Parse SIPS (secure) URI const secureUri = parseSIPURI('sips:bob@secure.example.com'); console.log(secureUri.scheme); // 'sips' ``` -------------------------------- ### Manage SIP Transport with TypeScript Source: https://github.com/tomgie/tsip/blob/main/README.md Demonstrates setting up and using the `TransportManager` for sending and receiving SIP messages over UDP. It includes listening for incoming messages and sending a message to a specific destination. ```typescript import { TransportManager } from '@tomgiee/tsip'; const transport = new TransportManager(); // Listen for incoming messages transport.on('message', (msg, rinfo) => { console.log('Received:', msg); }); // Start UDP transport await transport.startUDP({ port: 5060 }); // Send a message await transport.send(message, { host: 'example.com', port: 5060, transport: 'UDP' }); ``` -------------------------------- ### Register SIP User Agent with RegistrationManager in TypeScript Source: https://context7.com/tomgie/tsip/llms.txt Registers a SIP user agent with a registrar server, handling authentication challenges and automatic refresh. It listens for registration events like 'registered', 'authRequired', 'refreshed', and 'failed'. Dependencies include 'RegistrationManager' and 'RegisterOptions' from '@tomgiee/tsip'. ```typescript import { RegistrationManager, RegisterOptions } from '@tomgiee/tsip'; const registrationManager = new RegistrationManager(); // Configure transport destination const destination = { host: 'sip.example.com', port: 5060, protocol: 'UDP' as const }; // Registration options const options: RegisterOptions = { aor: 'sip:alice@example.com', registrar: 'sip:sip.example.com', contacts: [{ uri: { scheme: 'sip', user: 'alice', host: '192.168.1.100', port: 5060 } }], expires: 3600, autoRefresh: true, refreshMargin: 60 }; // Listen for registration events registrationManager.on('registered', (data) => { console.log('Registration successful!'); console.log('Expires at:', new Date(data.expiresAt)); console.log('Current bindings:', data.currentBindings); }); registrationManager.on('authRequired', async (challenge, statusCode) => { console.log('Authentication required'); console.log('Realm:', challenge.realm); // Provide credentials await registrationManager.retryWithAuth( options.aor, 'alice', 'password123' ); }); registrationManager.on('refreshed', (data) => { console.log('Registration refreshed at', new Date()); }); registrationManager.on('failed', (error) => { console.error('Registration failed:', error.message); }); // Perform registration await registrationManager.register(options, destination); // Fetch current bindings const bindings = await registrationManager.fetchBindings(options, destination); console.log('Current bindings:', bindings); // Unregister await registrationManager.unregister(options.aor); ``` -------------------------------- ### Session Management API Source: https://context7.com/tomgie/tsip/llms.txt Manages complete SIP call sessions, including INVITE, ACK, and BYE handling with full lifecycle support. This includes listening for session events, initiating outgoing calls, answering incoming calls, and terminating sessions. ```APIDOC ## Session Management API ### Description Manage complete SIP call sessions including INVITE, ACK, and BYE handling with full lifecycle support. ### Method Various (Class methods) ### Endpoint N/A (Class-based API) ### Parameters N/A ### Request Example ```typescript import { SessionManager, InviteOptions } from '@tomgiee/tsip'; const sessionManager = new SessionManager(); // Listen for session events sessionManager.on('sessionCreated', (session) => { console.log('Session created:', session.id); console.log('Role:', session.role); // 'UAC' or 'UAS' console.log('State:', session.state); }); sessionManager.on('invite', (session) => { console.log('Incoming call from:', session.data.remoteUri); // Ring session.sendProgress(180, 'Ringing'); // Answer after delay setTimeout(async () => { try { await session.accept({ body: 'v=0\r\no=- 123 456 IN IP4 192.168.1.100\r\n...', // SDP body contentType: 'application/sdp' }); console.log('Call answered'); } catch (error) { console.error('Failed to answer:', error); } }, 2000); }); sessionManager.on('sessionAnswered', (session, dialog) => { console.log('Session answered!'); console.log('Dialog ID:', dialog.id); console.log('Media session established'); }); sessionManager.on('sessionTerminated', (session, reason) => { console.log('Session ended:', reason); }); // Initiate outgoing call (UAC) const inviteOptions: InviteOptions = { to: 'sip:bob@example.com', from: 'sip:alice@example.com', contact: 'sip:alice@192.168.1.100:5060', body: 'v=0\r\no=- 123 456 IN IP4 192.168.1.100\r\ns=SIP Call\r\n...', // SDP body contentType: 'application/sdp' }; const session = await sessionManager.sendInvite(inviteOptions); // Session will progress through states: CALLING -> PROCEEDING -> ANSWERED // Terminate session setTimeout(async () => { await session.terminate(); }, 30000); // Get session statistics const stats = sessionManager.getStats(); console.log('Total sessions:', stats.totalSessions); console.log('Active:', stats.activeSessions); console.log('Answered:', stats.answeredSessions); ``` ``` -------------------------------- ### Build SIP Messages with tsip Source: https://context7.com/tomgie/tsip/llms.txt Constructs RFC 3261-compliant SIP messages from structured TypeScript objects. It leverages typed interfaces to ensure correctness and provides a fluent API for message creation. This is used for generating outgoing SIP requests and responses. ```typescript import { buildMessage, SIPRequest, SIPMethod } from '@tomgiee/tsip'; const request: SIPRequest = { type: 'request', method: SIPMethod.INVITE, uri: { scheme: 'sip', user: 'bob', host: 'example.com' }, version: 'SIP/2.0', headers: new Map([ ['Via', [{ name: 'Via', protocol: 'SIP/2.0/UDP', host: 'pc33.example.com', params: { branch: 'z9hG4bK776asdhds' }, toString: function() { return 'Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds'; } }]], ['From', [{ name: 'From', uri: { scheme: 'sip', user: 'alice', host: 'example.com' }, params: { tag: '1928301774' }, toString: function() { return 'From: ;tag=1928301774'; } }]], ['To', [{ name: 'To', uri: { scheme: 'sip', user: 'bob', host: 'example.com' }, params: {}, toString: function() { return 'To: '; } }]], ['Call-ID', [{ name: 'Call-ID', callId: 'a84b4c76e66710@pc33.example.com', toString: function() { return 'Call-ID: a84b4c76e66710@pc33.example.com'; } }]], ['CSeq', [{ name: 'CSeq', sequence: 314159, method: 'INVITE', toString: function() { return 'CSeq: 314159 INVITE'; } }]], ['Max-Forwards', [{ name: 'Max-Forwards', value: 70, toString: function() { return 'Max-Forwards: 70'; } }]], ['Contact', [{ name: 'Contact', uri: { scheme: 'sip', user: 'alice', host: 'pc33.example.com' }, toString: function() { return 'Contact: '; } }]], ['Content-Length', [{ name: 'Content-Length', value: 0, toString: function() { return 'Content-Length: 0'; } }]] ]) }; const sipString = buildMessage(request); console.log(sipString); // Output: // INVITE sip:bob@example.com SIP/2.0 // Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds // From: ;tag=1928301774 // ... ``` -------------------------------- ### Dialog Management API Source: https://context7.com/tomgie/tsip/llms.txt Manages SIP dialogs to maintain conversation state between user agents. This includes listening for dialog events, creating dialogs as both UAC and UAS, and retrieving dialog statistics. ```APIDOC ## Dialog Management API ### Description Create and manage SIP dialogs for maintaining conversation state between user agents. ### Method Various (Internal library methods) ### Endpoint N/A (Class-based API) ### Parameters N/A ### Request Example ```typescript import { DialogManager, TransactionManager, TransportManager } from '@tomgiee/tsip'; const transportManager = new TransportManager(); await transportManager.createMandatoryTransports('0.0.0.0', 5060); const transactionManager = new TransactionManager(transportManager); const dialogManager = new DialogManager(transactionManager); // Listen for dialog events dialogManager.on('dialogCreated', (dialog) => { console.log('Dialog created:', dialog.id); console.log('State:', dialog.state); // 'EARLY' or 'CONFIRMED' console.log('Role:', dialog.role); // 'UAC' or 'UAS' console.log('Local URI:', dialog.data.localUri); console.log('Remote URI:', dialog.data.remoteUri); }); dialogManager.on('dialogTerminated', (dialog, reason) => { console.log('Dialog terminated:', dialog.id); console.log('Reason:', reason); }); // Create dialog as UAC when receiving 1xx-2xx response to INVITE const inviteRequest = buildInitialInvite({ to: 'sip:bob@example.com', from: 'sip:alice@example.com', contact: 'sip:alice@192.168.1.100:5060' }); // When receiving 180 Ringing or 200 OK const responseWith180 = parseMessage(/* 180 response */); const dialog = dialogManager.createDialogAsUAC(inviteRequest, responseWith180); // Create dialog as UAS when sending 2xx response transactionManager.on('request', (request, source, transaction) => { if (request.method === 'INVITE' && transaction) { // Send 200 OK const response = buildResponse(request, 200, 'OK'); transaction.send(response); // Create dialog const dialog = dialogManager.createDialogAsUAS(request, response); } }); // Get dialog statistics const stats = dialogManager.getStats(); console.log('Dialogs:', stats.early, 'early,', stats.confirmed, 'confirmed'); ``` ``` -------------------------------- ### Digest Authentication for SIP Source: https://context7.com/tomgie/tsip/llms.txt Generates and verifies RFC 2617 digest authentication credentials for SIP challenges. Requires specific challenge parameters from the server and user credentials to create authorization headers or validate incoming requests. The nonce count must be incremented for subsequent requests. ```typescript import { generateDigestCredentials, verifyDigestCredentials, DigestChallenge, DigestAlgorithm, QopOption } from '@tomgiee/tsip'; // Server sends 401/407 with challenge const challenge: DigestChallenge = { realm: 'example.com', nonce: '84a4cc6f3082121f32b42a2187831a9e', algorithm: DigestAlgorithm.MD5, qop: [QopOption.AUTH], opaque: '5ccc069c403ebaf9f0171e9517f40e41' }; // Client generates credentials const credentials = generateDigestCredentials( 'alice', // username 'secretpass', // password 'REGISTER', // method 'sip:example.com', // URI challenge // challenge from 401/407 response ); console.log('Response:', credentials.response); console.log('Nonce count:', credentials.nc); // '00000001' console.log('Client nonce:', credentials.cnonce); // Build Authorization header with credentials // Assuming AuthorizationHeader is a defined class // const authHeader = new AuthorizationHeader('Digest', credentials); // request.headers.set('Authorization', [authHeader]); // Server verifies credentials const isValid = verifyDigestCredentials( credentials, 'REGISTER', 'secretpass' // Expected password from user database ); if (isValid) { console.log('Authentication successful'); // Send 200 OK } else { console.log('Authentication failed'); // Send 403 Forbidden } // For subsequent requests with same nonce credentials.nc = '00000002'; // Increment nonce count ``` -------------------------------- ### Manage UDP/TCP Transports with TransportManager in TypeScript Source: https://context7.com/tomgie/tsip/llms.txt Creates and manages UDP and TCP transports for sending and receiving SIP messages. It supports automatic protocol selection and listens for incoming messages. Dependencies include the 'TransportManager' from '@tomgiee/tsip'. ```typescript import { TransportManager } from '@tomgiee/tsip'; const transportManager = new TransportManager(); // Create UDP transport const udpTransport = await transportManager.createTransport({ protocol: 'udp', host: '0.0.0.0', port: 5060 }); // Listen for incoming messages udpTransport.on('message', (msg) => { console.log('Received message:', msg.message); console.log('From:', msg.source.address, msg.source.port); }); // Send a message const destination = { host: 'example.com', port: 5060, protocol: 'udp' as const }; await udpTransport.send(sipRequest, destination); // Create both UDP and TCP transports (RFC 3261 requirement) const transports = await transportManager.createMandatoryTransports('0.0.0.0', 5060); console.log('UDP transport:', transports.udp); console.log('TCP transport:', transports.tcp); // Cleanup await transportManager.closeAll(); ``` -------------------------------- ### Build SIP Messages with TypeScript Source: https://github.com/tomgie/tsip/blob/main/README.md Constructs a SIP request message object and then serializes it into a SIP string using the `buildMessage` function. This utilizes TypeScript's type safety for defining SIP message structures. ```typescript import { buildMessage } from '@tomgiee/tsip'; import { SIPRequest, SIPMethod } from '@tomgiee/tsip'; const request: SIPRequest = { type: 'request', method: SIPMethod.INVITE, uri: { scheme: 'sip', user: 'bob', host: 'example.com' }, version: 'SIP/2.0', headers: { via: [{ protocol: 'SIP/2.0/UDP', host: 'pc33.example.com', params: { branch: 'z9hG4bK776asdhds' } }], from: { uri: { scheme: 'sip', user: 'alice', host: 'example.com' }, params: { tag: '1928301774' } }, to: { uri: { scheme: 'sip', user: 'bob', host: 'example.com' } }, callId: 'a84b4c76e66710@pc33.example.com', cseq: { seq: 314159, method: 'INVITE' }, maxForwards: 70, contact: [{ uri: { scheme: 'sip', user: 'alice', host: 'pc33.example.com' } }], contentLength: 0, }, }; const sipString = buildMessage(request); ``` -------------------------------- ### Handle SIP Transactions with TransactionManager in TypeScript Source: https://context7.com/tomgie/tsip/llms.txt Manages SIP transactions for reliable request/response delivery, including automatic retransmissions and timeout handling. It listens for incoming requests and responses, and can send requests via client transactions. Dependencies include 'TransactionManager', 'TransportManager', 'buildMessage', 'parseMessage', and 'SIPMethod' from '@tomgiee/tsip'. ```typescript import { TransactionManager, TransportManager } from '@tomgiee/tsip'; import { buildMessage, parseMessage, SIPMethod } from '@tomgiee/tsip'; const transportManager = new TransportManager(); await transportManager.createMandatoryTransports('0.0.0.0', 5060); const transactionManager = new TransactionManager(transportManager); // Listen for incoming requests transactionManager.on('request', (request, source, serverTransaction) => { console.log('Received:', request.method); if (serverTransaction) { // Send response via server transaction const response = { type: 'response' as const, statusCode: 200, reasonPhrase: 'OK', version: 'SIP/2.0', headers: request.headers }; serverTransaction.send(response); } }); // Listen for responses transactionManager.on('response', (response, clientTransaction) => { console.log('Received response:', response.statusCode); if (clientTransaction) { console.log('Transaction ID:', clientTransaction.id); console.log('Transaction state:', clientTransaction.state); } }); // Send request via client transaction const destination = { host: 'example.com', port: 5060, protocol: 'udp' as const }; const clientTransaction = transactionManager.sendRequest(inviteRequest, destination); clientTransaction.on('timeout', (timer) => { console.error('Transaction timeout:', timer); }); // Get statistics const stats = transactionManager.getStats(); console.log('Active transactions:', stats.clientTransactions, stats.serverTransactions); ``` -------------------------------- ### Parse SIP Messages with TypeScript Source: https://github.com/tomgie/tsip/blob/main/README.md Parses a raw SIP message string into a structured object using the `parseMessage` function from the `@tomgiee/tsip` library. It demonstrates how to extract message components like the method. ```typescript import { parseMessage } from '@tomgiee/tsip'; const sipMessage = `INVITE sip:bob@example.com SIP/2.0 Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds Max-Forwards: 70 To: Bob From: Alice ;tag=1928301774 Call-ID: a84b4c76e66710@pc33.example.com CSeq: 314159 INVITE Contact: Content-Length: 0 `; const message = parseMessage(sipMessage); console.log(message.method); // 'INVITE' ``` -------------------------------- ### Parse SIP Messages with tsip Source: https://context7.com/tomgie/tsip/llms.txt Parses raw SIP message strings into structured TypeScript objects. It extracts full type information and headers from both requests and responses. This function is essential for interpreting incoming SIP traffic. ```typescript import { parseMessage } from '@tomgiee/tsip'; const rawSipMessage = `INVITE sip:bob@example.com SIP/2.0 Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds Max-Forwards: 70 To: Bob From: Alice ;tag=1928301774 Call-ID: a84b4c76e66710@pc33.example.com CSeq: 314159 INVITE Contact: Content-Length: 0 `; const message = parseMessage(rawSipMessage); // Access parsed fields console.log(message.method); // 'INVITE' console.log(message.uri); // { scheme: 'sip', user: 'bob', host: 'example.com' } // Access headers const fromHeader = message.headers.get('From')[0]; console.log(fromHeader.uri.user); // 'alice' console.log(fromHeader.tag); // '1928301774' // Parse response const responseMessage = `SIP/2.0 200 OK Via: SIP/2.0/UDP pc33.example.com;branch=z9hG4bK776asdhds To: Bob ;tag=a6c85cf From: Alice ;tag=1928301774 Call-ID: a84b4c76e66710@pc33.example.com CSeq: 314159 INVITE Content-Length: 0 `; const response = parseMessage(responseMessage); console.log(response.statusCode); // 200 console.log(response.reasonPhrase); // 'OK' ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.