package service import ( "context" "errors" "fmt" "log/slog" "net" "os" "sync" "github.com/emiago/sipgo" "github.com/ossrs/srs-sip/pkg/config" "github.com/ossrs/srs-sip/pkg/db" "github.com/ossrs/srs-sip/pkg/media" ) type UAS struct { *Cascade SN uint32 Streams sync.Map mediaLock sync.Mutex media media.IMedia recordQueryResults sync.Map // channelID -> chan []Record sipConnUDP *net.UDPConn sipConnTCP *net.TCPListener } var DM = GetDeviceManager() var MediaDB, _ = db.GetInstance("./media_servers.db") func NewUas() *UAS { return &UAS{ Cascade: &Cascade{}, } } func (s *UAS) Start(agent *sipgo.UserAgent, r0 interface{}) error { ctx := context.Background() s.startSipServer(agent, ctx, r0) return nil } func (s *UAS) Stop() { s.sipCli.Close() s.sipSvr.Close() } func (s *UAS) startSipServer(agent *sipgo.UserAgent, ctx context.Context, r0 interface{}) error { conf := r0.(*config.MainConfig) s.ctx = ctx s.conf = conf if agent == nil { ua, err := sipgo.NewUA(sipgo.WithUserAgent(UserAgent)) if err != nil { return err } agent = ua } cli, err := sipgo.NewClient(agent) if err != nil { return err } s.sipCli = cli svr, err := sipgo.NewServer(agent) if err != nil { return err } s.sipSvr = svr s.sipSvr.OnRegister(s.onRegister) s.sipSvr.OnMessage(s.onMessage) s.sipSvr.OnNotify(s.onNotify) if err := s.startUDP(); err != nil { return err } if err := s.startTCP(); err != nil { return err } candidate := os.Getenv("CANDIDATE") if candidate != "" { MediaDB.AddOrUpdateMediaServer("Default", "SRS", candidate, 1985, "", "", "", 1) } return nil } func (s *UAS) startUDP() error { lis, err := net.ListenUDP("udp", &net.UDPAddr{ IP: net.IPv4(0, 0, 0, 0), Port: s.conf.GB28181.Port, }) if err != nil { return fmt.Errorf("cannot listen on the UDP signaling port %d: %w", s.conf.GB28181.Port, err) } s.sipConnUDP = lis slog.Info("sip signaling listening on UDP", "address", lis.LocalAddr().String(), "port", s.conf.GB28181.Port) go func() { if err := s.sipSvr.ServeUDP(lis); err != nil { panic(fmt.Errorf("SIP listen UDP error: %w", err)) } }() return nil } func (s *UAS) startTCP() error { lis, err := net.ListenTCP("tcp", &net.TCPAddr{ IP: net.IPv4(0, 0, 0, 0), Port: s.conf.GB28181.Port, }) if err != nil { return fmt.Errorf("cannot listen on the TCP signaling port %d: %w", s.conf.GB28181.Port, err) } s.sipConnTCP = lis slog.Info("sip signaling listening on TCP", "address", lis.Addr().String(), "port", s.conf.GB28181.Port) go func() { if err := s.sipSvr.ServeTCP(lis); err != nil && !errors.Is(err, net.ErrClosed) { panic(fmt.Errorf("SIP listen TCP error: %w", err)) } }() return nil } func (s *UAS) getSN() uint32 { s.SN++ return s.SN }