В стандартной конфигурации используем 2 сервера: ecss1 и ecss2, соответственно 2 MSR которые обрабатывают медиа трафик.
Рассмотрим добавление еще одного или нескольких 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"
BASH

Далее необходимо выполнить импорт ключа командой:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 33CB2B750F8BB6A5
BASH

Перед началом установки необходимо обновить ОС:

sudo apt update
BASH

Если вы видите такое сообщение системы:

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
CODE
sudo apt update
BASH
sudo apt upgrade
BASH

Устанавливаем пакет "ecss-dns-env"

sudo apt install ecss-dns-env
BASH

Настройщик предложит выбрать разделы для настройки по вопросам ниже. Нужно выбрать 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
CODE

Проверка:

Проверить работу dnsmasq можно простыми ping:
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
CODE

Для медиасервера (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
CODE
<?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>
CODE

Выполним перезагрузку сервиса:

sudo systemctl restart ecss-media-server
CODE

Проверяем, что новый 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
CODE


Звонки от абонентов внутри одного сайта будет обрабатывать MSR данного сайта.
Звонки между абонентов разных сайтов будут по очереди обрабатывать MSR сайта абонента А/В.