Подключение дополнительных MSR к ECSS-10

Рассмотрим добавление еще одного или нескольких MSR, для распределения медиа трафика на 3 хоста и более, для высоко нагруженных систем /для приземления RTP трафика на локальном сайте в распределенных системах.
Требования к ОС/дополнительным пакетам, соответствуют требованиям ECSS10.
Установка MSR
Для работы MSR на отдельном хосте потребуются следующие пакеты с сайта Элтекс:
- ecss-dns-env
- ecss-media-server
Для этого необходимо добавить репозиторий ELTEX:
sudo sh -c "echo 'deb [arch=amd64] http://archive.eltex.org/ssw/jammy/3.14 stable main extras external' > /etc/apt/sources.list.d/eltex-ecss10-stable.list"
Далее необходимо выполнить импорт ключа командой:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 33CB2B750F8BB6A5
Перед началом установки необходимо обновить ОС:
sudo apt update
Если вы видите такое сообщение системы:
W: http://archive.eltex.org/ssw/jammy/3.14/dists/unstable/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.
Выполните следующую команду:
на обоих хостах
sudo cp /etc/apt/trusted.gpg /etc/apt/trusted.gpg.d
sudo apt update
sudo apt upgrade
Устанавливаем пакет "ecss-dns-env"
sudo apt install ecss-dns-env
Настройщик предложит выбрать разделы для настройки по вопросам ниже. Нужно выбрать broker, restfs и mysql. (на все вопросы указать "mysql vrrp адрес" ECSS10, для примера 10.0.10.10 )
| Вопрос ecss-dns-env | ответы |
|---|---|
| [Primary broker] Введите адрес: | 10.0.10.10 (необходимо ввести) |
| [Secondary broker] Введите адрес: | 10.0.10.10 (необходимо ввести) |
| [Mysql] Введите адрес: | 10.0.10.10 (необходимо ввести) |
| [Restfs] Введите адрес: | 10.0.10.10 (необходимо ввести) |
В случае необходимости можно скорректировать командой:
sudo dpkg-reconfigure ecss-dns-env
Проверка:
ping -c1 cocon.mysql.ecss ping -c1 dialer.mysql.ecss ping -c1 statistics.mysql.ecss ping -c1 tc.mysql.ecss ping -c1 tts.mysql.ecss ping -c1 system.restfs.ecss
ping -c1 cocon.mysql.ecss PING cocon.mysql.ecss (10.0.10.10) 56(84) bytes of data. 64 bytes from 10.0.10.10 (10.0.10.10): icmp_seq=1 ttl=64 time=0.234 ms --- cocon.mysql.ecss ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.234/0.234/0.234/0.000 ms . . . ping -c1 system.restfs.ecss PING system.restfs.ecss (10.0.10.10) 56(84) bytes of data. 64 bytes from 10.0.10.10 (10.0.10.10): icmp_seq=1 ttl=64 time=0.531 ms --- system.restfs.ecss ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.531/0.531/0.531/0.000 ms
Устанавливаем пакет "ecss-media-server"
sudo apt install ecss-media-server
Для медиасервера (ecss-media-server/MSR) возможно начальное конфигурирование с записью параметров в файл конфигурации,
для этого нужно провести конфигурацию transport bind-addr,mcc bind-addres (указываем локальный IP адрес, для примера 10.0.20.93):
| Вопросы ecss-media-server | Ответы для ecss1 |
|---|---|
| [ MSR SIP ] Введите bind-ip адрес (Enter) | 10.0.20.93 (необходимо ввести) |
| [MSR Control-Channel] Введите bind-ip-адрес | 10.0.20.93 (необходимо ввести) |
После формирования конфигураций по умолчанию производим их проверку:
Кодеки и все остальное, кроме ip на котором работает сервис, должно совпадать с MSR на ecss1 и ecss2
sudo nano /etc/ecss/ecss-media-server/config.xml
<?xml version="1.0" encoding="utf-8"?>
<config date="15:25:27 21.04.2025">
<general log-level="3" log-rotate="yes" max-calls="8192" max-vid-calls="8192" max-in-group="512" load-sensor="media" load-delta="10" calls-delta="100" spool-dir-size="100M" log-name="msr.log" log-path="/var/log/ecss/media-server" use-srtp="disabled" enable-ice-transport="no" ice-update="no" aggressive-ice="yes" stun-server="" suspicious-mode="no"/>
<transport bind-addr="10.0.20.93" port="5040" transport="udp+tcp"/>
<!-- By default configured public TURN-server -->
<turn-server use-turn="no" host="numb.viagenie.ca" user="webrtc@live.com" password="muazkh"/>
<media mixer-clock-rate="8000" use-vad="no" cng-level="0" jb-size="60" rtcp-timeout="0" rtp-timeout="350" udp-src-check="no" cn-multiplier="3" port-start="12000" port-range="2048" tias-in-sdp="no" thread-cnt="2" vid-enc-threads="2" vid-dec-threads="2" video-conf-layout="evenly" keyframe-interval="1000" vid-decode-delay="100" silent-codec-switch="yes" silence-threshold="-30" dtmf-flash-disable="no" video-dscp="0" other-dscp="0" dummy-video-src="/usr/share/ecss-media-server/video/dummy_video.yuv" video-enc-width="640" video-enc-height="360" finalsilence="1000" rtcp-stat-dump="yes" dtmf-tg-fpc-loop="10" dtmf-tg-fit="1" dtmf-tg-fot="2" dtmf-tg-volume="12288"/>
<codec pcma="1" pcmu="2" ilbc="0" gsm="0" g722="3" g726="0" g729="0" speex="0" l16="0" g7221="0" opus="0" h264="1" h263-1998="2" t38="1" tel-event-pt="0"/>
<accounts>
<!-- <dynamic msr_name="msr.name"
realm="sip:127.0.0.1:5000"
dtmf_mode="rfc+inband+info"
auth_name="user"
auth_password="password" /> -->
</accounts>
<pbyte>
<mcc bind-addr="10.0.20.93" port="5700"/>
</pbyte>
<conf_dir path="/etc/ecss/ecss-media-server/conf.d"/>
<metrics enable="no"/>
<rtp>
<auto addr-v4=""/>
</rtp>
</config>
В файле /etc/ecss/ecss-media-server/conf.d/default.xml указываем Ip адреса core, vlan 20 ECSS10 (для примера 10.0.20.91/10.0.20.92):
Здесь выставляем ip регистраторов, ecss1/ecss2
<?xml version="1.0"?>
<config>
<accounts>
<dynamic msr_name="msr.msr" realm="sip:10.0.20.91:5000" dtmf_mode="rfc+inband+info" auth_name="user" auth_password="password"/>
<dynamic msr_name="msr.msr" realm="sip:10.0.20.92:5000" dtmf_mode="rfc+inband+info" auth_name="user" auth_password="password"/>
</accounts>
</config>

