KI-AGENT: SIP-Eingangssignalisierung prüfbarer machen

This commit is contained in:
2026-05-21 12:11:01 +02:00
parent e9bfa3dc1c
commit 8196f8a955
2 changed files with 58 additions and 0 deletions

View File

@@ -23,6 +23,17 @@ const sipError = ref(null)
const incomingCall = ref(null)
const callState = ref("idle")
const registererState = ref("Initial")
const sipEvents = ref([])
const addSipEvent = (message) => {
sipEvents.value = [
{
time: new Date().toLocaleTimeString("de-DE"),
message,
},
...sipEvents.value,
].slice(0, 8)
}
const selectedAccount = computed(() =>
(config.value?.testAccounts || []).find((account) => account.extension === selectedExtension.value)
@@ -254,6 +265,7 @@ const registerSip = async () => {
if (!uri) throw new Error("SIP-URI konnte nicht erstellt werden.")
const handleIncomingInvite = (invitation) => {
addSipEvent(`INVITE von ${invitation.remoteIdentity?.uri?.user || "unbekannt"} empfangen`)
incomingCall.value = invitation
setupSession(invitation, "incoming")
@@ -270,18 +282,37 @@ const registerSip = async () => {
contactName: account.extension,
authorizationUsername: account.extension,
authorizationPassword: account.password,
logBuiltinEnabled: true,
logLevel: "log",
logConnector: (level, category, label, content) => {
if (category === "sip.Transport" && content.includes("Received WebSocket")) {
addSipEvent("SIP-Nachricht über WebSocket empfangen")
}
if (content.includes("INVITE")) {
addSipEvent(`${category}: ${content.split("\n")[0]}`)
}
if (level === "error" || level === "warn") {
addSipEvent(`${category}: ${content.split("\n")[0]}`)
}
},
delegate: {
onInvite: handleIncomingInvite,
onConnect: () => {
addSipEvent("SIP-WebSocket verbunden")
sipStatus.value = sipRegistered.value ? `Registriert als ${account.extension}` : "SIP-WebSocket verbunden"
},
onDisconnect: () => {
addSipEvent("SIP-WebSocket getrennt")
sipRegistered.value = false
sipStatus.value = "SIP-WebSocket getrennt"
},
},
transportOptions: {
server: config.value.sipWebSocketUrl,
keepAliveInterval: 20,
traceSip: true,
},
sessionDescriptionHandlerFactoryOptions: {
constraints: {
@@ -302,11 +333,13 @@ const registerSip = async () => {
registererState.value = state
if (state === sip.RegistererState.Registered) {
addSipEvent(`Registrierung ${account.extension}: Registered`)
sipRegistered.value = true
sipStatus.value = `Registriert als ${account.extension}`
}
if (state === sip.RegistererState.Unregistered || state === sip.RegistererState.Terminated) {
addSipEvent(`Registrierung ${account.extension}: ${state}`)
sipRegistered.value = false
sipStatus.value = "Nicht verbunden"
}
@@ -319,6 +352,7 @@ const registerSip = async () => {
await reg.register({
requestDelegate: {
onAccept: () => {
addSipEvent(`REGISTER ${account.extension}: 200 OK`)
sipRegistered.value = true
sipStatus.value = `Registriert als ${account.extension}`
registererState.value = sip.RegistererState.Registered
@@ -327,6 +361,7 @@ const registerSip = async () => {
sipRegistered.value = false
sipStatus.value = "Registrierung abgelehnt"
sipError.value = `Asterisk hat REGISTER mit HTTP/SIP ${response.message.statusCode} abgelehnt.`
addSipEvent(`REGISTER ${account.extension}: ${response.message.statusCode}`)
},
},
})
@@ -576,6 +611,25 @@ onBeforeUnmount(() => {
</UBadge>
</div>
<div
v-if="sipEvents.length"
class="mt-4 rounded-lg border border-gray-200 bg-gray-50 p-3"
>
<p class="text-xs font-medium uppercase text-gray-500">
SIP-Ereignisse
</p>
<ul class="mt-2 space-y-1 text-xs text-gray-600">
<li
v-for="event in sipEvents"
:key="`${event.time}-${event.message}`"
class="grid grid-cols-[4.5rem_1fr] gap-2"
>
<span class="font-mono text-gray-400">{{ event.time }}</span>
<span class="break-words">{{ event.message }}</span>
</li>
</ul>
</div>
<UAlert
v-if="incomingCall"
class="mt-4"

View File

@@ -46,6 +46,8 @@ password=fedeo-test-1001
type=aor
max_contacts=5
remove_existing=yes
support_path=yes
qualify_frequency=30
[1002](fedeo-webrtc)
auth=1002-auth
@@ -62,3 +64,5 @@ password=fedeo-test-1002
type=aor
max_contacts=5
remove_existing=yes
support_path=yes
qualify_frequency=30