В рамках частной подсети 10.12.0.0/24 есть два сервера
1) 10.12.0.130 - на нем установлен asterisk и два номера - 1000 и 1001
2) Nodejs приложение на сервере 10.12.0.30
Если для обоих номеров использовать linphone - связь без проблем устанавливается, но если для номера 1000 указать клиент AsteriskAgi (nodejs приложение) звонок приходит - но данные ( голос ) не передаются
В чем может быть проблема?
Использовать AsteriskAgi необязтельно
Файл extensions.conf:
[internal]
exten => 1000,1,AGI(agi://10.12.0.30:5062)
exten => 1001,1,Dial(PJSIP/1001,20)
exten => 1002,1,Dial(PJSIP/1002,20)
exten => 1003,1,Dial(PJSIP/1002,20)
pjsip.conf:
[1003]
type=endpoint
context=internal
disallow=all
allow=ulaw
auth=auth1003
aors=1003
[auth1003]
type=auth
auth_type=userpass
password=1003p
username=1003
[1003]
type=aor
max_contacts=1
[1000]
type=endpoint
context=internal
disallow=all
allow=ulaw
auth=auth1000
aors=1000
[auth1000]
type=auth
auth_type=userpass
password=1000p
username=1000
[1000]
type=aor
max_contacts=1
[1001]
type=endpoint
context=internal
disallow=all
allow=ulaw
auth=auth1001
aors=1001
[auth1001]
type=auth
auth_type=userpass
password=1001p
username=1001
[1001]
type=aor
max_contacts=1
[1002]
type=endpoint
context=internal
disallow=all
allow=ulaw
auth=auth1002
aors=1002
[auth1002]
type=auth
auth_type=userpass
password=1002p
username=1002
[1002]
type=aor
max_contacts=1
Связь между всеми номерами по linphone работает нормально, но AGI - нет.
Буду рад если поможете разобраться или посоветуете другую архитектуру.
P.S. Не знаю как мониторить RTP пакеты, но в логах asterisk CLI бесконечно много спамит строка
Got RTP packet from 10.12.0.22:33639 (type 00, seq 002087, ts 635031636, len 000640)
Полный код nodejs приложения:
const AGIServer = require('asteriskagi');
const express = require('express');
const bodyParser = require('body-parser');
const { spawn } = require('child_process');
const app = express();
app.use(bodyParser.json());
let currentCall = null;
// Настройка AGI сервера
const agi = new AGIServer({port: 5062}); // Server (optional port, default: 4573)
console.log(agi)
agi.on("call", async (call) => {
const {
remoteServer,
uniqueid,
context,
extension,
priority,
calleridname,
callerid,
channel,
} = call;
console.log(`Incoming call from: ${callerid}`);
console.log(`Call details: ${JSON.stringify({ remoteServer, uniqueid, context, extension, priority, calleridname, callerid, channel })}`);
// Сохранение текущего вызова
currentCall = call;
call.on("hangup", () => {
console.log(`Hangup ${remoteServer}/${channel}`);
currentCall = null;
});
call.on("error", (err) => {
console.error(`ERROR: ${remoteServer}/${channel}: ${err}`);
currentCall = null;
});
// Убираем автоматический ответ на вызов
await call.Answer();
console.log('NEW CALL!!!');
call.on('data', (data) => {
try {
console.log('Received data from call');
console.log(data); // Логирование данных
ffmpegProcess.stdin.write(data);
} catch (error) {
console.log(error)
}
});
await call.Playback("beep");
await call.SayDigits('1234');
// console.log('Said digits 1234');
// console.log(call)
// console.log(call['_events'])
// console.log(call.AGI)
});
// HTTP-сервер для обработки запросов
app.post('/answer', async (req, res) => {
if (currentCall) {
const call = currentCall;
try {
await call.Answer();
console.log('Call answered');
// Использование ffmpeg для воспроизведения аудио через устройство
const audioOutputDevice = req.body.audioOutputDevice || 'default'; // Получение устройства из запроса или использование устройства по умолчанию
console.log(`Using audio output device: ${audioOutputDevice}`);
const ffmpegProcess = spawn('ffmpeg', [
'-f', 's16le',
'-ar', '8000',
'-ac', '1',
'-i', '-',
'-f', 'alsa',
audioOutputDevice
]);
ffmpegProcess.stdin.on('error', (error) => {
console.error('Error writing to ffmpeg stdin:', error);
});
ffmpegProcess.stderr.on('data', (data) => {
console.error(`ffmpeg stderr: ${data}`);
});
ffmpegProcess.on('close', (code) => {
console.log(`ffmpeg process exited with code ${code}`);
});
call.on('data', (data) => {
console.log('Received data from call');
console.log(data); // Логирование данных
ffmpegProcess.stdin.write(data);
});
call.on('end', () => {
console.log('Call ended');
ffmpegProcess.stdin.end();
});
res.status(200).send('Call answered');
} catch (err) {
console.error('Error answering call:', err);
await call.Hangup();
res.status(500).send('Error answering call');
currentCall = null;
}
} else {
res.status(400).send('No incoming call to answer');
}
});
// Запуск HTTP-сервера
app.listen(4000, () => {
console.log('HTTP server listening on port 4000');
});
call.on('data') не вызывается