Выполним перезагрузку сервиса:
sudo systemctl restart ecss-media-server
Проверяем, что новый MSR зарегистрировался на ecss1/ecss2 нодах:

Или аналогичная проверка в Cocon:
/system/media/resource/list all All media resource selected list specific: ┌─────────────┬───────────┬───────────────┬───────────┬──────┬────────┬───────────┬───────────┬─────────────────┬────────┬────────────┬────────┬─────────┬────────────┬──────────────────┬────────────┬─────────┐ │ Node │ MSR │ MSR │ MSR │ MSR │ Cc-id │ Cc-status │ Cc-uptime │ Cc-address │ Iface │ Iface │ Active │ Zone │ Site │ Contact │ Status │ Expired │ │ │ │ version │ perf coef │ load │ │ │ │ │ name │ addr │ │ │ │ │ │ │ ├─────────────┼───────────┼───────────────┼───────────┼──────┼────────┼───────────┼───────────┼─────────────────┼────────┼────────────┼────────┼─────────┼────────────┼──────────────────┼────────────┼─────────┤ │ core1@ecss1 │ msr.ecss1 │ 3.14.16.0.118 │ 1.0 │ 0 │ 54faa9 │ connected │ 01:57:46 │ 10.0.20.91:5700 │ net.20 │ 10.0.20.91 │ true │ default │ local │ net.20@msr.ecss1 │ registered │ 69 │ │ │ msr.ecss2 │ 3.14.16.0.118 │ 1.0 │ 0 │ 4cff7c │ connected │ 01:57:48 │ 10.0.20.92:5700 │ net.20 │ 10.0.20.92 │ true │ default │ local │ net.20@msr.ecss2 │ registered │ 67 │ │ │ msr.msr │ 3.14.16.0.147 │ 1.0 │ 0 │ 607c93 │ connected │ 00:17:07 │ 10.0.20.93:5700 │ net.20 │ 10.0.20.93 │ false │ default │ sub_A_site │ net.20@msr.msr │ registered │ 113 │ │ │ msr.msr1 │ 3.14.16.0.147 │ 1.0 │ 0 │ 77518b │ connected │ 00:17:11 │ 10.0.20.94:5701 │ net.30 │ 10.0.20.94 │ false │ default │ sub_B_site │ net.30@msr.msr1 │ registered │ 110 │ │ core1@ecss2 │ msr.ecss1 │ 3.14.16.0.118 │ 1.0 │ 0 │ 54faa9 │ connected │ 01:57:32 │ 10.0.20.91:5700 │ net.20 │ 10.0.20.91 │ true │ default │ local │ net.20@msr.ecss1 │ registered │ 81 │ │ │ msr.ecss2 │ 3.14.16.0.118 │ 1.0 │ 0 │ 4cff7c │ connected │ 01:57:32 │ 10.0.20.92:5700 │ net.20 │ 10.0.20.92 │ true │ default │ local │ net.20@msr.ecss2 │ registered │ 80 │ │ │ msr.msr │ 3.14.16.0.147 │ 1.0 │ 0 │ 607c93 │ connected │ 00:17:07 │ 10.0.20.93:5700 │ net.20 │ 10.0.20.93 │ false │ default │ sub_A_site │ net.20@msr.msr │ registered │ 112 │ │ │ msr.msr1 │ 3.14.16.0.147 │ 1.0 │ 0 │ 77518b │ connected │ 00:17:11 │ 10.0.20.94:5701 │ net.30 │ 10.0.20.94 │ false │ default │ sub_B_site │ net.30@msr.msr1 │ registered │ 109 │ └─────────────┴───────────┴───────────────┴───────────┴──────┴────────┴───────────┴───────────┴─────────────────┴────────┴────────────┴────────┴─────────┴────────────┴──────────────────┴────────────┴─────────┘
Активизируем и сохраняем:

