Files
gb-cms/api_jt.go
2025-08-26 17:36:04 +08:00

252 lines
7.2 KiB
Go

package main
import (
"fmt"
"gb-cms/common"
"gb-cms/dao"
"gb-cms/log"
"gb-cms/stack"
"math"
"net/http"
)
func CheckJTDeviceOptions(device *dao.JTDeviceModel) error {
if err := stack.CheckSipUAOptions(&common.SIPUAOptions{
Username: device.Username,
ServerAddr: device.ServerAddr,
ServerID: device.SeverID,
}); err != nil {
return err
} else if device.SimNumber == "" {
// sim卡号必选项
return fmt.Errorf("sim number is required")
} else if dao.Device.ExistDevice(device.Username) {
// 用户名与下级设备冲突
return fmt.Errorf("username already exists")
}
return nil
}
func SaveAndStartJTDevice(device *dao.JTDeviceModel) error {
jtDevice, err := stack.NewJTDevice(device, common.SipStack)
if err != nil {
log.Sugar.Errorf("create virtual device failed: %s", err.Error())
return err
}
if !stack.JTDeviceManager.Add(device.Username, jtDevice) {
return fmt.Errorf("ua添加失败, id冲突. key: %s", device.Username)
}
jtDevice.Start()
return nil
}
func EqualJTDeviceOptions(old, new *dao.JTDeviceModel) bool {
return stack.EqualSipUAOptions(&common.SIPUAOptions{
Username: old.Username,
ServerAddr: old.ServerAddr,
Transport: old.Transport,
RegisterExpires: old.RegisterExpires,
Password: old.Password,
KeepaliveInterval: old.KeepaliveInterval,
ServerID: old.SeverID,
}, &common.SIPUAOptions{
Username: new.Username,
ServerAddr: new.ServerAddr,
Transport: new.Transport,
RegisterExpires: new.RegisterExpires,
Password: new.Password,
KeepaliveInterval: new.KeepaliveInterval,
ServerID: new.SeverID,
})
}
func (api *ApiServer) OnVirtualDeviceAdd(device *dao.JTDeviceModel, w http.ResponseWriter, r *http.Request) (interface{}, error) {
log.Sugar.Debugf("add virtual device: %v", *device)
err := CheckJTDeviceOptions(device)
if err != nil {
log.Sugar.Errorf("%s", err.Error())
return nil, err
} else if stack.JTDeviceManager.Find(device.Username) != nil {
log.Sugar.Errorf("jt device already exists: %s", device.Username)
return nil, fmt.Errorf("jt device already exists: %s", device.Username)
}
err = dao.JTDevice.SaveDevice(device)
if err != nil {
log.Sugar.Errorf("save device failed: %s", err.Error())
return nil, err
}
err = SaveAndStartJTDevice(device)
if err != nil {
log.Sugar.Errorf("start device failed: %s", err.Error())
}
return nil, err
}
func (api *ApiServer) OnVirtualDeviceEdit(device *dao.JTDeviceModel, w http.ResponseWriter, r *http.Request) (interface{}, error) {
log.Sugar.Debugf("edit virtual device: %v", *device)
err := CheckJTDeviceOptions(device)
if err != nil {
log.Sugar.Errorf("%s", err.Error())
return nil, err
}
oldDevice, err := dao.JTDevice.QueryDeviceByID(device.ID)
if err != nil {
log.Sugar.Errorf("jt device not found: %d", device.ID)
return nil, err
}
if err = dao.JTDevice.UpdateDevice(device); err != nil {
log.Sugar.Errorf("update device failed: %s", err.Error())
return nil, err
}
// 国标ID发生变更, 更新通道的RootID
if oldDevice.Username != device.Username {
_ = dao.Channel.UpdateRootID(oldDevice.Username, device.Username)
}
// sim卡号发生变更, 告知media server关闭推流, 关闭与上级的转发sink
if oldDevice.SimNumber != device.SimNumber {
log.Sugar.Infof("sim number changed, close streams")
streams, _ := dao.Stream.DeleteStreamByDeviceID(oldDevice.SimNumber)
for _, stream := range streams {
(&stack.Stream{stream}).Close(true, true)
}
}
// SipUA信息发生变更, 则需要重启设备
if !EqualJTDeviceOptions(oldDevice, device) {
log.Sugar.Infof("sipua options changed, restart device")
// 重启设备
if client := stack.JTDeviceManager.Remove(oldDevice.Username); client != nil {
client.Stop()
}
err = SaveAndStartJTDevice(device)
if err != nil {
log.Sugar.Errorf("update device failed: %s", err.Error())
}
} else {
log.Sugar.Infof("device info changed, update device info")
if client := stack.JTDeviceManager.Find(oldDevice.Username); client != nil {
client.SetDeviceInfo(device.Name, device.Manufacturer, device.Model, device.Firmware)
}
}
return nil, err
}
func (api *ApiServer) OnVirtualDeviceRemove(device *dao.JTDeviceModel, w http.ResponseWriter, r *http.Request) (interface{}, error) {
log.Sugar.Debugf("remove virtual device: %v", *device)
err := dao.JTDevice.DeleteDevice(device.Username)
if err != nil {
return nil, err
} else if client := stack.JTDeviceManager.Remove(device.Username); client != nil {
client.Stop()
}
return nil, nil
}
func (api *ApiServer) OnVirtualChannelAdd(channel *dao.ChannelModel, w http.ResponseWriter, r *http.Request) (interface{}, error) {
log.Sugar.Debugf("add virtual channel: %v", *channel)
device, err := dao.JTDevice.QueryDevice(channel.RootID)
if err != nil {
log.Sugar.Errorf("query jt device failed: %s device: %s ", err.Error(), channel.RootID)
return nil, err
}
if len(channel.DeviceID) != 20 {
log.Sugar.Errorf("invalid channel id: %s", channel.DeviceID)
return nil, fmt.Errorf("invalid channel id: %s", channel.DeviceID)
}
channel.ParentID = device.Username
channel.RootID = device.Username
channel.GroupID = device.Username
err = dao.Channel.SaveJTChannel(channel)
if err != nil {
log.Sugar.Errorf("save channel failed: %s", err.Error())
}
return nil, err
}
func (api *ApiServer) OnVirtualChannelEdit(channel *dao.ChannelModel, w http.ResponseWriter, r *http.Request) (interface{}, error) {
log.Sugar.Debugf("edit virtual channel: %v", *channel)
oldChannel, err := dao.Channel.QueryChannelByID(channel.ID)
if err != nil {
log.Sugar.Errorf("query channel failed: %s", err.Error())
return nil, err
}
if oldChannel.Name == channel.Name {
// 目前只支持修改通道名称
log.Sugar.Warnf("channel name not changed: %s", channel.Name)
return nil, nil
}
err = dao.Channel.UpdateChannel(channel)
if err != nil {
log.Sugar.Errorf("update channel failed: %s", err.Error())
}
return nil, err
}
func (api *ApiServer) OnVirtualChannelRemove(channel *dao.ChannelModel, w http.ResponseWriter, r *http.Request) (interface{}, error) {
log.Sugar.Debugf("remove virtual channel: %v", *channel)
device, err := dao.JTDevice.QueryDevice(channel.RootID)
if err != nil {
log.Sugar.Errorf("query jt device failed: %s device: %s ", err.Error(), channel.RootID)
return nil, err
}
err = dao.Channel.DeleteChannel(device.Username, channel.DeviceID)
if err != nil {
log.Sugar.Errorf("delete channel failed: %s", err.Error())
}
return nil, err
}
func (api *ApiServer) OnVirtualDeviceList(v *PageQuery, w http.ResponseWriter, r *http.Request) (interface{}, error) {
log.Sugar.Debugf("query virtual device list: %v", *v)
if v.PageNumber == nil {
var defaultPageNumber = 1
v.PageNumber = &defaultPageNumber
}
if v.PageSize == nil {
var defaultPageSize = 10
v.PageSize = &defaultPageSize
}
devices, total, err := dao.JTDevice.QueryDevices(*v.PageNumber, *v.PageSize)
if err != nil {
log.Sugar.Errorf("查询设备列表失败 err: %s", err.Error())
return nil, err
}
query := &PageQuery{
PageNumber: v.PageNumber,
PageSize: v.PageSize,
TotalCount: total,
TotalPages: int(math.Ceil(float64(total) / float64(*v.PageSize))),
Data: devices,
}
return query, nil
}