mirror of
https://github.com/lkmio/gb-cms.git
synced 2025-09-26 19:51:22 +08:00
feat: 适配级联相关接口
This commit is contained in:
526
api.go
526
api.go
@@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gb-cms/common"
|
"gb-cms/common"
|
||||||
"gb-cms/dao"
|
"gb-cms/dao"
|
||||||
@@ -15,6 +16,7 @@ import (
|
|||||||
"github.com/lkmio/avformat/utils"
|
"github.com/lkmio/avformat/utils"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
@@ -120,9 +122,10 @@ type QueryDeviceChannel struct {
|
|||||||
Limit int `json:"limit"`
|
Limit int `json:"limit"`
|
||||||
Keyword string `json:"q"`
|
Keyword string `json:"q"`
|
||||||
Online string `json:"online"`
|
Online string `json:"online"`
|
||||||
ChannelType string `json:"channel_type"`
|
Enable string `json:"enable"`
|
||||||
Order string `json:"order"` // asc/desc
|
ChannelType string `json:"channel_type"` // dir-查询子目录
|
||||||
Sort string `json:"sort"` // Channel-根据数据库ID排序/iD-根据通道ID排序
|
Order string `json:"order"` // asc/desc
|
||||||
|
Sort string `json:"sort"` // Channel-根据数据库ID排序/iD-根据通道ID排序
|
||||||
SMS string `json:"sms"`
|
SMS string `json:"sms"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +136,35 @@ type DeleteDevice struct {
|
|||||||
UA string `json:"ua"`
|
UA string `json:"ua"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SetEnable struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Enable bool `json:"enable"`
|
||||||
|
ShareAllChannel bool `json:"shareallchannel"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryCascadeChannelList struct {
|
||||||
|
QueryDeviceChannel
|
||||||
|
ID string `json:"id"`
|
||||||
|
Related bool `json:"related"` // 只看已选择
|
||||||
|
Reverse bool `json:"reverse"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChannelListResult struct {
|
||||||
|
ChannelCount int `json:"ChannelCount"`
|
||||||
|
ChannelList []*LiveGBSChannel `json:"ChannelList"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CascadeChannel struct {
|
||||||
|
CascadeID string
|
||||||
|
*LiveGBSChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
type CustomChannel struct {
|
||||||
|
DeviceID string `json:"serial"`
|
||||||
|
ChannelID string `json:"code"`
|
||||||
|
CustomID string `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
var apiServer *ApiServer
|
var apiServer *ApiServer
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -203,16 +235,28 @@ func startApiServer(addr string) {
|
|||||||
apiServer.router.HandleFunc("/api/v1/stream/info", withVerify(apiServer.OnStreamInfo))
|
apiServer.router.HandleFunc("/api/v1/stream/info", withVerify(apiServer.OnStreamInfo))
|
||||||
apiServer.router.HandleFunc("/api/v1/device/session/list", withVerify(common.WithQueryStringParams(apiServer.OnSessionList, QueryDeviceChannel{}))) // 推流列表
|
apiServer.router.HandleFunc("/api/v1/device/session/list", withVerify(common.WithQueryStringParams(apiServer.OnSessionList, QueryDeviceChannel{}))) // 推流列表
|
||||||
apiServer.router.HandleFunc("/api/v1/device/session/stop", withVerify(common.WithFormDataParams(apiServer.OnSessionStop, StreamIDParams{}))) // 关闭流
|
apiServer.router.HandleFunc("/api/v1/device/session/stop", withVerify(common.WithFormDataParams(apiServer.OnSessionStop, StreamIDParams{}))) // 关闭流
|
||||||
|
apiServer.router.HandleFunc("/api/v1/device/setchannelid", withVerify(common.WithFormDataParams(apiServer.OnCustomChannelSet, CustomChannel{}))) // 关闭流
|
||||||
|
|
||||||
apiServer.router.HandleFunc("/api/v1/position/sub", common.WithJsonResponse(apiServer.OnSubscribePosition, &DeviceChannelID{})) // 订阅移动位置
|
apiServer.router.HandleFunc("/api/v1/position/sub", common.WithJsonResponse(apiServer.OnSubscribePosition, &DeviceChannelID{})) // 订阅移动位置
|
||||||
apiServer.router.HandleFunc("/api/v1/playback/seek", common.WithJsonResponse(apiServer.OnSeekPlayback, &SeekParams{})) // 回放seek
|
apiServer.router.HandleFunc("/api/v1/playback/seek", common.WithJsonResponse(apiServer.OnSeekPlayback, &SeekParams{})) // 回放seek
|
||||||
apiServer.router.HandleFunc("/api/v1/control/ptz", withVerify(common.WithFormDataParams(apiServer.OnPTZControl, QueryRecordParams{}))) // 云台控制
|
apiServer.router.HandleFunc("/api/v1/control/ptz", withVerify(common.WithFormDataParams(apiServer.OnPTZControl, QueryRecordParams{}))) // 云台控制
|
||||||
|
|
||||||
apiServer.router.HandleFunc("/api/v1/cascade/list", apiServer.OnPlatformList) // 级联设备列表
|
apiServer.router.HandleFunc("/api/v1/cascade/list", withVerify(common.WithQueryStringParams(apiServer.OnPlatformList, QueryDeviceChannel{}))) // 级联设备列表
|
||||||
apiServer.router.HandleFunc("/api/v1/platform/add", common.WithJsonResponse(apiServer.OnPlatformAdd, &dao.PlatformModel{})) // 添加级联设备
|
apiServer.router.HandleFunc("/api/v1/cascade/save", withVerify(common.WithFormDataParams(apiServer.OnPlatformAdd, LiveGBSCascade{}))) // 添加级联设备
|
||||||
apiServer.router.HandleFunc("/api/v1/platform/remove", common.WithJsonResponse(apiServer.OnPlatformRemove, &dao.PlatformModel{})) // 删除级联设备
|
apiServer.router.HandleFunc("/api/v1/cascade/setenable", withVerify(common.WithFormDataParams(apiServer.OnEnableSet, SetEnable{}))) // 添加级联设备
|
||||||
apiServer.router.HandleFunc("/api/v1/platform/channel/bind", common.WithJsonResponse(apiServer.OnPlatformChannelBind, &PlatformChannel{})) // 级联绑定通道
|
apiServer.router.HandleFunc("/api/v1/cascade/remove", withVerify(common.WithFormDataParams(apiServer.OnPlatformRemove, SetEnable{}))) // 删除级联设备
|
||||||
apiServer.router.HandleFunc("/api/v1/platform/channel/unbind", common.WithJsonResponse(apiServer.OnPlatformChannelUnbind, &PlatformChannel{})) // 级联解绑通道
|
apiServer.router.HandleFunc("/api/v1/cascade/channellist", withVerify(common.WithQueryStringParams(apiServer.OnPlatformChannelList, QueryCascadeChannelList{}))) // 级联设备通道列表
|
||||||
|
|
||||||
|
apiServer.router.HandleFunc("/api/v1/cascade/savechannels", withVerify(apiServer.OnPlatformChannelBind)) // 级联绑定通道
|
||||||
|
apiServer.router.HandleFunc("/api/v1/cascade/removechannels", withVerify(apiServer.OnPlatformChannelUnbind)) // 级联解绑通道
|
||||||
|
apiServer.router.HandleFunc("/api/v1/cascade/setshareallchannel", withVerify(common.WithFormDataParams(apiServer.OnShareAllChannel, SetEnable{}))) // 开启或取消级联所有通道
|
||||||
|
apiServer.router.HandleFunc("/api/v1/cascade/pushcatalog", withVerify(common.WithFormDataParams(apiServer.OnCatalogPush, SetEnable{}))) // 推送目录
|
||||||
|
|
||||||
|
// 暂未开发
|
||||||
|
apiServer.router.HandleFunc("/api/v1/alarm/list", withVerify(func(w http.ResponseWriter, req *http.Request) {})) // 报警查询
|
||||||
|
apiServer.router.HandleFunc("/api/v1/cloudrecord/querychannels", withVerify(func(w http.ResponseWriter, req *http.Request) {})) // 云端录像
|
||||||
|
apiServer.router.HandleFunc("/api/v1/user/list", withVerify(func(w http.ResponseWriter, req *http.Request) {})) // 用户管理
|
||||||
|
apiServer.router.HandleFunc("/api/v1/log/list", withVerify(func(w http.ResponseWriter, req *http.Request) {})) // 操作日志
|
||||||
|
|
||||||
apiServer.router.HandleFunc("/api/v1/broadcast/invite", common.WithJsonResponse(apiServer.OnBroadcast, &BroadcastParams{Setup: &common.DefaultSetupType})) // 发起语音广播
|
apiServer.router.HandleFunc("/api/v1/broadcast/invite", common.WithJsonResponse(apiServer.OnBroadcast, &BroadcastParams{Setup: &common.DefaultSetupType})) // 发起语音广播
|
||||||
apiServer.router.HandleFunc("/api/v1/broadcast/hangup", common.WithJsonResponse(apiServer.OnHangup, &BroadcastParams{})) // 挂断广播会话
|
apiServer.router.HandleFunc("/api/v1/broadcast/hangup", common.WithJsonResponse(apiServer.OnHangup, &BroadcastParams{})) // 挂断广播会话
|
||||||
@@ -281,15 +325,6 @@ func (api *ApiServer) OnPlay(params *StreamParams, w http.ResponseWriter, r *htt
|
|||||||
|
|
||||||
// 拉流地址携带的参数
|
// 拉流地址携带的参数
|
||||||
query := r.URL.Query()
|
query := r.URL.Query()
|
||||||
|
|
||||||
// 播放授权
|
|
||||||
streamToken := query.Get("stream_token")
|
|
||||||
if TokenManager.Find(streamToken) == nil {
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
log.Sugar.Errorf("播放鉴权失败, token不存在 token: %s", streamToken)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
jtSource := query.Get("forward_type") == "gateway_1078"
|
jtSource := query.Get("forward_type") == "gateway_1078"
|
||||||
|
|
||||||
// 跳过非国标拉流
|
// 跳过非国标拉流
|
||||||
@@ -324,12 +359,21 @@ func (api *ApiServer) OnPlay(params *StreamParams, w http.ResponseWriter, r *htt
|
|||||||
log.Sugar.Errorf("通知1078信令服务器失败. 响应状态码: %d sim number: %s channel number: %s", response.StatusCode, simNumber, channelNumber)
|
log.Sugar.Errorf("通知1078信令服务器失败. 响应状态码: %d sim number: %s channel number: %s", response.StatusCode, simNumber, channelNumber)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// livegbs前端即使退出的播放,还是会拉流. 如果在hook中发起invite, 会造成不必要的请求.
|
// livegbs前端即使退出的播放,还是会拉流. 如果在hook中发起invite, 会造成不必要的请求.
|
||||||
// 流不存在, 返回404
|
// 流不存在, 返回404
|
||||||
if stream, _ := dao.Stream.QueryStream(params.Stream); stream == nil {
|
if params.Protocol < stack.TransStreamGBCascaded {
|
||||||
w.WriteHeader(http.StatusNotFound)
|
// 播放授权
|
||||||
return
|
streamToken := query.Get("stream_token")
|
||||||
|
if TokenManager.Find(streamToken) == nil {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
log.Sugar.Errorf("播放鉴权失败, token不存在 token: %s", streamToken)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if stream, _ := dao.Stream.QueryStream(params.Stream); stream == nil {
|
||||||
|
w.WriteHeader(http.StatusNotFound)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inviteParams := &InviteParams{
|
inviteParams := &InviteParams{
|
||||||
@@ -421,11 +465,11 @@ func (api *ApiServer) OnPublish(params *StreamParams, w http.ResponseWriter, _ *
|
|||||||
func (api *ApiServer) OnPublishDone(params *StreamParams, _ http.ResponseWriter, _ *http.Request) {
|
func (api *ApiServer) OnPublishDone(params *StreamParams, _ http.ResponseWriter, _ *http.Request) {
|
||||||
log.Sugar.Debugf("推流结束事件. protocol: %s stream: %s", params.Protocol, params.Stream)
|
log.Sugar.Debugf("推流结束事件. protocol: %s stream: %s", params.Protocol, params.Stream)
|
||||||
|
|
||||||
stack.CloseStream(params.Stream, false)
|
//stack.CloseStream(params.Stream, false)
|
||||||
// 对讲websocket断开连接
|
//// 对讲websocket断开连接
|
||||||
if stack.SourceTypeGBTalk == params.Protocol {
|
//if stack.SourceTypeGBTalk == params.Protocol {
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ApiServer) OnIdleTimeout(params *StreamParams, w http.ResponseWriter, _ *http.Request) {
|
func (api *ApiServer) OnIdleTimeout(params *StreamParams, w http.ResponseWriter, _ *http.Request) {
|
||||||
@@ -705,10 +749,15 @@ func (api *ApiServer) OnChannelList(q *QueryDeviceChannel, _ http.ResponseWriter
|
|||||||
values := r.URL.Query()
|
values := r.URL.Query()
|
||||||
log.Sugar.Debugf("查询通道列表 %s", values.Encode())
|
log.Sugar.Debugf("查询通道列表 %s", values.Encode())
|
||||||
|
|
||||||
device, err := dao.Device.QueryDevice(q.DeviceID)
|
var deviceName string
|
||||||
if err != nil {
|
if q.DeviceID != "" {
|
||||||
log.Sugar.Errorf("查询设备失败 err: %s", err.Error())
|
device, err := dao.Device.QueryDevice(q.DeviceID)
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
log.Sugar.Errorf("查询设备失败 err: %s", err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceName = device.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
var status string
|
var status string
|
||||||
@@ -723,98 +772,19 @@ func (api *ApiServer) OnChannelList(q *QueryDeviceChannel, _ http.ResponseWriter
|
|||||||
q.Order = "asc"
|
q.Order = "asc"
|
||||||
}
|
}
|
||||||
|
|
||||||
channels, total, err := dao.Channel.QueryChannels(q.DeviceID, q.GroupID, (q.Start/q.Limit)+1, q.Limit, status, q.Keyword, q.Order, q.Sort)
|
channels, total, err := dao.Channel.QueryChannels(q.DeviceID, q.GroupID, (q.Start/q.Limit)+1, q.Limit, status, q.Keyword, q.Order, q.Sort, q.ChannelType == "dir")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Sugar.Errorf("查询通道列表失败 err: %s", err.Error())
|
log.Sugar.Errorf("查询通道列表失败 err: %s", err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
response := struct {
|
response := ChannelListResult{
|
||||||
ChannelCount int
|
|
||||||
ChannelList []LiveGBSChannel
|
|
||||||
}{
|
|
||||||
ChannelCount: total,
|
ChannelCount: total,
|
||||||
}
|
}
|
||||||
|
|
||||||
index := q.Start + 1
|
index := q.Start + 1
|
||||||
for _, channel := range channels {
|
response.ChannelList = ChannelModels2LiveGBSChannels(index, channels, deviceName)
|
||||||
parental, _ := strconv.Atoi(channel.Parental)
|
return &response, nil
|
||||||
port, _ := strconv.Atoi(channel.Port)
|
|
||||||
registerWay, _ := strconv.Atoi(channel.RegisterWay)
|
|
||||||
secrecy, _ := strconv.Atoi(channel.Secrecy)
|
|
||||||
|
|
||||||
streamID := common.GenerateStreamID(common.InviteTypePlay, channel.RootID, channel.DeviceID, "", "")
|
|
||||||
if stream, err := dao.Stream.QueryStream(streamID); err != nil || stream == nil {
|
|
||||||
streamID = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
response.ChannelList = append(response.ChannelList, LiveGBSChannel{
|
|
||||||
Address: channel.Address,
|
|
||||||
Altitude: 0,
|
|
||||||
AudioEnable: true,
|
|
||||||
BatteryLevel: 0,
|
|
||||||
Channel: index,
|
|
||||||
CivilCode: channel.CivilCode,
|
|
||||||
CloudRecord: false,
|
|
||||||
CreatedAt: channel.CreatedAt.Format("2006-01-02 15:04:05"),
|
|
||||||
Custom: false,
|
|
||||||
CustomAddress: "",
|
|
||||||
CustomBlock: "",
|
|
||||||
CustomCivilCode: "",
|
|
||||||
CustomFirmware: "",
|
|
||||||
CustomID: "",
|
|
||||||
CustomIPAddress: "",
|
|
||||||
CustomLatitude: 0,
|
|
||||||
CustomLongitude: 0,
|
|
||||||
CustomManufacturer: "",
|
|
||||||
CustomModel: "",
|
|
||||||
CustomName: "",
|
|
||||||
CustomPTZType: 0,
|
|
||||||
CustomParentID: "",
|
|
||||||
CustomPort: 0,
|
|
||||||
CustomSerialNumber: "",
|
|
||||||
CustomStatus: "",
|
|
||||||
Description: "",
|
|
||||||
DeviceCustomName: "",
|
|
||||||
DeviceID: channel.RootID,
|
|
||||||
DeviceName: device.Name,
|
|
||||||
DeviceOnline: device.Online(),
|
|
||||||
DeviceType: "GB",
|
|
||||||
Direction: 0,
|
|
||||||
DownloadSpeed: "",
|
|
||||||
Firmware: "",
|
|
||||||
ID: channel.DeviceID,
|
|
||||||
IPAddress: channel.IPAddress,
|
|
||||||
Latitude: 0,
|
|
||||||
Longitude: 0,
|
|
||||||
Manufacturer: channel.Manufacturer,
|
|
||||||
Model: channel.Model,
|
|
||||||
Name: channel.Name,
|
|
||||||
NumOutputs: 0,
|
|
||||||
Ondemand: true,
|
|
||||||
Owner: channel.Owner,
|
|
||||||
PTZType: 0,
|
|
||||||
ParentID: channel.ParentID,
|
|
||||||
Parental: parental,
|
|
||||||
Port: port,
|
|
||||||
Quality: "",
|
|
||||||
RegisterWay: registerWay,
|
|
||||||
Secrecy: secrecy,
|
|
||||||
SerialNumber: "",
|
|
||||||
Shared: false,
|
|
||||||
SignalLevel: 0,
|
|
||||||
SnapURL: "",
|
|
||||||
Speed: 0,
|
|
||||||
Status: channel.Status.String(),
|
|
||||||
StreamID: string(streamID), // 实时流ID
|
|
||||||
SubCount: channel.SubCount,
|
|
||||||
UpdatedAt: channel.UpdatedAt.Format("2006-01-02 15:04:05"),
|
|
||||||
})
|
|
||||||
|
|
||||||
index++
|
|
||||||
}
|
|
||||||
|
|
||||||
return response, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ApiServer) OnRecordList(v *QueryRecordParams, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
func (api *ApiServer) OnRecordList(v *QueryRecordParams, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
||||||
@@ -1084,7 +1054,7 @@ func (api *ApiServer) OnStarted(_ http.ResponseWriter, _ *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ApiServer) OnPlatformAdd(v *dao.PlatformModel, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
func (api *ApiServer) OnPlatformAdd(v *LiveGBSCascade, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
||||||
log.Sugar.Debugf("添加级联设备 %v", *v)
|
log.Sugar.Debugf("添加级联设备 %v", *v)
|
||||||
|
|
||||||
if v.Username == "" {
|
if v.Username == "" {
|
||||||
@@ -1092,89 +1062,171 @@ func (api *ApiServer) OnPlatformAdd(v *dao.PlatformModel, _ http.ResponseWriter,
|
|||||||
log.Sugar.Infof("级联设备使用本级域: %s", common.Config.SipID)
|
log.Sugar.Infof("级联设备使用本级域: %s", common.Config.SipID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
if len(v.Username) != 20 {
|
if len(v.Username) != 20 {
|
||||||
err := fmt.Errorf("用户名长度必须20位")
|
err = fmt.Errorf("用户名长度必须20位")
|
||||||
log.Sugar.Errorf("添加级联设备失败 err: %s", err.Error())
|
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if len(v.ServerID) != 20 {
|
} else if len(v.Serial) != 20 {
|
||||||
err := fmt.Errorf("上级ID长度必须20位")
|
err = fmt.Errorf("上级ID长度必须20位")
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
log.Sugar.Errorf("添加级联设备失败 err: %s", err.Error())
|
log.Sugar.Errorf("添加级联设备失败 err: %s", err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
v.Status = "OFF"
|
v.Status = "OFF"
|
||||||
platform, err := stack.NewPlatform(&v.SIPUAOptions, common.SipStack)
|
model := dao.PlatformModel{
|
||||||
|
SIPUAOptions: common.SIPUAOptions{
|
||||||
|
Name: v.Name,
|
||||||
|
Username: v.Username,
|
||||||
|
Password: v.Password,
|
||||||
|
ServerID: v.Serial,
|
||||||
|
ServerAddr: net.JoinHostPort(v.Host, strconv.Itoa(v.Port)),
|
||||||
|
Transport: v.CommandTransport,
|
||||||
|
RegisterExpires: v.RegisterInterval,
|
||||||
|
KeepaliveInterval: v.KeepaliveInterval,
|
||||||
|
Status: common.OFF,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, err := stack.NewPlatform(&model.SIPUAOptions, common.SipStack)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Sugar.Errorf("创建级联设备失败 err: %s", err.Error())
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !stack.PlatformManager.Add(v.ServerAddr, platform) {
|
// 编辑国标设备
|
||||||
log.Sugar.Errorf("ua添加失败, id冲突. key: %s", v.ServerAddr)
|
if v.ID != "" {
|
||||||
return fmt.Errorf("ua添加失败, id冲突. key: %s", v.ServerAddr), nil
|
// 停止旧的
|
||||||
} else if err = dao.Platform.SavePlatform(v); err != nil {
|
oldPlatform := stack.PlatformManager.Remove(model.ServerAddr)
|
||||||
stack.PlatformManager.Remove(v.ServerAddr)
|
if oldPlatform != nil {
|
||||||
log.Sugar.Errorf("保存级联设备失败 err: %s", err.Error())
|
oldPlatform.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新数据库
|
||||||
|
id, _ := strconv.ParseInt(v.ID, 10, 64)
|
||||||
|
model.ID = uint(id)
|
||||||
|
err = dao.Platform.UpdatePlatform(&model)
|
||||||
|
} else {
|
||||||
|
err = dao.Platform.SavePlatform(&model)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil && v.Enable {
|
||||||
|
if !stack.PlatformManager.Add(model.ServerAddr, platform) {
|
||||||
|
err = fmt.Errorf("地址冲突. key: %s", model.ServerAddr)
|
||||||
|
if err != nil {
|
||||||
|
_ = dao.Platform.DeletePlatformByAddr(model.ServerAddr)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
platform.Start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Sugar.Errorf("添加级联设备失败 err: %s", err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
platform.Start()
|
return "OK", nil
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ApiServer) OnPlatformRemove(v *dao.PlatformModel, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
func (api *ApiServer) OnPlatformRemove(v *SetEnable, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
||||||
log.Sugar.Debugf("删除级联设备 %v", *v)
|
log.Sugar.Debugf("删除级联设备 %v", *v)
|
||||||
|
platform, _ := dao.Platform.QueryPlatformByID(v.ID)
|
||||||
err := dao.Platform.DeleteUAByAddr(v.ServerAddr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
} else if platform := stack.PlatformManager.Remove(v.ServerAddr); platform != nil {
|
|
||||||
platform.Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *ApiServer) OnPlatformList(_ http.ResponseWriter, _ *http.Request) {
|
|
||||||
//platforms := LoadPlatforms()
|
|
||||||
//httpResponseOK(w, platforms)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (api *ApiServer) OnPlatformChannelBind(v *PlatformChannel, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
|
||||||
log.Sugar.Debugf("级联绑定通道 %v", *v)
|
|
||||||
|
|
||||||
platform := stack.PlatformManager.Find(v.ServerAddr)
|
|
||||||
if platform == nil {
|
if platform == nil {
|
||||||
log.Sugar.Errorf("绑定通道失败, 级联设备不存在 addr: %s", v.ServerAddr)
|
return nil, fmt.Errorf("级联设备不存在")
|
||||||
return nil, fmt.Errorf("not found platform")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 级联功能,通道号必须唯一
|
_ = dao.Platform.DeletePlatformByID(v.ID)
|
||||||
channels, err := dao.Platform.BindChannels(v.ServerAddr, v.Channels)
|
client := stack.PlatformManager.Remove(platform.ServerAddr)
|
||||||
if err != nil {
|
if client != nil {
|
||||||
log.Sugar.Errorf("绑定通道失败 err: %s", err.Error())
|
client.Stop()
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return channels, nil
|
return "OK", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ApiServer) OnPlatformChannelUnbind(v *PlatformChannel, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
func (api *ApiServer) OnPlatformList(q *QueryDeviceChannel, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
||||||
log.Sugar.Debugf("级联解绑通道 %v", *v)
|
response := struct {
|
||||||
|
CascadeCount int `json:"CascadeCount"`
|
||||||
|
CascadeList []*LiveGBSCascade `json:"CascadeList"`
|
||||||
|
}{}
|
||||||
|
|
||||||
platform := stack.PlatformManager.Find(v.ServerAddr)
|
platforms, total, err := dao.Platform.QueryPlatforms((q.Start/q.Limit)+1, q.Limit, q.Keyword, q.Enable, q.Online)
|
||||||
if platform == nil {
|
if err == nil {
|
||||||
log.Sugar.Errorf("解绑通道失败, 级联设备不存在 addr: %s", v.ServerAddr)
|
response.CascadeCount = total
|
||||||
return nil, fmt.Errorf("not found platform")
|
for _, platform := range platforms {
|
||||||
|
host, p, _ := net.SplitHostPort(platform.ServerAddr)
|
||||||
|
port, _ := strconv.Atoi(p)
|
||||||
|
response.CascadeList = append(response.CascadeList, &LiveGBSCascade{
|
||||||
|
ID: strconv.Itoa(int(platform.ID)),
|
||||||
|
Enable: platform.Enable,
|
||||||
|
Name: platform.Name,
|
||||||
|
Serial: platform.ServerID,
|
||||||
|
Realm: platform.ServerID[:10],
|
||||||
|
Host: host,
|
||||||
|
Port: port,
|
||||||
|
LocalSerial: platform.Username,
|
||||||
|
Username: platform.Username,
|
||||||
|
Password: platform.Password,
|
||||||
|
Online: platform.Status == common.ON,
|
||||||
|
Status: platform.Status,
|
||||||
|
RegisterInterval: platform.RegisterExpires,
|
||||||
|
KeepaliveInterval: platform.KeepaliveInterval,
|
||||||
|
CommandTransport: platform.Transport,
|
||||||
|
Charset: "GB2312",
|
||||||
|
CatalogGroupSize: 1,
|
||||||
|
LoadLimit: 0,
|
||||||
|
CivilCodeLimit: 8,
|
||||||
|
DigestAlgorithm: "",
|
||||||
|
GM: false,
|
||||||
|
Cert: "***",
|
||||||
|
CreateAt: platform.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||||
|
UpdateAt: platform.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *ApiServer) OnPlatformChannelBind(w http.ResponseWriter, r *http.Request) {
|
||||||
|
idStr := r.FormValue("id")
|
||||||
|
channels := r.Form["channels[]"]
|
||||||
|
|
||||||
|
var err error
|
||||||
|
id, _ := strconv.Atoi(idStr)
|
||||||
|
_, err = dao.Platform.QueryPlatformByID(id)
|
||||||
|
if err == nil {
|
||||||
|
err = dao.Platform.BindChannels(id, channels)
|
||||||
}
|
}
|
||||||
|
|
||||||
channels, err := dao.Platform.UnbindChannels(v.ServerAddr, v.Channels)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Sugar.Errorf("解绑通道失败 err: %s", err.Error())
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
return nil, err
|
_ = common.HttpResponseJson(w, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = common.HttpResponseJson(w, "OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *ApiServer) OnPlatformChannelUnbind(w http.ResponseWriter, r *http.Request) {
|
||||||
|
idStr := r.FormValue("id")
|
||||||
|
channels := r.Form["channels[]"]
|
||||||
|
|
||||||
|
var err error
|
||||||
|
id, _ := strconv.Atoi(idStr)
|
||||||
|
_, err = dao.Platform.QueryPlatformByID(id)
|
||||||
|
if err == nil {
|
||||||
|
err = dao.Platform.UnbindChannels(id, channels)
|
||||||
}
|
}
|
||||||
|
|
||||||
return channels, nil
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
_ = common.HttpResponseJson(w, err.Error())
|
||||||
|
} else {
|
||||||
|
_ = common.HttpResponseJson(w, "OK")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ApiServer) OnDeviceMediaTransportSet(req *SetMediaTransportReq, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
func (api *ApiServer) OnDeviceMediaTransportSet(req *SetMediaTransportReq, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
|
||||||
@@ -1318,7 +1370,7 @@ func (api *ApiServer) OnDeviceTree(q *QueryDeviceChannel, w http.ResponseWriter,
|
|||||||
if q.PCode == "" {
|
if q.PCode == "" {
|
||||||
q.PCode = q.DeviceID
|
q.PCode = q.DeviceID
|
||||||
}
|
}
|
||||||
channels, _, _ := dao.Channel.QueryChannels(q.DeviceID, q.PCode, -1, 0, "", "", "asc", "")
|
channels, _, _ := dao.Channel.QueryChannels(q.DeviceID, q.PCode, -1, 0, "", "", "asc", "", false)
|
||||||
for _, channel := range channels {
|
for _, channel := range channels {
|
||||||
id := channel.RootID + ":" + channel.DeviceID
|
id := channel.RootID + ":" + channel.DeviceID
|
||||||
latitude, _ := strconv.ParseFloat(channel.Latitude, 10)
|
latitude, _ := strconv.ParseFloat(channel.Latitude, 10)
|
||||||
@@ -1365,3 +1417,141 @@ func (api *ApiServer) OnDeviceRemove(q *DeleteDevice, w http.ResponseWriter, req
|
|||||||
|
|
||||||
return "OK", nil
|
return "OK", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *ApiServer) OnEnableSet(params *SetEnable, w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
model, err := dao.Platform.QueryPlatformByID(params.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = dao.Platform.UpdateEnable(params.ID, params.Enable)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Enable {
|
||||||
|
if stack.PlatformManager.Find(model.ServerAddr) != nil {
|
||||||
|
return nil, errors.New("device already started")
|
||||||
|
}
|
||||||
|
|
||||||
|
platform, err := stack.NewPlatform(&model.SIPUAOptions, common.SipStack)
|
||||||
|
if err != nil {
|
||||||
|
_ = dao.Platform.UpdateEnable(params.ID, false)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stack.PlatformManager.Add(platform.ServerAddr, platform)
|
||||||
|
platform.Start()
|
||||||
|
} else if client := stack.PlatformManager.Remove(model.ServerAddr); client != nil {
|
||||||
|
client.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *ApiServer) OnPlatformChannelList(q *QueryCascadeChannelList, w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
response := struct {
|
||||||
|
ChannelCount int `json:"ChannelCount"`
|
||||||
|
ChannelList []*CascadeChannel `json:"ChannelList"`
|
||||||
|
|
||||||
|
ChannelRelateCount *int `json:"ChannelRelateCount,omitempty"`
|
||||||
|
ShareAllChannel *bool `json:"ShareAllChannel,omitempty"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
id, err := strconv.Atoi(q.ID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// livegbs前端, 如果开启级联所有通道, 是不允许再只看已选择或取消绑定通道
|
||||||
|
platform, err := dao.Platform.QueryPlatformByID(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只看已选择
|
||||||
|
if q.Related == true {
|
||||||
|
list, total, err := dao.Platform.QueryPlatformChannelList(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response.ChannelCount = total
|
||||||
|
ChannelList := ChannelModels2LiveGBSChannels(q.Start+1, list, "")
|
||||||
|
for _, channel := range ChannelList {
|
||||||
|
response.ChannelList = append(response.ChannelList, &CascadeChannel{
|
||||||
|
CascadeID: q.ID,
|
||||||
|
LiveGBSChannel: channel,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
list, err := api.OnChannelList(&q.QueryDeviceChannel, w, req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := list.(*ChannelListResult)
|
||||||
|
response.ChannelCount = result.ChannelCount
|
||||||
|
|
||||||
|
for _, channel := range result.ChannelList {
|
||||||
|
var cascadeId string
|
||||||
|
if exist, _ := dao.Platform.QueryPlatformChannelExist(id, channel.DeviceID, channel.ID); exist {
|
||||||
|
cascadeId = q.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断该通道是否选中
|
||||||
|
response.ChannelList = append(response.ChannelList, &CascadeChannel{
|
||||||
|
cascadeId, channel,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
response.ChannelRelateCount = new(int)
|
||||||
|
response.ShareAllChannel = new(bool)
|
||||||
|
|
||||||
|
// 级联设备通道总数
|
||||||
|
if count, err := dao.Platform.QueryPlatformChannelCount(id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
response.ChannelRelateCount = &count
|
||||||
|
}
|
||||||
|
|
||||||
|
*response.ShareAllChannel = platform.ShareAll
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *ApiServer) OnShareAllChannel(q *SetEnable, w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
var err error
|
||||||
|
if q.ShareAllChannel {
|
||||||
|
// 删除所有已经绑定的通道, 设置级联所有通道为true
|
||||||
|
if err = dao.Platform.DeletePlatformChannels(q.ID); err == nil {
|
||||||
|
err = dao.Platform.SetShareAllChannel(q.ID, true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 设置级联所有通道为false
|
||||||
|
err = dao.Platform.SetShareAllChannel(q.ID, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *ApiServer) OnCustomChannelSet(q *CustomChannel, w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
if len(q.CustomID) != 20 {
|
||||||
|
return nil, fmt.Errorf("20位国标ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := dao.Channel.UpdateCustomID(q.DeviceID, q.ChannelID, q.CustomID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return "OK", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *ApiServer) OnCatalogPush(q *SetEnable, w http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||||
|
return "OK", nil
|
||||||
|
}
|
||||||
|
@@ -27,6 +27,16 @@ func parseQueryParams(c func(key string) string, v interface{}) (interface{}, er
|
|||||||
field := typ.Field(i)
|
field := typ.Field(i)
|
||||||
fieldValue := val.Field(i)
|
fieldValue := val.Field(i)
|
||||||
|
|
||||||
|
// 处理组合字段
|
||||||
|
if field.Anonymous {
|
||||||
|
embedded := reflect.New(field.Type).Elem()
|
||||||
|
if _, err := parseQueryParams(c, embedded.Addr().Interface()); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fieldValue.Set(embedded)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// 获取字段名
|
// 获取字段名
|
||||||
fieldName := field.Tag.Get("json")
|
fieldName := field.Tag.Get("json")
|
||||||
if fieldName == "" {
|
if fieldName == "" {
|
||||||
|
@@ -12,22 +12,6 @@ func (d *BlacklistModel) TableName() string {
|
|||||||
return "lkm_blacklist"
|
return "lkm_blacklist"
|
||||||
}
|
}
|
||||||
|
|
||||||
type DaoBlacklist interface {
|
|
||||||
Load() ([]*BlacklistModel, error)
|
|
||||||
|
|
||||||
SaveIP(ip string) error
|
|
||||||
|
|
||||||
DeleteIP(ip string) error
|
|
||||||
|
|
||||||
SaveUA(ua string) error
|
|
||||||
|
|
||||||
DeleteUA(ua string) error
|
|
||||||
|
|
||||||
QueryIP(ip string) (*BlacklistModel, error)
|
|
||||||
|
|
||||||
QueryUA(ua string) (*BlacklistModel, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type daoBlacklist struct {
|
type daoBlacklist struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,6 +53,7 @@ type ChannelModel struct {
|
|||||||
ChannelNumber int `json:"channel_number" xml:"-"` // 对应1078的通道号
|
ChannelNumber int `json:"channel_number" xml:"-"` // 对应1078的通道号
|
||||||
SubCount int `json:"-" xml:"-"` // 子节点数量
|
SubCount int `json:"-" xml:"-"` // 子节点数量
|
||||||
IsDir bool `json:"-" xml:"-"` // 是否是目录
|
IsDir bool `json:"-" xml:"-"` // 是否是目录
|
||||||
|
CustomID *string `gorm:"unique"` // 自定义通道ID
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *ChannelModel) TableName() string {
|
func (d *ChannelModel) TableName() string {
|
||||||
@@ -63,54 +64,6 @@ func (d *ChannelModel) Online() bool {
|
|||||||
return d.Status == common.ON
|
return d.Status == common.ON
|
||||||
}
|
}
|
||||||
|
|
||||||
type DaoChannel interface {
|
|
||||||
SaveChannel(channel *ChannelModel) error
|
|
||||||
|
|
||||||
SaveChannels(channel []*ChannelModel) error
|
|
||||||
|
|
||||||
UpdateChannelStatus(deviceId, channelId, status string) error
|
|
||||||
|
|
||||||
QueryChannelByID(id uint) (*ChannelModel, error)
|
|
||||||
|
|
||||||
QueryChannel(deviceId string, channelId string) (*ChannelModel, error)
|
|
||||||
|
|
||||||
QueryChannels(deviceId, groupId, string, page, size int, keyword string, order string) ([]*ChannelModel, int, error)
|
|
||||||
|
|
||||||
QueryChannelsByRootID(rootId string) ([]*ChannelModel, error)
|
|
||||||
|
|
||||||
QueryChannelsByChannelID(channelId string) ([]*ChannelModel, error)
|
|
||||||
|
|
||||||
QueryChanelCount(deviceId string, hasDir bool) (int, error)
|
|
||||||
|
|
||||||
QuerySubChannelCount(deviceId string, groupId string, hasDir bool) (int, error)
|
|
||||||
|
|
||||||
QueryOnlineChanelCount(deviceId string, hasDir bool) (int, error)
|
|
||||||
|
|
||||||
QueryOnlineSubChannelCount(deviceId string, groupId string, hasDir bool) (int, error)
|
|
||||||
|
|
||||||
QueryChannelByTypeCode(codecs ...int) ([]*ChannelModel, error)
|
|
||||||
|
|
||||||
ExistChannel(channelId string) bool
|
|
||||||
|
|
||||||
SaveJTChannel(channel *ChannelModel) error
|
|
||||||
|
|
||||||
ExistJTChannel(simNumber string, channelNumber int) bool
|
|
||||||
|
|
||||||
QueryJTChannelBySimNumber(simNumber string) (*ChannelModel, error)
|
|
||||||
|
|
||||||
DeleteChannel(deviceId string, channelId string) error
|
|
||||||
|
|
||||||
DeleteChannels(deviceId string) error
|
|
||||||
|
|
||||||
UpdateRootID(rootId, newRootId string) error
|
|
||||||
|
|
||||||
UpdateChannel(channel *ChannelModel) error
|
|
||||||
|
|
||||||
TotalCount() (int, error)
|
|
||||||
|
|
||||||
OnlineCount(ids []string) (int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type daoChannel struct {
|
type daoChannel struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,15 +105,21 @@ func (d *daoChannel) QueryChannel(deviceId string, channelId string) (*ChannelMo
|
|||||||
return &channel, nil
|
return &channel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoChannel) QueryChannels(deviceId, groupId string, page, size int, status string, keyword string, order, sort string) ([]*ChannelModel, int, error) {
|
func (d *daoChannel) QueryChannels(deviceId, groupId string, page, size int, status string, keyword string, order, sort string, isDir bool) ([]*ChannelModel, int, error) {
|
||||||
conditions := map[string]interface{}{}
|
conditions := map[string]interface{}{}
|
||||||
conditions["root_id"] = deviceId
|
if deviceId != "" {
|
||||||
|
conditions["root_id"] = deviceId
|
||||||
|
}
|
||||||
|
|
||||||
if groupId != "" {
|
if groupId != "" {
|
||||||
conditions["group_id"] = groupId
|
conditions["group_id"] = groupId
|
||||||
}
|
}
|
||||||
if status != "" {
|
if status != "" {
|
||||||
conditions["status"] = status
|
conditions["status"] = status
|
||||||
}
|
}
|
||||||
|
if isDir {
|
||||||
|
conditions["is_dir"] = 1
|
||||||
|
}
|
||||||
|
|
||||||
cTx := db.Where(conditions)
|
cTx := db.Where(conditions)
|
||||||
|
|
||||||
@@ -278,6 +237,16 @@ func (d *daoChannel) QueryChannelsByChannelID(channelId string) ([]*ChannelModel
|
|||||||
return channels, nil
|
return channels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QueryChannelByCustomID 根据自定义通道ID查询通道
|
||||||
|
func (d *daoChannel) QueryChannelByCustomID(customID string) (*ChannelModel, error) {
|
||||||
|
var channel ChannelModel
|
||||||
|
tx := db.Where("custom_id =?", customID).Take(&channel)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return nil, tx.Error
|
||||||
|
}
|
||||||
|
return &channel, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (d *daoChannel) UpdateRootID(rootId, newRootId string) error {
|
func (d *daoChannel) UpdateRootID(rootId, newRootId string) error {
|
||||||
channel := &ChannelModel{
|
channel := &ChannelModel{
|
||||||
RootID: newRootId,
|
RootID: newRootId,
|
||||||
@@ -335,3 +304,8 @@ func (d *daoChannel) QueryOnlineSubChannelCount(rootId string, groupId string, h
|
|||||||
}
|
}
|
||||||
return int(total), nil
|
return int(total), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateCustomID 更新自定义通道ID
|
||||||
|
func (d *daoChannel) UpdateCustomID(rootId, channelId string, customID string) error {
|
||||||
|
return db.Model(&ChannelModel{}).Where("root_id =? and device_id =?", rootId, channelId).Update("custom_id", customID).Error
|
||||||
|
}
|
||||||
|
@@ -44,36 +44,6 @@ func (d *DeviceModel) GetID() string {
|
|||||||
return d.DeviceID
|
return d.DeviceID
|
||||||
}
|
}
|
||||||
|
|
||||||
type DaoDevice interface {
|
|
||||||
LoadOnlineDevices() (map[string]*DeviceModel, error)
|
|
||||||
|
|
||||||
LoadDevices() (map[string]*DeviceModel, error)
|
|
||||||
|
|
||||||
SaveDevice(device *DeviceModel) error
|
|
||||||
|
|
||||||
RefreshHeartbeat(deviceId string, now time.Time, addr string) error
|
|
||||||
|
|
||||||
QueryDevice(id string) (*DeviceModel, error)
|
|
||||||
|
|
||||||
QueryDevices(page int, size int, status string, keyword string, order string) ([]*DeviceModel, int, error)
|
|
||||||
|
|
||||||
UpdateDeviceStatus(deviceId string, status common.OnlineStatus) error
|
|
||||||
|
|
||||||
UpdateDeviceInfo(deviceId string, device *DeviceModel) error
|
|
||||||
|
|
||||||
UpdateOfflineDevices(deviceIds []string) error
|
|
||||||
|
|
||||||
ExistDevice(deviceId string) bool
|
|
||||||
|
|
||||||
UpdateMediaTransport(deviceId string, setupType common.SetupType) error
|
|
||||||
|
|
||||||
DeleteDevice(deviceId string) error
|
|
||||||
|
|
||||||
DeleteDevicesByIP(ip string) error
|
|
||||||
|
|
||||||
DeleteDevicesByUA(ua string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type daoDevice struct {
|
type daoDevice struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +83,7 @@ func (d *daoDevice) SaveDevice(device *DeviceModel) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
} else {
|
} else {
|
||||||
return tx.Model(device).Select("Transport", "RemoteAddr", "Status", "RegisterTime", "LastHeartbeat").Updates(*device).Error
|
return tx.Model(device).Select("Transport", "RemoteIP", "RemotePort", "Status", "RegisterTime", "LastHeartbeat").Updates(*device).Error
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
23
dao/jt.go
23
dao/jt.go
@@ -30,29 +30,6 @@ func (g *JTDeviceModel) TableName() string {
|
|||||||
return "lkm_jt_device"
|
return "lkm_jt_device"
|
||||||
}
|
}
|
||||||
|
|
||||||
// DaoJTDevice 保存级联和1078设备的sipua参数项
|
|
||||||
type DaoJTDevice interface {
|
|
||||||
LoadDevices() ([]*JTDeviceModel, error)
|
|
||||||
|
|
||||||
UpdateOnlineStatus(status common.OnlineStatus, username string) error
|
|
||||||
|
|
||||||
QueryDevice(user string) (*JTDeviceModel, error)
|
|
||||||
|
|
||||||
QueryDeviceBySimNumber(simNumber string) (*JTDeviceModel, error)
|
|
||||||
|
|
||||||
QueryDeviceByID(id uint) (*JTDeviceModel, error)
|
|
||||||
|
|
||||||
ExistDevice(username, simNumber string) bool
|
|
||||||
|
|
||||||
DeleteDevice(username string) error
|
|
||||||
|
|
||||||
SaveDevice(model *JTDeviceModel) error
|
|
||||||
|
|
||||||
UpdateDevice(model *JTDeviceModel) error
|
|
||||||
|
|
||||||
QueryDevices(page int, size int) ([]*JTDeviceModel, int, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type daoJTDevice struct {
|
type daoJTDevice struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
267
dao/platform.go
267
dao/platform.go
@@ -2,39 +2,31 @@ package dao
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gb-cms/common"
|
"gb-cms/common"
|
||||||
"gb-cms/log"
|
"gorm.io/gorm"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PlatformModel 数据库表结构
|
// PlatformModel 数据库表结构
|
||||||
type PlatformModel struct {
|
type PlatformModel struct {
|
||||||
GBModel
|
GBModel
|
||||||
common.SIPUAOptions
|
common.SIPUAOptions
|
||||||
|
Enable bool // 启用/禁用
|
||||||
|
ShareAll bool // 级联所有通道
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *PlatformModel) TableName() string {
|
func (g *PlatformModel) TableName() string {
|
||||||
return "lkm_platform"
|
return "lkm_platform"
|
||||||
}
|
}
|
||||||
|
|
||||||
// DaoVirtualDevice 保存级联和1078设备的sipua参数项
|
type PlatformChannelModel struct {
|
||||||
type DaoVirtualDevice interface {
|
GBModel
|
||||||
LoadPlatforms() ([]*PlatformModel, error)
|
DeviceID string `json:"device_id"`
|
||||||
|
ChannelID string `json:"channel_id"`
|
||||||
|
PID uint `json:"pid"` // 级联设备数据库ID
|
||||||
|
}
|
||||||
|
|
||||||
QueryPlatform(addr string) (*PlatformModel, error)
|
func (d *PlatformChannelModel) TableName() string {
|
||||||
|
return "lkm_platform_channel"
|
||||||
SavePlatform(platform *PlatformModel) error
|
|
||||||
|
|
||||||
DeletePlatform(addr string) error
|
|
||||||
|
|
||||||
UpdatePlatform(platform *PlatformModel) error
|
|
||||||
|
|
||||||
BindChannels(addr string, channels [][2]string) ([][2]string, error)
|
|
||||||
|
|
||||||
UnbindChannels(addr string, channels [][2]string) ([][2]string, error)
|
|
||||||
|
|
||||||
// QueryPlatformChannel 查询级联设备的某个通道, 返回通道所属设备ID、通道.
|
|
||||||
QueryPlatformChannel(addr string, channelId string) (string, *ChannelModel, error)
|
|
||||||
|
|
||||||
QueryPlatformChannels(addr string) ([]*ChannelModel, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type daoPlatform struct {
|
type daoPlatform struct {
|
||||||
@@ -50,7 +42,7 @@ func (d *daoPlatform) LoadPlatforms() ([]*PlatformModel, error) {
|
|||||||
return platforms, nil
|
return platforms, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) QueryUAByAddr(addr string) (*PlatformModel, error) {
|
func (d *daoPlatform) QueryPlatformByAddr(addr string) (*PlatformModel, error) {
|
||||||
var platform PlatformModel
|
var platform PlatformModel
|
||||||
tx := db.Where("server_addr =?", addr).First(&platform)
|
tx := db.Where("server_addr =?", addr).First(&platform)
|
||||||
if tx.Error != nil {
|
if tx.Error != nil {
|
||||||
@@ -69,95 +61,232 @@ func (d *daoPlatform) SavePlatform(platform *PlatformModel) error {
|
|||||||
return db.Save(platform).Error
|
return db.Save(platform).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) DeleteUAByAddr(addr string) error {
|
func (d *daoPlatform) DeletePlatformByAddr(addr string) error {
|
||||||
|
// 删除绑定的通道
|
||||||
return db.Where("server_addr =?", addr).Unscoped().Delete(&PlatformModel{}).Error
|
return db.Where("server_addr =?", addr).Unscoped().Delete(&PlatformModel{}).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) UpdatePlatform(platform *PlatformModel) error {
|
func (d *daoPlatform) UpdatePlatform(platform *PlatformModel) error {
|
||||||
//TODO implement me
|
return DBTransaction(func(tx *gorm.DB) error {
|
||||||
panic("implement me")
|
return tx.Save(platform).Error
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) UpdateOnlineStatus(status common.OnlineStatus, addr string) error {
|
func (d *daoPlatform) UpdateOnlineStatus(status common.OnlineStatus, addr string) error {
|
||||||
return db.Model(&PlatformModel{}).Where("server_addr =?", addr).Update("status", status).Error
|
return db.Model(&PlatformModel{}).Where("server_addr =?", addr).Update("status", status).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
type PlatformChannelModel struct {
|
func (d *daoPlatform) BindChannels(pid int, channels []string) error {
|
||||||
GBModel
|
return DBTransaction(func(tx *gorm.DB) error {
|
||||||
DeviceID string `json:"device_id"`
|
for _, channel := range channels {
|
||||||
Channel string `json:"channel_id"`
|
ids := strings.Split(channel, ":")
|
||||||
ServerAddr string `json:"server_addr"`
|
var old PlatformChannelModel
|
||||||
}
|
// 检查是否已经绑定
|
||||||
|
tx.Where("device_id =? and channel_id =? and p_id =?", ids[0], ids[1], pid).First(&old)
|
||||||
|
if old.ID != 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
func (d *PlatformChannelModel) TableName() string {
|
// 检查通道是否存在
|
||||||
return "lkm_platform_channel"
|
_, err := Channel.QueryChannel(ids[0], ids[1])
|
||||||
}
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) BindChannels(addr string, channels [][2]string) ([][2]string, error) {
|
// 插入绑定关系
|
||||||
var res [][2]string
|
_ = tx.Create(&PlatformChannelModel{
|
||||||
for _, channel := range channels {
|
DeviceID: ids[0],
|
||||||
|
ChannelID: ids[1],
|
||||||
var old PlatformChannelModel
|
PID: uint(pid),
|
||||||
_ = db.Where("device_id =? and channel_id =? and server_addr =?", channel[0], channel[1], addr).First(&old)
|
|
||||||
if old.ID == 0 {
|
|
||||||
_ = db.Create(&PlatformChannelModel{
|
|
||||||
DeviceID: channel[0],
|
|
||||||
Channel: channel[1],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
res = append(res, channel)
|
return nil
|
||||||
}
|
})
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) UnbindChannels(addr string, channels [][2]string) ([][2]string, error) {
|
func (d *daoPlatform) UnbindChannels(pid int, channels []string) error {
|
||||||
var res [][2]string
|
return DBTransaction(func(tx *gorm.DB) error {
|
||||||
for _, channel := range channels {
|
for _, channel := range channels {
|
||||||
tx := db.Unscoped().Delete(&PlatformChannelModel{}, "device_id =? and channel_id =? and server_addr =?", channel[0], channel[1], addr)
|
ids := strings.Split(channel, ":")
|
||||||
if tx.Error == nil {
|
tx.Unscoped().Delete(&PlatformChannelModel{}, "device_id =? and channel_id =? and p_id =?", ids[0], ids[1], pid)
|
||||||
res = append(res, channel)
|
|
||||||
} else {
|
|
||||||
log.Sugar.Errorf("解绑级联设备通道失败. device_id: %s, channel_id: %s err: %s", channel[0], channel[1], tx.Error)
|
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
|
})
|
||||||
return res, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) QueryPlatformChannel(addr string, channelId string) (string, *ChannelModel, error) {
|
func (d *daoPlatform) QueryPlatformChannel(addr string, channelId string) (string, *ChannelModel, error) {
|
||||||
|
model, err := d.QueryPlatformByAddr(addr)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if model.ShareAll {
|
||||||
|
channel, _ := Channel.QueryChannelByCustomID(channelId)
|
||||||
|
if channel != nil {
|
||||||
|
return channel.RootID, channel, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
channels, err := Channel.QueryChannelsByChannelID(channelId)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, err
|
||||||
|
}
|
||||||
|
return channels[0].RootID, channels[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
var platformChannel PlatformChannelModel
|
var platformChannel PlatformChannelModel
|
||||||
tx := db.Model(&PlatformChannelModel{}).Where("channel_id =? and server_addr =?", channelId, addr).First(&platformChannel)
|
tx := db.Model(&PlatformChannelModel{}).Where("channel_id =? and p_id =?", channelId, model.ID).First(&platformChannel)
|
||||||
if tx.Error != nil {
|
if tx.Error != nil {
|
||||||
return "", nil, tx.Error
|
return "", nil, tx.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
var channel ChannelModel
|
// 优先查询自定义通道
|
||||||
tx = db.Where("device_id =? and channel_id =?", platformChannel.DeviceID, platformChannel.Channel).First(&channel)
|
channel, _ := Channel.QueryChannelByCustomID(channelId)
|
||||||
|
if channel != nil {
|
||||||
|
return channel.RootID, channel, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tx = db.Where("root_id =? and device_id =?", platformChannel.DeviceID, platformChannel.ChannelID).First(&channel)
|
||||||
if tx.Error != nil {
|
if tx.Error != nil {
|
||||||
return "", nil, tx.Error
|
return "", nil, tx.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
return platformChannel.DeviceID, &channel, nil
|
return channel.RootID, channel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *daoPlatform) QueryPlatformChannels(addr string) ([]*ChannelModel, error) {
|
func (d *daoPlatform) QueryPlatformChannels(addr string) ([]*ChannelModel, error) {
|
||||||
|
model, err := d.QueryPlatformByAddr(addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回所有通道
|
||||||
|
if model.ShareAll {
|
||||||
|
channels, _, _ := Channel.QueryChannels("", "", -1, -1, "", "", "", "", false)
|
||||||
|
return channels, nil
|
||||||
|
}
|
||||||
|
|
||||||
var platformChannels []*PlatformChannelModel
|
var platformChannels []*PlatformChannelModel
|
||||||
tx := db.Where("server_addr =?", addr).Find(&platformChannels)
|
tx := db.Where("p_id =?", model.ID).Find(&platformChannels)
|
||||||
if tx.Error != nil {
|
if tx.Error != nil {
|
||||||
return nil, tx.Error
|
return nil, tx.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
var channels []*ChannelModel
|
var channels []*ChannelModel
|
||||||
for _, platformChannel := range platformChannels {
|
for _, platformChannel := range platformChannels {
|
||||||
var channel ChannelModel
|
queryChannel, err := Channel.QueryChannel(platformChannel.DeviceID, platformChannel.ChannelID)
|
||||||
tx = db.Where("device_id =? and channel_id =?", platformChannel.DeviceID, platformChannel.Channel).First(&channel)
|
if err != nil {
|
||||||
if tx.Error == nil {
|
continue
|
||||||
channels = append(channels, &channel)
|
|
||||||
} else {
|
|
||||||
log.Sugar.Errorf("查询级联设备通道失败. device_id: %s, channel_id: %s err: %s", platformChannel.DeviceID, platformChannel.Channel, tx.Error)
|
|
||||||
}
|
}
|
||||||
|
channels = append(channels, queryChannel)
|
||||||
}
|
}
|
||||||
|
|
||||||
return channels, nil
|
return channels, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *daoPlatform) QueryPlatforms(page, size int, keyword, enable, status string) ([]*PlatformModel, int, error) {
|
||||||
|
var platforms []*PlatformModel
|
||||||
|
var total int64
|
||||||
|
query := db.Model(&PlatformModel{})
|
||||||
|
if keyword != "" {
|
||||||
|
query = query.Where("username like ?", "%"+keyword+"%")
|
||||||
|
}
|
||||||
|
|
||||||
|
if enable == "true" {
|
||||||
|
query = query.Where("enable = ?", 1)
|
||||||
|
} else if enable == "false" {
|
||||||
|
query = query.Where("enable = ?", 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if status == "true" {
|
||||||
|
query = query.Where("status = ?", "ON")
|
||||||
|
} else if status == "false" {
|
||||||
|
query = query.Where("status = ?", "OFF")
|
||||||
|
}
|
||||||
|
|
||||||
|
query.Count(&total)
|
||||||
|
query.Offset((page - 1) * size).Limit(size).Find(&platforms)
|
||||||
|
return platforms, int(total), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *daoPlatform) UpdateEnable(id int, enable bool) error {
|
||||||
|
return DBTransaction(func(tx *gorm.DB) error {
|
||||||
|
return tx.Model(&PlatformModel{}).Where("id =?", id).Update("enable", enable).Error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *daoPlatform) QueryPlatformByID(id int) (*PlatformModel, error) {
|
||||||
|
var platform PlatformModel
|
||||||
|
tx := db.Where("id =?", id).First(&platform)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return nil, tx.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return &platform, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *daoPlatform) DeletePlatformByID(id int) error {
|
||||||
|
return DBTransaction(func(tx *gorm.DB) error {
|
||||||
|
return tx.Unscoped().Delete(&PlatformModel{}, id).Error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryPlatformChannelList 查询级联设备通道列表
|
||||||
|
func (d *daoPlatform) QueryPlatformChannelList(id int) ([]*ChannelModel, int, error) {
|
||||||
|
var platformChannels []*PlatformChannelModel
|
||||||
|
tx := db.Where("p_id =?", id).Find(&platformChannels)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return nil, 0, tx.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询通道总数
|
||||||
|
count, err := d.QueryPlatformChannelCount(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var channels []*ChannelModel
|
||||||
|
for _, platformChannel := range platformChannels {
|
||||||
|
channel, err := Channel.QueryChannel(platformChannel.DeviceID, platformChannel.ChannelID)
|
||||||
|
if err == nil {
|
||||||
|
channels = append(channels, channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return channels, count, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryPlatformChannelCount 查询级联设备的通道总数
|
||||||
|
func (d *daoPlatform) QueryPlatformChannelCount(id int) (int, error) {
|
||||||
|
var total int64
|
||||||
|
tx := db.Model(&PlatformChannelModel{}).Where("p_id =?", id).Count(&total)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return 0, tx.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return int(total), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryPlatformChannelExist 查询某个通道是否绑定到某个级联设备
|
||||||
|
func (d *daoPlatform) QueryPlatformChannelExist(pid int, deviceId, channelId string) (bool, error) {
|
||||||
|
var total int64
|
||||||
|
tx := db.Model(&PlatformChannelModel{}).Where("p_id =? and device_id =? and channel_id =?", pid, deviceId, channelId).Count(&total)
|
||||||
|
if tx.Error != nil {
|
||||||
|
return false, tx.Error
|
||||||
|
}
|
||||||
|
|
||||||
|
return total > 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeletePlatformChannels 删除级联设备的所有通道
|
||||||
|
func (d *daoPlatform) DeletePlatformChannels(id int) error {
|
||||||
|
return DBTransaction(func(tx *gorm.DB) error {
|
||||||
|
return tx.Unscoped().Delete(&PlatformChannelModel{}, "p_id =?", id).Error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetShareAllChannel 设置级联设备是否分享所有通道
|
||||||
|
func (d *daoPlatform) SetShareAllChannel(id int, shareAll bool) error {
|
||||||
|
return DBTransaction(func(tx *gorm.DB) error {
|
||||||
|
return tx.Model(&PlatformModel{}).Where("id =?", id).Update("share_all", shareAll).Error
|
||||||
|
})
|
||||||
|
}
|
||||||
|
28
dao/sink.go
28
dao/sink.go
@@ -24,34 +24,6 @@ func (d *SinkModel) TableName() string {
|
|||||||
return "lkm_sink"
|
return "lkm_sink"
|
||||||
}
|
}
|
||||||
|
|
||||||
type DaoSink interface {
|
|
||||||
LoadForwardSinks() (map[string]*SinkModel, error)
|
|
||||||
|
|
||||||
// QueryForwardSink 查询转发流Sink
|
|
||||||
QueryForwardSink(stream common.StreamID, sink string) (*SinkModel, error)
|
|
||||||
|
|
||||||
QueryForwardSinks(stream common.StreamID) (map[string]*SinkModel, error)
|
|
||||||
|
|
||||||
// SaveForwardSink 保存转发流Sink
|
|
||||||
SaveForwardSink(stream common.StreamID, sink *SinkModel) error
|
|
||||||
|
|
||||||
DeleteForwardSink(stream common.StreamID, sink string) (*SinkModel, error)
|
|
||||||
|
|
||||||
DeleteForwardSinksByStreamID(stream common.StreamID) ([]*SinkModel, error)
|
|
||||||
|
|
||||||
DeleteForwardSinks() ([]*SinkModel, error)
|
|
||||||
|
|
||||||
DeleteForwardSinksByIds(ids []uint) error
|
|
||||||
|
|
||||||
QueryForwardSinkByCallID(callID string) (*SinkModel, error)
|
|
||||||
|
|
||||||
DeleteForwardSinkByCallID(callID string) (*SinkModel, error)
|
|
||||||
|
|
||||||
DeleteForwardSinkBySinkStreamID(sinkStreamID common.StreamID) (*SinkModel, error)
|
|
||||||
|
|
||||||
DeleteForwardSinksByServerAddr(addr string) ([]*SinkModel, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type daoSink struct {
|
type daoSink struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,12 +9,12 @@ import (
|
|||||||
|
|
||||||
type StreamModel struct {
|
type StreamModel struct {
|
||||||
GBModel
|
GBModel
|
||||||
DeviceID string `gorm:"index"` // 下级设备ID, 统计某个设备的所有流/1078设备为sim number
|
DeviceID string `gorm:"index"` // 下级设备ID, 统计某个设备的所有流/1078设备为sim number
|
||||||
ChannelID string `gorm:"index"` // 下级通道ID, 统计某个设备下的某个通道的所有流/1078设备为 channel number
|
ChannelID string `gorm:"index"` // 下级通道ID, 统计某个设备下的某个通道的所有流/1078设备为 channel number
|
||||||
StreamID common.StreamID `json:"stream_id" gorm:"index"` // 流ID
|
StreamID common.StreamID `json:"stream_id" gorm:"index,unique"` // 流ID
|
||||||
Protocol int `json:"protocol,omitempty"` // 推流协议, rtmp/28181/1078/gb_talk
|
Protocol int `json:"protocol,omitempty"` // 推流协议, rtmp/28181/1078/gb_talk
|
||||||
Dialog *common.RequestWrapper `json:"dialog,omitempty"` // 国标流的SipCall会话
|
Dialog *common.RequestWrapper `json:"dialog,omitempty"` // 国标流的SipCall会话
|
||||||
SinkCount int32 `json:"sink_count"` // 拉流端计数(包含级联转发)
|
SinkCount int32 `json:"sink_count"` // 拉流端计数(包含级联转发)
|
||||||
SetupType common.SetupType
|
SetupType common.SetupType
|
||||||
CallID string `json:"call_id" gorm:"index"`
|
CallID string `json:"call_id" gorm:"index"`
|
||||||
Urls []string `gorm:"serializer:json"` // 从流媒体服务器返回的拉流地址
|
Urls []string `gorm:"serializer:json"` // 从流媒体服务器返回的拉流地址
|
||||||
@@ -31,30 +31,6 @@ func (s *StreamModel) SetDialog(dialog sip.Request) {
|
|||||||
s.CallID = id.Value()
|
s.CallID = id.Value()
|
||||||
}
|
}
|
||||||
|
|
||||||
type DaoStream interface {
|
|
||||||
LoadStreams() (map[string]*StreamModel, error)
|
|
||||||
|
|
||||||
SaveStream(stream *StreamModel) (*StreamModel, bool)
|
|
||||||
|
|
||||||
UpdateStream(stream *StreamModel) error
|
|
||||||
|
|
||||||
DeleteStream(streamId common.StreamID) (*StreamModel, error)
|
|
||||||
|
|
||||||
DeleteStreams() ([]*StreamModel, error)
|
|
||||||
|
|
||||||
DeleteStreamsByIds(ids []uint) error
|
|
||||||
|
|
||||||
QueryStream(streamId common.StreamID) (*StreamModel, error)
|
|
||||||
|
|
||||||
QueryStreams(keyword string, page, size int) ([]*StreamModel, int, error)
|
|
||||||
|
|
||||||
QueryStreamByCallID(callID string) (*StreamModel, error)
|
|
||||||
|
|
||||||
DeleteStreamByCallID(callID string) (*StreamModel, error)
|
|
||||||
|
|
||||||
DeleteStreamByDeviceID(deviceID string) ([]*StreamModel, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type daoStream struct {
|
type daoStream struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
261
livegbs_bean.go
261
livegbs_bean.go
@@ -1,5 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gb-cms/common"
|
||||||
|
"gb-cms/dao"
|
||||||
|
"gb-cms/stack"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
type LiveGBSDevice struct {
|
type LiveGBSDevice struct {
|
||||||
AlarmSubscribe bool `json:"AlarmSubscribe"`
|
AlarmSubscribe bool `json:"AlarmSubscribe"`
|
||||||
CatalogInterval int `json:"CatalogInterval"`
|
CatalogInterval int `json:"CatalogInterval"`
|
||||||
@@ -44,67 +51,67 @@ type LiveGBSDevice struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LiveGBSChannel struct {
|
type LiveGBSChannel struct {
|
||||||
Address string `json:"Address"`
|
Address string `json:"Address"`
|
||||||
Altitude int `json:"Altitude"`
|
Altitude int `json:"Altitude"`
|
||||||
AudioEnable bool `json:"AudioEnable"`
|
AudioEnable bool `json:"AudioEnable"`
|
||||||
BatteryLevel int `json:"BatteryLevel"`
|
BatteryLevel int `json:"BatteryLevel"`
|
||||||
Block string `json:"Block"`
|
Block string `json:"Block"`
|
||||||
Channel int `json:"Channel"`
|
Channel int `json:"Channel"`
|
||||||
CivilCode string `json:"CivilCode"`
|
CivilCode string `json:"CivilCode"`
|
||||||
CloudRecord bool `json:"CloudRecord"`
|
CloudRecord bool `json:"CloudRecord"`
|
||||||
CreatedAt string `json:"CreatedAt"`
|
CreatedAt string `json:"CreatedAt"`
|
||||||
Custom bool `json:"Custom"`
|
Custom bool `json:"Custom"`
|
||||||
CustomAddress string `json:"CustomAddress"`
|
CustomAddress string `json:"CustomAddress"`
|
||||||
CustomBlock string `json:"CustomBlock"`
|
CustomBlock string `json:"CustomBlock"`
|
||||||
CustomCivilCode string `json:"CustomCivilCode"`
|
CustomCivilCode string `json:"CustomCivilCode"`
|
||||||
CustomFirmware string `json:"CustomFirmware"`
|
CustomFirmware string `json:"CustomFirmware"`
|
||||||
CustomID string `json:"CustomID"`
|
CustomID string `json:"CustomID"`
|
||||||
CustomIPAddress string `json:"CustomIPAddress"`
|
CustomIPAddress string `json:"CustomIPAddress"`
|
||||||
CustomLatitude int `json:"CustomLatitude"`
|
CustomLatitude int `json:"CustomLatitude"`
|
||||||
CustomLongitude int `json:"CustomLongitude"`
|
CustomLongitude int `json:"CustomLongitude"`
|
||||||
CustomManufacturer string `json:"CustomManufacturer"`
|
CustomManufacturer string `json:"CustomManufacturer"`
|
||||||
CustomModel string `json:"CustomModel"`
|
CustomModel string `json:"CustomModel"`
|
||||||
CustomName string `json:"CustomName"`
|
CustomName string `json:"CustomName"`
|
||||||
CustomPTZType int `json:"CustomPTZType"`
|
CustomPTZType int `json:"CustomPTZType"`
|
||||||
CustomParentID string `json:"CustomParentID"`
|
CustomParentID string `json:"CustomParentID"`
|
||||||
CustomPort int `json:"CustomPort"`
|
CustomPort int `json:"CustomPort"`
|
||||||
CustomSerialNumber string `json:"CustomSerialNumber"`
|
CustomSerialNumber string `json:"CustomSerialNumber"`
|
||||||
CustomStatus string `json:"CustomStatus"`
|
CustomStatus string `json:"CustomStatus"`
|
||||||
Description string `json:"Description"`
|
Description string `json:"Description"`
|
||||||
DeviceCustomName string `json:"DeviceCustomName"`
|
DeviceCustomName string `json:"DeviceCustomName"`
|
||||||
DeviceID string `json:"DeviceID"`
|
DeviceID string `json:"DeviceID"`
|
||||||
DeviceName string `json:"DeviceName"`
|
DeviceName string `json:"DeviceName"`
|
||||||
DeviceOnline bool `json:"DeviceOnline"`
|
DeviceOnline bool `json:"DeviceOnline"`
|
||||||
DeviceType string `json:"DeviceType"`
|
DeviceType string `json:"DeviceType"`
|
||||||
Direction int `json:"Direction"`
|
Direction int `json:"Direction"`
|
||||||
DownloadSpeed string `json:"DownloadSpeed"`
|
DownloadSpeed string `json:"DownloadSpeed"`
|
||||||
Firmware string `json:"Firmware"`
|
Firmware string `json:"Firmware"`
|
||||||
ID string `json:"ID"`
|
ID string `json:"ID"`
|
||||||
IPAddress string `json:"IPAddress"`
|
IPAddress string `json:"IPAddress"`
|
||||||
Latitude int `json:"Latitude"`
|
Latitude float64 `json:"Latitude"`
|
||||||
Longitude int `json:"Longitude"`
|
Longitude float64 `json:"Longitude"`
|
||||||
Manufacturer string `json:"Manufacturer"`
|
Manufacturer string `json:"Manufacturer"`
|
||||||
Model string `json:"Model"`
|
Model string `json:"Model"`
|
||||||
Name string `json:"Name"`
|
Name string `json:"Name"`
|
||||||
NumOutputs int `json:"NumOutputs"`
|
NumOutputs int `json:"NumOutputs"`
|
||||||
Ondemand bool `json:"Ondemand"`
|
Ondemand bool `json:"Ondemand"`
|
||||||
Owner string `json:"Owner"`
|
Owner string `json:"Owner"`
|
||||||
PTZType int `json:"PTZType"`
|
PTZType int `json:"PTZType"`
|
||||||
ParentID string `json:"ParentID"`
|
ParentID string `json:"ParentID"`
|
||||||
Parental int `json:"Parental"`
|
Parental int `json:"Parental"`
|
||||||
Port int `json:"Port"`
|
Port int `json:"Port"`
|
||||||
Quality string `json:"Quality"`
|
Quality string `json:"Quality"`
|
||||||
RegisterWay int `json:"RegisterWay"`
|
RegisterWay int `json:"RegisterWay"`
|
||||||
Secrecy int `json:"Secrecy"`
|
Secrecy int `json:"Secrecy"`
|
||||||
SerialNumber string `json:"SerialNumber"`
|
SerialNumber string `json:"SerialNumber"`
|
||||||
Shared bool `json:"Shared"`
|
Shared bool `json:"Shared"`
|
||||||
SignalLevel int `json:"SignalLevel"`
|
SignalLevel int `json:"SignalLevel"`
|
||||||
SnapURL string `json:"SnapURL"`
|
SnapURL string `json:"SnapURL"`
|
||||||
Speed int `json:"Speed"`
|
Speed int `json:"Speed"`
|
||||||
Status string `json:"Status"`
|
Status string `json:"Status"`
|
||||||
StreamID string `json:"StreamID"`
|
StreamID string `json:"StreamID"`
|
||||||
SubCount int `json:"SubCount"`
|
SubCount int `json:"SubCount"`
|
||||||
UpdatedAt string `json:"UpdatedAt"`
|
UpdatedAt string `json:"UpdatedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LiveGBSStreamStart struct {
|
type LiveGBSStreamStart struct {
|
||||||
@@ -171,3 +178,135 @@ type LiveGBSDeviceTree struct {
|
|||||||
SubCount int `json:"subCount"` // 包含目录的总数
|
SubCount int `json:"subCount"` // 包含目录的总数
|
||||||
SubCountDevice int `json:"subCountDevice"` // 不包含目录的总数
|
SubCountDevice int `json:"subCountDevice"` // 不包含目录的总数
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type LiveGBSCascade struct {
|
||||||
|
Load int
|
||||||
|
Manufacturer string
|
||||||
|
ID string
|
||||||
|
Enable bool // 是否启用
|
||||||
|
Name string
|
||||||
|
Serial string // 上级ID
|
||||||
|
Realm string // 上级域
|
||||||
|
Host string // 上级IP
|
||||||
|
Port int // 上级端口
|
||||||
|
LocalSerial string
|
||||||
|
LocalHost string
|
||||||
|
LocalPort int
|
||||||
|
Username string // 向上级sip通信的用户名
|
||||||
|
Password string // 向上级注册的密码
|
||||||
|
Online bool
|
||||||
|
Status common.OnlineStatus
|
||||||
|
RegisterTimeout int
|
||||||
|
KeepaliveInterval int
|
||||||
|
RegisterInterval int
|
||||||
|
StreamKeepalive bool
|
||||||
|
StreamReader bool
|
||||||
|
BindLocalIP bool
|
||||||
|
AllowControl bool
|
||||||
|
ShareRecord bool
|
||||||
|
MergeRecord bool
|
||||||
|
ShareAllChannel bool
|
||||||
|
CommandTransport string
|
||||||
|
Charset string
|
||||||
|
CatalogGroupSize int
|
||||||
|
LoadLimit int
|
||||||
|
CivilCodeLimit int
|
||||||
|
DigestAlgorithm string
|
||||||
|
GM bool
|
||||||
|
Cert string
|
||||||
|
CreateAt string
|
||||||
|
UpdateAt string
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChannelModels2LiveGBSChannels(index int, channels []*dao.ChannelModel, deviceName string) []*LiveGBSChannel {
|
||||||
|
var ChannelList []*LiveGBSChannel
|
||||||
|
|
||||||
|
for _, channel := range channels {
|
||||||
|
parental, _ := strconv.Atoi(channel.Parental)
|
||||||
|
port, _ := strconv.Atoi(channel.Port)
|
||||||
|
registerWay, _ := strconv.Atoi(channel.RegisterWay)
|
||||||
|
secrecy, _ := strconv.Atoi(channel.Secrecy)
|
||||||
|
|
||||||
|
streamID := common.GenerateStreamID(common.InviteTypePlay, channel.RootID, channel.DeviceID, "", "")
|
||||||
|
if stream, err := dao.Stream.QueryStream(streamID); err != nil || stream == nil {
|
||||||
|
streamID = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
_, online := stack.OnlineDeviceManager.Find(channel.RootID)
|
||||||
|
// 转换经纬度
|
||||||
|
latitude, _ := strconv.ParseFloat(channel.Latitude, 64)
|
||||||
|
longitude, _ := strconv.ParseFloat(channel.Longitude, 64)
|
||||||
|
|
||||||
|
var customID string
|
||||||
|
if channel.CustomID != nil {
|
||||||
|
customID = *channel.CustomID
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelList = append(ChannelList, &LiveGBSChannel{
|
||||||
|
Address: channel.Address,
|
||||||
|
Altitude: 0,
|
||||||
|
AudioEnable: true,
|
||||||
|
BatteryLevel: 0,
|
||||||
|
Channel: index,
|
||||||
|
CivilCode: channel.CivilCode,
|
||||||
|
CloudRecord: false,
|
||||||
|
CreatedAt: channel.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||||
|
Custom: false,
|
||||||
|
CustomAddress: "",
|
||||||
|
CustomBlock: "",
|
||||||
|
CustomCivilCode: "",
|
||||||
|
CustomFirmware: "",
|
||||||
|
CustomID: customID,
|
||||||
|
CustomIPAddress: "",
|
||||||
|
CustomLatitude: 0,
|
||||||
|
CustomLongitude: 0,
|
||||||
|
CustomManufacturer: "",
|
||||||
|
CustomModel: "",
|
||||||
|
CustomName: "",
|
||||||
|
CustomPTZType: 0,
|
||||||
|
CustomParentID: "",
|
||||||
|
CustomPort: 0,
|
||||||
|
CustomSerialNumber: "",
|
||||||
|
CustomStatus: "",
|
||||||
|
Description: "",
|
||||||
|
DeviceCustomName: "",
|
||||||
|
DeviceID: channel.RootID,
|
||||||
|
DeviceName: deviceName,
|
||||||
|
DeviceOnline: online,
|
||||||
|
DeviceType: "GB",
|
||||||
|
Direction: 0,
|
||||||
|
DownloadSpeed: "",
|
||||||
|
Firmware: "",
|
||||||
|
ID: channel.DeviceID,
|
||||||
|
IPAddress: channel.IPAddress,
|
||||||
|
Latitude: latitude,
|
||||||
|
Longitude: longitude,
|
||||||
|
Manufacturer: channel.Manufacturer,
|
||||||
|
Model: channel.Model,
|
||||||
|
Name: channel.Name,
|
||||||
|
NumOutputs: 0,
|
||||||
|
Ondemand: true,
|
||||||
|
Owner: channel.Owner,
|
||||||
|
PTZType: 0,
|
||||||
|
ParentID: channel.ParentID,
|
||||||
|
Parental: parental,
|
||||||
|
Port: port,
|
||||||
|
Quality: "",
|
||||||
|
RegisterWay: registerWay,
|
||||||
|
Secrecy: secrecy,
|
||||||
|
SerialNumber: "",
|
||||||
|
Shared: false,
|
||||||
|
SignalLevel: 0,
|
||||||
|
SnapURL: "",
|
||||||
|
Speed: 0,
|
||||||
|
Status: channel.Status.String(),
|
||||||
|
StreamID: string(streamID), // 实时流ID
|
||||||
|
SubCount: channel.SubCount,
|
||||||
|
UpdatedAt: channel.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||||
|
})
|
||||||
|
|
||||||
|
index++
|
||||||
|
}
|
||||||
|
|
||||||
|
return ChannelList
|
||||||
|
}
|
||||||
|
12
recover.go
12
recover.go
@@ -18,15 +18,19 @@ func startPlatformDevices() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, record := range platforms {
|
for _, record := range platforms {
|
||||||
|
if err := dao.Platform.UpdateOnlineStatus(common.OFF, record.ServerAddr); err != nil {
|
||||||
|
log.Sugar.Infof("更新级联设备状态失败 err: %s device: %s", err.Error(), record.ServerID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !record.Enable {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
platform, err := stack.NewPlatform(&record.SIPUAOptions, common.SipStack)
|
platform, err := stack.NewPlatform(&record.SIPUAOptions, common.SipStack)
|
||||||
// 都入库了不允许失败, 程序有BUG, 及时修复
|
// 都入库了不允许失败, 程序有BUG, 及时修复
|
||||||
utils.Assert(err == nil)
|
utils.Assert(err == nil)
|
||||||
utils.Assert(stack.PlatformManager.Add(platform.ServerAddr, platform))
|
utils.Assert(stack.PlatformManager.Add(platform.ServerAddr, platform))
|
||||||
|
|
||||||
if err := dao.Platform.UpdateOnlineStatus(common.OFF, record.ServerAddr); err != nil {
|
|
||||||
log.Sugar.Infof("更新级联设备状态失败 err: %s device: %s", err.Error(), record.ServerID)
|
|
||||||
}
|
|
||||||
|
|
||||||
platform.Start()
|
platform.Start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -51,6 +51,11 @@ func (g *gbClient) OnQueryCatalog(sn int, channels []*dao.ChannelModel) {
|
|||||||
for i, _ := range channels {
|
for i, _ := range channels {
|
||||||
channel := *channels[i]
|
channel := *channels[i]
|
||||||
|
|
||||||
|
// 向上级推送自定义的通道ID
|
||||||
|
if channel.CustomID != nil {
|
||||||
|
channel.DeviceID = *channel.CustomID
|
||||||
|
}
|
||||||
|
|
||||||
response.DeviceList.Devices = nil
|
response.DeviceList.Devices = nil
|
||||||
response.DeviceList.Num = 1 // 一次发一个通道
|
response.DeviceList.Num = 1 // 一次发一个通道
|
||||||
response.DeviceList.Devices = append(response.DeviceList.Devices, &channel)
|
response.DeviceList.Devices = append(response.DeviceList.Devices, &channel)
|
||||||
|
@@ -91,7 +91,7 @@ func (p *ClientManager) ExistClientByServerAddr(addr string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func RemovePlatform(key string) (GBClient, error) {
|
func RemovePlatform(key string) (GBClient, error) {
|
||||||
err := dao.Platform.DeleteUAByAddr(key)
|
err := dao.Platform.DeletePlatformByAddr(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@@ -74,6 +74,7 @@ func (g *Platform) OnInvite(request sip.Request, user string) sip.Response {
|
|||||||
return CreateResponseWithStatusCode(request, http.StatusNotFound)
|
return CreateResponseWithStatusCode(request, http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 解析sdp
|
||||||
gbSdp, err := ParseGBSDP(request.Body())
|
gbSdp, err := ParseGBSDP(request.Body())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Sugar.Errorf("处理上级Invite失败,err: %s sdp: %s", err.Error(), request.Body())
|
log.Sugar.Errorf("处理上级Invite失败,err: %s sdp: %s", err.Error(), request.Body())
|
||||||
@@ -84,24 +85,16 @@ func (g *Platform) OnInvite(request sip.Request, user string) sip.Response {
|
|||||||
inviteType.SessionName2Type(strings.ToLower(gbSdp.SDP.Session))
|
inviteType.SessionName2Type(strings.ToLower(gbSdp.SDP.Session))
|
||||||
streamId := common.GenerateStreamID(inviteType, channel.RootID, channel.DeviceID, gbSdp.StartTime, gbSdp.StopTime)
|
streamId := common.GenerateStreamID(inviteType, channel.RootID, channel.DeviceID, gbSdp.StartTime, gbSdp.StopTime)
|
||||||
|
|
||||||
// 如果流不存在, 向通道发送Invite请求
|
|
||||||
stream, _ := dao.Stream.QueryStream(streamId)
|
|
||||||
if stream == nil {
|
|
||||||
stream, err = (&Device{device}).StartStream(inviteType, streamId, user, gbSdp.StartTime, gbSdp.StopTime, channel.Setup.String(), 0, true)
|
|
||||||
if err != nil {
|
|
||||||
log.Sugar.Errorf("处理上级Invite失败 err: %s stream: %s", err.Error(), streamId)
|
|
||||||
return CreateResponseWithStatusCode(request, http.StatusBadRequest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sink := &dao.SinkModel{
|
sink := &dao.SinkModel{
|
||||||
StreamID: streamId,
|
StreamID: streamId,
|
||||||
ServerAddr: g.ServerAddr,
|
ServerAddr: g.ServerAddr,
|
||||||
Protocol: "gb_cascaded"}
|
Protocol: "gb_cascaded"}
|
||||||
|
|
||||||
|
// 添加转发sink到流媒体服务器
|
||||||
response, err := AddForwardSink(TransStreamGBCascaded, request, user, &Sink{sink}, streamId, gbSdp, inviteType, "96 PS/90000")
|
response, err := AddForwardSink(TransStreamGBCascaded, request, user, &Sink{sink}, streamId, gbSdp, inviteType, "96 PS/90000")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Sugar.Errorf("处理上级Invite失败 err: %s stream: %s", err.Error(), streamId)
|
log.Sugar.Errorf("处理上级Invite失败 err: %s stream: %s", err.Error(), streamId)
|
||||||
|
response = CreateResponseWithStatusCode(request, http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
@@ -358,12 +358,12 @@ func filterRequest(f func(wrapper *SipRequestSource)) gosip.RequestHandler {
|
|||||||
userAgent := req.GetHeaders("User-Agent")
|
userAgent := req.GetHeaders("User-Agent")
|
||||||
|
|
||||||
// 过滤黑名单
|
// 过滤黑名单
|
||||||
if _, err := dao.Blacklist.QueryIP(req.Source()); err == nil {
|
if model, _ := dao.Blacklist.QueryIP(req.Source()); model != nil {
|
||||||
SendResponseWithStatusCode(req, tx, http.StatusForbidden)
|
SendResponseWithStatusCode(req, tx, http.StatusForbidden)
|
||||||
log2.Sugar.Errorf("处理%s请求失败, IP被黑名单过滤: %s request: %s ", req.Method(), req.Source(), req.String())
|
log2.Sugar.Errorf("处理%s请求失败, IP被黑名单过滤: %s request: %s ", req.Method(), req.Source(), req.String())
|
||||||
return
|
return
|
||||||
} else if len(userAgent) > 0 {
|
} else if len(userAgent) > 0 {
|
||||||
if _, err = dao.Blacklist.QueryUA(userAgent[0].Value()); err == nil {
|
if model, _ = dao.Blacklist.QueryUA(userAgent[0].Value()); model != nil {
|
||||||
SendResponseWithStatusCode(req, tx, http.StatusForbidden)
|
SendResponseWithStatusCode(req, tx, http.StatusForbidden)
|
||||||
log2.Sugar.Errorf("处理%s请求失败, UA被黑名单过滤: %s request: %s ", req.Method(), userAgent[0].Value(), req.String())
|
log2.Sugar.Errorf("处理%s请求失败, UA被黑名单过滤: %s request: %s ", req.Method(), userAgent[0].Value(), req.String())
|
||||||
return
|
return
|
||||||
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"gb-cms/common"
|
"gb-cms/common"
|
||||||
|
"gb-cms/log"
|
||||||
"github.com/ghettovoice/gosip/sip"
|
"github.com/ghettovoice/gosip/sip"
|
||||||
"github.com/lkmio/avformat/utils"
|
"github.com/lkmio/avformat/utils"
|
||||||
"math"
|
"math"
|
||||||
@@ -87,10 +88,10 @@ func (g *sipUA) doRegister(request sip.Request) bool {
|
|||||||
hop.Params.Add("received", &empty)
|
hop.Params.Add("received", &empty)
|
||||||
|
|
||||||
for i := 0; i < 2; i++ {
|
for i := 0; i < 2; i++ {
|
||||||
//发起注册, 第一次未携带授权头, 第二次携带授权头
|
// 发起注册, 第一次未携带授权头, 第二次携带授权头
|
||||||
clientTransaction := g.stack.SendRequest(request)
|
clientTransaction := g.stack.SendRequest(request)
|
||||||
|
|
||||||
//等待响应
|
// 等待响应
|
||||||
responses := clientTransaction.Responses()
|
responses := clientTransaction.Responses()
|
||||||
var response sip.Response
|
var response sip.Response
|
||||||
select {
|
select {
|
||||||
@@ -112,6 +113,12 @@ func (g *sipUA) doRegister(request sip.Request) bool {
|
|||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} else if response.StatusCode() == 401 || response.StatusCode() == 407 {
|
} else if response.StatusCode() == 401 || response.StatusCode() == 407 {
|
||||||
|
if i == 1 {
|
||||||
|
// 密码错误
|
||||||
|
log.Sugar.Errorf("注册失败, 密码错误. username: %s, server id: %s, server addr: %s password: %s", g.Username, g.ServerID, g.ServerAddr, g.Password)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
authorizer := sip.DefaultAuthorizer{Password: sip.String{Str: g.Password}, User: sip.String{Str: g.Username}}
|
authorizer := sip.DefaultAuthorizer{Password: sip.String{Str: g.Password}, User: sip.String{Str: g.Username}}
|
||||||
if err := authorizer.AuthorizeRequest(request, response); err != nil {
|
if err := authorizer.AuthorizeRequest(request, response); err != nil {
|
||||||
break
|
break
|
||||||
|
Reference in New Issue
Block a user