Или аналогичные действия в Cocon:
/system/media/resource/set * net.30@msr.msr1 active true Media resource: ┌─────────────┬─────────────────┬──────────┬───────┐ │ Node │ Contact │ Property │ Value │ ├─────────────┼─────────────────┼──────────┼───────┤ │ core1@ecss1 │ net.30@msr.msr1 │ active │ true │ │ core1@ecss2 │ net.30@msr.msr1 │ active │ true │ └─────────────┴─────────────────┴──────────┴───────┘
Проверяем:
/system/media/resource/list Active media resource selected list specific: ┌─────────────┬───────────┬───────────────┬───────────┬──────┬────────┬───────────┬───────────┬─────────────────┬────────┬────────────┬────────┬─────────┬────────────┬──────────────────┬────────────┬─────────┐ │ Node │ MSR │ MSR │ MSR │ MSR │ Cc-id │ Cc-status │ Cc-uptime │ Cc-address │ Iface │ Iface │ Active │ Zone │ Site │ Contact │ Status │ Expired │ │ │ │ version │ perf coef │ load │ │ │ │ │ name │ addr │ │ │ │ │ │ │ ├─────────────┼───────────┼───────────────┼───────────┼──────┼────────┼───────────┼───────────┼─────────────────┼────────┼────────────┼────────┼─────────┼────────────┼──────────────────┼────────────┼─────────┤ │ core1@ecss1 │ msr.ecss1 │ 3.14.16.0.118 │ 1.0 │ 0 │ 54faa9 │ connected │ 00:02:51 │ 10.0.20.91:5700 │ net.20 │ 10.0.20.91 │ true │ default │ local │ net.20@msr.ecss1 │ registered │ 129 │ │ │ msr.ecss2 │ 3.14.16.0.118 │ 1.0 │ 0 │ 4cff7c │ connected │ 00:02:51 │ 10.0.20.92:5700 │ net.20 │ 10.0.20.92 │ true │ default │ local │ net.20@msr.ecss2 │ registered │ 128 │ │ │ msr.msr │ 3.14.16.0.147 │ 1.0 │ 0 │ 607c93 │ connected │ 00:02:48 │ 10.0.20.93:5700 │ net.20 │ 10.0.20.93 │ true │ default │ sub_A_site │ net.20@msr.msr │ registered │ 132 │ │ │ msr.msr1 │ 3.14.16.0.147 │ 1.0 │ 0 │ 77518b │ connected │ 00:02:51 │ 10.0.20.94:5701 │ net.30 │ 10.0.20.94 │ true │ default │ sub_B_site │ net.30@msr.msr1 │ registered │ 129 │ │ core1@ecss2 │ msr.ecss1 │ 3.14.16.0.118 │ 1.0 │ 0 │ 54faa9 │ connected │ 00:02:31 │ 10.0.20.91:5700 │ net.20 │ 10.0.20.91 │ true │ default │ local │ net.20@msr.ecss1 │ registered │ 149 │ │ │ msr.ecss2 │ 3.14.16.0.118 │ 1.0 │ 0 │ 4cff7c │ connected │ 00:02:33 │ 10.0.20.92:5700 │ net.20 │ 10.0.20.92 │ true │ default │ local │ net.20@msr.ecss2 │ registered │ 147 │ │ │ msr.msr │ 3.14.16.0.147 │ 1.0 │ 0 │ 607c93 │ connected │ 00:02:32 │ 10.0.20.93:5700 │ net.20 │ 10.0.20.93 │ true │ default │ sub_A_site │ net.20@msr.msr │ registered │ 147 │ │ │ msr.msr1 │ 3.14.16.0.147 │ 1.0 │ 0 │ 77518b │ connected │ 00:02:31 │ 10.0.20.94:5701 │ net.30 │ 10.0.20.94 │ true │ default │ sub_B_site │ net.30@msr.msr1 │ registered │ 149 │ └─────────────┴───────────┴───────────────┴───────────┴──────┴────────┴───────────┴───────────┴─────────────────┴────────┴────────────┴────────┴─────────┴────────────┴──────────────────┴────────────┴─────────┘
Создание нескольких Site-ов
По умолчанию, после установки в ECSS10 существует только один сайт "local". В случае использования нескольких абонентских локаций, с большой локальной речевой нагрузкой, будет хорошим решением приземлять речевой трафик локально, а в центральный офис отправлять только сигнальную информацию. Конечно RTP пакеты для абонентов в центральном офисе будут отправлены на локацию "local". Для реализации данной концепции потребуется не только добавить MSR на локациях "Sub_A_Site", "Sub_B_Site", что мы уже сделали. Но и описать в SSW к каким локациям относится тот или иной абонент. А так же описать правила распределения речевой нагрузки как внутри одной локации, так и между ними.
Указать реальную локацию абонента можно как через веб, так и через cocon:
Вариант веб.

