157 lines
4.0 KiB
JavaScript
157 lines
4.0 KiB
JavaScript
const config = require('config');
|
|
const logger = require('./utils/logger');
|
|
const { Srf } = require('drachtio-srf');
|
|
const RequestProcessor = require('./middleware/requestProcessor');
|
|
const RegistrationHandler = require('./routes/registration');
|
|
const InviteHandler = require('./routes/invite');
|
|
const InDialogHandler = require('./routes/indialog');
|
|
|
|
/**
|
|
* NexusVoice SIP Border Controller - Drachtio Implementation
|
|
*
|
|
* This server provides equivalent functionality to the Kamailio configuration:
|
|
* - SIP request validation and security filtering
|
|
* - User registration and location management
|
|
* - Call routing and media handling
|
|
* - Integration with external systems (Asterisk, RTP proxy)
|
|
*/
|
|
|
|
class SipServer {
|
|
constructor() {
|
|
this.srf = new Srf();
|
|
this.config = config;
|
|
this.requestProcessor = new RequestProcessor(this.srf);
|
|
this.registrationHandler = new RegistrationHandler(this.srf);
|
|
this.inviteHandler = new InviteHandler(this.srf);
|
|
this.inDialogHandler = new InDialogHandler(this.srf);
|
|
}
|
|
|
|
/**
|
|
* Initialize the SIP server
|
|
*/
|
|
async initialize() {
|
|
try {
|
|
logger.info('Initializing NexusVoice SBC...');
|
|
|
|
// Configure SIP listening parameters
|
|
const sipConfig = this.config.get('sip');
|
|
|
|
// Connect to drachtio server
|
|
await this.srf.connect({
|
|
host: sipConfig.host,
|
|
port: sipConfig.port,
|
|
transport: sipConfig.transport
|
|
});
|
|
|
|
logger.info('Connected to drachtio server on %s:%s', sipConfig.host, sipConfig.port);
|
|
|
|
// Setup middleware pipeline (equivalent to Kamailio's request_route)
|
|
this.setupMiddleware();
|
|
|
|
// Setup method-specific handlers
|
|
this.setupMethodHandlers();
|
|
|
|
// Setup in-dialog handlers
|
|
this.setupInDialogHandlers();
|
|
|
|
logger.info('NexusVoice SBC initialized successfully');
|
|
} catch (error) {
|
|
logger.error('Failed to initialize SBC: %s', error.message);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Setup the main request processing pipeline
|
|
*/
|
|
setupMiddleware() {
|
|
logger.info('Setting up request processing pipeline...');
|
|
|
|
// Apply the main request processor middleware
|
|
this.srf.use(this.requestProcessor.processRequest());
|
|
|
|
logger.info('Request processing pipeline configured');
|
|
}
|
|
|
|
/**
|
|
* Setup method-specific request handlers
|
|
*/
|
|
setupMethodHandlers() {
|
|
logger.info('Setting up method-specific handlers...');
|
|
|
|
// REGISTER requests (equivalent to kamailio.cfg:186-189)
|
|
this.srf.register((req, res) => {
|
|
this.registrationHandler.handleRegister(req, res);
|
|
});
|
|
|
|
// INVITE requests (equivalent to kamailio.cfg:210-212)
|
|
this.srf.invite((req, res) => {
|
|
this.inviteHandler.handleInvite(req, res);
|
|
});
|
|
|
|
logger.info('Method-specific handlers configured');
|
|
}
|
|
|
|
/**
|
|
* Setup in-dialog request handlers
|
|
*/
|
|
setupInDialogHandlers() {
|
|
logger.info('Setting up in-dialog handlers...');
|
|
|
|
// Handle all in-dialog requests
|
|
this.srf.dialog((req, res) => {
|
|
this.inDialogHandler.handleInDialog(req, res);
|
|
});
|
|
|
|
logger.info('In-dialog handlers configured');
|
|
}
|
|
|
|
/**
|
|
* Start the server
|
|
*/
|
|
async start() {
|
|
try {
|
|
await this.initialize();
|
|
logger.info('NexusVoice SBC started successfully');
|
|
} catch (error) {
|
|
logger.error('Failed to start SBC: %s', error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Graceful shutdown
|
|
*/
|
|
async shutdown() {
|
|
logger.info('Shutting down NexusVoice SBC...');
|
|
|
|
try {
|
|
await this.srf.disconnect();
|
|
logger.info('NexusVoice SBC shutdown complete');
|
|
} catch (error) {
|
|
logger.error('Error during shutdown: %s', error.message);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Create and start the server instance
|
|
const server = new SipServer();
|
|
|
|
// Handle graceful shutdown
|
|
process.on('SIGTERM', async () => {
|
|
await server.shutdown();
|
|
process.exit(0);
|
|
});
|
|
|
|
process.on('SIGINT', async () => {
|
|
await server.shutdown();
|
|
process.exit(0);
|
|
});
|
|
|
|
// Start the server
|
|
server.start().catch((error) => {
|
|
logger.error('Failed to start server: %s', error.message);
|
|
process.exit(1);
|
|
});
|
|
|
|
module.exports = SipServer; |