На втором рабочем месте откройте телефон старшего группы и зарегистрируйте 6102. Пароли 6101/6102 выдаёт локальный администратор командой make sip-credentials.
+
На втором рабочем месте откройте телефон старшего группы (6102); преподаватель в роли вышестоящего начальника — телефон 6103. Пароли 6101–6103 выдаёт локальный администратор командой make sip-credentials.
Учебный протокол доклада
Связь используется при необходимости. Разговор и учебный доклад сохраняются в журнале, но не блокируют изменение статуса.
diff --git a/frontend/src/pages/phone/Phone.tsx b/frontend/src/pages/phone/Phone.tsx
index bf767b0..cff22a4 100644
--- a/frontend/src/pages/phone/Phone.tsx
+++ b/frontend/src/pages/phone/Phone.tsx
@@ -1,9 +1,22 @@
import { SipPhone } from "@/features/sip/SipPhone";
+// Второе рабочее место голосовой связи ДДС. Старший группы — по умолчанию;
+// вышестоящего начальника (?role=superior) играет преподаватель: это
+// обязательный маршрут по ответу заказчика (П.7).
+const ROLES = {
+ crew: { title: "Телефон старшего группы", extension: "6102", heading: "IP-телефон старшего группы" },
+ superior: { title: "Телефон вышестоящего начальника", extension: "6103", heading: "IP-телефон вышестоящего начальника" },
+} as const;
+
export function Phone() {
+ const role = new URLSearchParams(window.location.search).get("role") === "superior" ? "superior" : "crew";
+ const { title, extension, heading } = ROLES[role];
return
-
IP-телефон старшего группы
-
Откройте этот экран на втором рабочем месте, зарегистрируйте номер 6102 и примите вызов ДДС 6101.
-
+
{heading}
+
Откройте этот экран на втором рабочем месте, зарегистрируйте номер {extension} и примите вызов ДДС 6101.
+
+
{role === "crew"
+ ? <>Роль вышестоящего начальника — телефон 6103.>
+ : <>Роль старшего группы — телефон 6102.>}
;
}
diff --git a/sip/entrypoint.sh b/sip/entrypoint.sh
index b5bcfca..32ab598 100644
--- a/sip/entrypoint.sh
+++ b/sip/entrypoint.sh
@@ -10,6 +10,7 @@ override_6002=${SIP_6002_PASSWORD:-}
override_6003=${SIP_6003_PASSWORD:-}
override_6101=${SIP_6101_PASSWORD:-}
override_6102=${SIP_6102_PASSWORD:-}
+override_6103=${SIP_6103_PASSWORD:-}
if [ -s "$credentials" ]; then
# Файл содержит только сгенерированные hex-значения без shell-конструкций.
. "$credentials"
@@ -19,6 +20,7 @@ SIP_6002_PASSWORD=${override_6002:-${SIP_6002_PASSWORD:-$(openssl rand -hex 16)}
SIP_6003_PASSWORD=${override_6003:-${SIP_6003_PASSWORD:-$(openssl rand -hex 16)}}
SIP_6101_PASSWORD=${override_6101:-${SIP_6101_PASSWORD:-$(openssl rand -hex 16)}}
SIP_6102_PASSWORD=${override_6102:-${SIP_6102_PASSWORD:-$(openssl rand -hex 16)}}
+SIP_6103_PASSWORD=${override_6103:-${SIP_6103_PASSWORD:-$(openssl rand -hex 16)}}
SIP_EXTERNAL_MEDIA_ADDRESS=${SIP_EXTERNAL_MEDIA_ADDRESS:-127.0.0.1}
SIP_RTP_START=${SIP_RTP_START:-10000}
SIP_RTP_END=${SIP_RTP_END:-10099}
@@ -36,12 +38,13 @@ SIP_6002_PASSWORD=$SIP_6002_PASSWORD
SIP_6003_PASSWORD=$SIP_6003_PASSWORD
SIP_6101_PASSWORD=$SIP_6101_PASSWORD
SIP_6102_PASSWORD=$SIP_6102_PASSWORD
+SIP_6103_PASSWORD=$SIP_6103_PASSWORD
EOF
chmod 600 "$credentials"
-export SIP_6001_PASSWORD SIP_6002_PASSWORD SIP_6003_PASSWORD SIP_6101_PASSWORD SIP_6102_PASSWORD SIP_EXTERNAL_MEDIA_ADDRESS
+export SIP_6001_PASSWORD SIP_6002_PASSWORD SIP_6003_PASSWORD SIP_6101_PASSWORD SIP_6102_PASSWORD SIP_6103_PASSWORD SIP_EXTERNAL_MEDIA_ADDRESS
export SIP_RTP_START SIP_RTP_END
-envsubst '${SIP_6001_PASSWORD} ${SIP_6002_PASSWORD} ${SIP_6003_PASSWORD} ${SIP_6101_PASSWORD} ${SIP_6102_PASSWORD} ${SIP_EXTERNAL_MEDIA_ADDRESS}' \
+envsubst '${SIP_6001_PASSWORD} ${SIP_6002_PASSWORD} ${SIP_6003_PASSWORD} ${SIP_6101_PASSWORD} ${SIP_6102_PASSWORD} ${SIP_6103_PASSWORD} ${SIP_EXTERNAL_MEDIA_ADDRESS}' \
< /opt/lct-sip/pjsip.conf.template > /etc/asterisk/pjsip.conf
chmod 640 /etc/asterisk/pjsip.conf
chown root:asterisk /etc/asterisk/pjsip.conf
diff --git a/sip/extensions.conf b/sip/extensions.conf
index 1d68ff5..0c2373c 100644
--- a/sip/extensions.conf
+++ b/sip/extensions.conf
@@ -12,9 +12,10 @@ exten => _600[1-3],1,NoOp(LCT training call ${CALLERID(num)} -> ${EXTEN})
same => n,StopMixMonitor()
same => n,Hangup()
-; 6101/6102 — браузерные WebRTC-абоненты. Тот же учебный контекст и запись,
-; но отдельные endpoints не ломают обычные UDP/TCP-софтфоны 6001–6003.
-exten => _610[1-2],1,NoOp(LCT WebRTC training call ${CALLERID(num)} -> ${EXTEN})
+; 6101–6103 — браузерные WebRTC-абоненты: ДДС, старший группы, вышестоящий
+; начальник. Тот же учебный контекст и запись, но отдельные endpoints не ломают
+; обычные UDP/TCP-софтфоны 6001–6003.
+exten => _610[1-3],1,NoOp(LCT WebRTC training call ${CALLERID(num)} -> ${EXTEN})
same => n,Set(RECORDING_FILE=${STRFTIME(${EPOCH},UTC,%Y%m%d-%H%M%S)}-${CALLERID(num)}-${EXTEN}-${UNIQUEID})
same => n,MixMonitor(/recordings/${RECORDING_FILE}.wav,b)
same => n,Dial(PJSIP/${EXTEN},30)
diff --git a/sip/pjsip.conf.template b/sip/pjsip.conf.template
index b75f5f0..6bd35df 100644
--- a/sip/pjsip.conf.template
+++ b/sip/pjsip.conf.template
@@ -157,3 +157,22 @@ type=aor
max_contacts=2
remove_existing=yes
qualify_frequency=0
+
+; Вышестоящий начальник ДДС: роль играет преподаватель со страницы
+; /phone?role=superior. Обязательный голосовой маршрут по ответу заказчика (П.7).
+[6103](webrtc-endpoint)
+auth=6103-auth
+aors=6103
+callerid=Веб вышестоящий начальник <6103>
+
+[6103-auth]
+type=auth
+auth_type=userpass
+username=6103
+password=${SIP_6103_PASSWORD}
+
+[6103]
+type=aor
+max_contacts=2
+remove_existing=yes
+qualify_frequency=0