Вариант Cocon.
/domain/test_domain/iface/user-set sip1 sip 50000@test_domain site sub_B_site
Property 'site' successfully changed to 'sub_B_site' for interfaces:
50000@test_domain
/domain/test_domain/iface/info sip1 sip 50000@test_domain
┌─────────────────┬─┬───────────────┬────────────────────────────────────────────────────────────────────────────────┐
│ Interface │W│ Property │ Value │
├─────────────────┼─┼───────────────┼────────────────────────────────────────────────────────────────────────────────┤
│50000@test_domain│i│account │{"...53-48-48-48-48","...53-48-48-48-48"} │
│ │i│adapter\version│"3.14.16.0.687" │
│ │i│alias │"alias-as-user" │
│ │i│aliases_list │["50000"] │
│ │i│auth_qop │true │
│ │D│cfc-support │true │
│ │i│declaration │{none,{1744,955449,987490}} │
│ │g│domain │"test_domain" │
│ │i│gate │{gate_amqp,<<"acp.adapter.init.ex">>,<<"acp.sip.sip1.test_set.init.rk">>} │
│ │i│group │"sip" │
│ │i│id │<<"06d0e9439eeca756">> │
│ │i│isActive │true │
│ │i│media-profile │{media_profile,"default",user, │
│ │ │ │ [{media_profile_codecs,'<other>', │
│ │ │ │ [{media_profile_codec,<<"<other>">>,<<"*">>,true,#{}}], │
│ │ │ │ #{offroad => false,'rtcp-enabled' => true}}, │
│ │ │ │ {media_profile_codecs,audio, │
│ │ │ │ [{media_profile_codec,<<"G722">>,<<"*">>,true,#{}}, │
│ │ │ │ {media_profile_codec,<<"PCMA">>,<<"*">>,true,#{}}, │
│ │ │ │ {media_profile_codec,<<"PCMU">>,<<"*">>,true,#{}}, │
│ │ │ │ {media_profile_codec,<<"G729">>,<<"*">>,true,#{}}, │
│ │ │ │ {media_profile_codec,<<"telephone-event">>,<<"*">>,true,#{}}], │
│ │ │ │ #{offroad => false,'rtcp-enabled' => true}}], │
│ │ │ │ #{'dtmf-receive-type' => auto,'dtmf-transmit-type' => transit}} │
│ │i│modificator │undefined │
│ │i│my_from │none │
│ │i│owner │"sip1" │
│ │i│profile │undefined │
│ │i│routing.context│default_routing │
│ │i│sip_domain │"test_domain" │
│ │i│site │<<"sub_B_site">> │
│ │i│subtype │user │
│ │D│terminal_type │smart │
│ │i│type │sip │
│ │i│user_agent │"TAU-8.IP/2.6.8 SN/VI33009554 sofia-sip/1.9" │
│ │i│user_name │"50000" │
│ │D│zone │<<"default">> │
└─────────────────┴─┴───────────────┴────────────────────────────────────────────────────────────────────────────────┘
Legend:
W: Where property is set:
D: This is default property
G: This is global property
g: This is group property
O: This is owner property
B: This is group+owner property
i: This is interface property
?: Unknown property level
Note: * char in W column means "Can't read iface resource info". Error reason in value column in this case
Звонки между абонентов разных сайтов будут по очереди обрабатывать MSR сайта абонента А/В.