2026-06-25 14:27:41 +07:00

108 lines
3.5 KiB
Go

package esl
import (
"fmt"
"log"
"strings"
)
// GatewayAdd создаёт gateway на FreeSWITCH через Sofia профиль.
// Возвращает nil если gateway создан или уже существует (идемпотентность).
func (c *Client) GatewayAdd(profile, name, proxy string) error {
cmd := fmt.Sprintf("api sofia profile %s gwadd %s %s", profile, name, proxy)
headers, body, err := c.Send(cmd)
c.IncGatewayOps()
if err != nil {
log.Printf("[esl] GatewayAdd %s: ошибка команды: %v", name, err)
return err
}
reply := headers["Reply-Text"]
if strings.HasPrefix(reply, "+OK") {
log.Printf("[esl] GatewayAdd %s: создан (%s → %s)", name, profile, proxy)
return nil
}
// Gateway уже существует — не ошибка
if strings.Contains(body, "GATEWAY ALREADY") || strings.Contains(reply, "GATEWAY ALREADY") {
log.Printf("[esl] GatewayAdd %s: уже существует, ок", name)
return nil
}
log.Printf("[esl] GatewayAdd %s: ошибка FS — Reply: %s, Body: %s", name, reply, body)
return fmt.Errorf("GatewayAdd %s: %s (%s)", name, reply, body)
}
// GatewayDelete удаляет gateway на FreeSWITCH.
// Возвращает nil если gateway удалён или не найден (идемпотентность).
func (c *Client) GatewayDelete(profile, name string) error {
cmd := fmt.Sprintf("api sofia profile %s gwdel %s", profile, name)
headers, body, err := c.Send(cmd)
c.IncGatewayOps()
if err != nil {
log.Printf("[esl] GatewayDelete %s: ошибка команды: %v", name, err)
return err
}
reply := headers["Reply-Text"]
if strings.HasPrefix(reply, "+OK") {
log.Printf("[esl] GatewayDelete %s: удалён", name)
return nil
}
// Gateway не найден — не ошибка
if strings.Contains(body, "GATEWAY NOT FOUND") || strings.Contains(reply, "GATEWAY NOT FOUND") {
log.Printf("[esl] GatewayDelete %s: не найден, ок", name)
return nil
}
log.Printf("[esl] GatewayDelete %s: ошибка FS — Reply: %s, Body: %s", name, reply, body)
return fmt.Errorf("GatewayDelete %s: %s (%s)", name, reply, body)
}
// GatewayList возвращает список имён gateway в заданном профиле.
func (c *Client) GatewayList(profile string) ([]string, error) {
cmd := fmt.Sprintf("api sofia profile %s gwlist", profile)
_, body, err := c.Send(cmd)
if err != nil {
return nil, fmt.Errorf("GatewayList: %w", err)
}
// Парсим вывод gwlist — имена gateway на отдельных строках
lines := strings.Split(body, "\n")
var gateways []string
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "Name:") || strings.HasPrefix(line, "====") {
continue
}
// Ищем строки вида "pulse-ingress-xxxxx sip:..."
if strings.Contains(line, "pulse-") {
parts := strings.Fields(line)
if len(parts) > 0 {
gateways = append(gateways, parts[0])
}
}
}
return gateways, nil
}
// GatewaySyncAll синхронизирует все ingress-транки как gateway на FS.
// Вызывается после реконнекта.
func (c *Client) GatewaySyncAll(profile string, gateways []GatewaySpec) {
for _, g := range gateways {
if err := c.GatewayAdd(profile, g.Name, g.Proxy); err != nil {
log.Printf("[esl] GatewaySyncAll: ошибка %s: %v", g.Name, err)
}
}
}
// GatewaySpec описывает gateway для синхронизации.
type GatewaySpec struct {
Name string
Proxy string
}