package gatewayServer
import (
"encoding/json"
"encoding/xml"
"fmt"
"github.com/sirupsen/logrus"
"lcfns/global"
"lcfns/isapi"
appModel "lcfns/model/app"
ipResp "lcfns/model/ipcast/response"
"lcfns/service"
appService "lcfns/service/app"
is "lcfns/service/isapi"
"net"
"net/http"
"strings"
)
func ParseAndResponse(adu AppDataUnit, c net.Conn) {
switch adu.CmdCode {
case CmdCodeHeartbeatC2S:
c2s4002(adu, c)
case CmdCodeGetParamC2S:
c2s4003(adu)
case CmdCodeSetParameterC2S:
c2s4004(adu)
case CmdCodeRegisterC2S:
c2s4001(adu, c)
case CmdCodeServerC2S:
c2s4000(adu, c)
case CmdCodeUpdateC2S:
//更新固件
default:
//fmt.Println(adu.String())
}
}
// 请求管理服务器响应
func c2s4000(adu AppDataUnit, c net.Conn) {
a := AppDataUnit{
CmdCode: CmdCodeServerS2C,
SubCode: 0,
DevId: adu.DevId,
Data: ipAddress,
}
a.Debug()
_, err := c.Write(Pack(a))
if err != nil {
logrus.Errorf("写入数据错误 %e\n", err)
}
logrus.Info(adu.DevId, "向登录服务器请求管理服务器")
}
// 注册登录响应
func c2s4001(adu AppDataUnit, c net.Conn) {
a := AppDataUnit{
CmdCode: CmdCodeRegisterS2C,
SubCode: 0,
DevId: adu.DevId,
}
a.Data = "0"
a.Debug()
_, err := c.Write(Pack(a))
if err != nil {
logrus.Errorf("写入数据错误 %e\n", err)
}
ConnMap[adu.DevId] = c
//1. 网关登录后检查是否已经注册到数据库,没有就要保存至数据库
gs := service.ServiceGroupApp.AppServiceGroup.GatewayService
gw, err := gs.CreateIfNotExist(adu.DevId)
if err != nil && err != appService.ExistError {
logrus.WithField("网关注册失败", adu.DevId).Error(err)
return
}
if err == appService.ExistError {
gs.UpdateState(&appModel.Gateway{Isn: gw.Isn, State: 1})
logrus.Infof("网关[%s]登录成功", adu.DevId)
}
//配置端口转发 配置不成功
//go func() {
// err = s2c8004Set(a.DevId, SubCodePortTrans, add1)
// err = s2c8004Set(a.DevId, SubCodePortTrans, apply)
// time.Sleep(200 * time.Millisecond)
// go func() {
// err = s2c8004Set(a.DevId, SubCodePortTrans, add2)
// err = s2c8004Set(a.DevId, SubCodePortTrans, apply)
// }()
//}()
//if err != nil {
// logrus.Errorf("s2c8004Set %e\n", err)
//}
//2. 获取网关上摄像头和ip音柱的信息,保存至数据库
var cs = service.ServiceGroupApp.AppServiceGroup.CameraService
baseUrl := strings.Split(c.RemoteAddr().String(), ":")[0] + ":8848"
resp, err := isapi.Com(baseUrl, isapi.GetDeviceInfo, nil)
if err != nil {
logrus.Error(err)
return
}
var info = resp.(isapi.DeviceInfo)
//xml.Unmarshal(resp, &info)
//创建camera记录并绑定gateway_id
err = cs.CreateIfNotExist(info, gw.ID)
if err != nil {
logrus.WithField("摄像头注册失败", info.SerialNumber).Error(err)
}
//3.检查摄像头是否配置
camera, err := cs.GetCameraByDeviceId(info.SerialNumber)
if err != nil {
logrus.Error(err)
return
}
//已配置不执行下面
if &camera != nil && camera.IsRegisted == 1 {
return
}
//配置摄像头-事件监听服务器
setServer(baseUrl)
//配置摄像头-sip服务器
setSIP(baseUrl, camera.ID, cs)
//检查ip音柱
url := "http://" + strings.Split(c.RemoteAddr().String(), ":")[0] + ":8849" + "/v1/check_alive"
ipcastService := service.ServiceGroupApp.IpcastServiceGroup.IpcastService
ipcastAppService := service.ServiceGroupApp.AppServiceGroup.IpcastService
all, err := ipcastService.Common(url, http.MethodGet, nil)
if err != nil {
logrus.Error(err)
return
}
var resp1 ipResp.PingResp
json.Unmarshal(all, &resp1)
if resp1.Code == 200 {
ipcastAppService.Create(&appModel.Ipcast{
Gid: gw.ID,
State: 1,
})
}
}
// 心跳响应
func c2s4002(adu AppDataUnit, c net.Conn) {
//todo 心跳处理
a := AppDataUnit{
CmdCode: CmdCodeHeartbeatS2C,
SubCode: 0,
DevId: adu.DevId,
}
a.Debug()
_, err := c.Write(Pack(a))
if err != nil {
logrus.Errorf("写入数据错误 %e\n", err)
}
//todo 更新网关摄像头和ip音柱的状态
}
// 查询参数响应
func c2s4003(adu AppDataUnit) {
logrus.Infof("参数响应%s,devId:%s,CmdCode=%X,SubCode=%X\n", adu.Data, adu.DevId, adu.CmdCode, adu.SubCode)
}
// 设置参数响应
func c2s4004(adu AppDataUnit) {
logrus.Infof("配置参数-响应码%s,devId:%s,CmdCode=%X,SubCode=%X\n", adu.Data, adu.DevId, adu.CmdCode, adu.SubCode)
}
func setServer(host string) uint {
marshal, err := xml.Marshal(global.Config.HttpHostNotificationList)
if err != nil {
logrus.Errorf("事件主机配置文件解析错误: %e\n", err)
return 0
}
data, err := isapi.Com(host, isapi.SetHosts, marshal)
if err != nil {
logrus.Error("配置监听主机错误", err)
}
var resp = data.(isapi.ResponseStatus)
//err = xml.Unmarshal(bytes, &resp)
if err != nil || (resp.StatusCode != 0 && resp.StatusCode != 1) {
logrus.Errorf("配置监听服务器响应 err:%s,StatusCode:%d,StatusString:%s", err.Error(), resp.StatusCode, resp.StatusString)
return 0
}
//logrus.Info("配置监听主机响应", string(bytes))
return 1
}
func setSIP(host string, cid uint, cs appService.CameraService) uint {
//1. 准备数据
var sipstr = `
1
5060
1
false
false
5060
5060
0
true
true
106.52.134.22
5060
34020000002000000001
3402000000
34020000002000000%03d
34020000001320000%03d
kk176@lc
3600
1
15
3
UDP
60
GB/T28181-2016
1
5060
false
false
`
var sipInfo = `
34020000001320000001
1
34020000001320000001
1
`
//获取自增ID,以51为起始值
id, err := is.GetSipUserID()
if err != nil {
logrus.Error("事务错误", err)
}
//2. 配置SIP
s := fmt.Sprintf(sipstr, id, id)
data, err := isapi.Com(host, isapi.SetSIP, []byte(s))
if err != nil {
logrus.Error("配置SIP错误", err)
return 0
}
var resp = data.(isapi.ResponseStatus)
//err = xml.Unmarshal(bytes, &resp)
if err != nil {
logrus.Errorf("配置SIP服务器err:%s", err.Error())
return 0
}
//失败记录失败原因
if resp.StatusCode != 0 && resp.StatusCode != 1 {
logrus.Infof("配置SIP服务器响应 StatusCode:%d,StatusString:%s", resp.StatusCode, resp.StatusString)
return 0
}
//3. 配置SIPInfo
data, err = isapi.Com(host, isapi.SetSIPInfo, []byte(sipInfo))
if err != nil {
logrus.Error("配置SIPInfo错误", err)
return 0
}
var resp1 = data.(isapi.ResponseStatus)
//err = xml.Unmarshal(com, &resp1)
if err != nil {
logrus.Errorf("配置配置SIPInfo err:%s", err.Error())
return 0
}
//记录失败原因
if resp1.StatusCode != 0 && resp1.StatusCode != 1 {
logrus.Infof("配置SIPInfo-响应 StatusCode:%d,StatusString:%s", resp1.StatusCode, resp1.StatusString)
return 0
}
//成功保存数据库
streamId := fmt.Sprintf("34020000002000000%03d@34020000001320000001", id)
streamUrl := global.Config.Hikvision.StreamBaseUrl + streamId
var camera = appModel.Camera{
StreamId: streamId,
StreamUrl: streamUrl,
IsRegisted: 1,
}
camera.ID = cid
err = cs.UpdateCamera(camera)
if err != nil {
logrus.Error(err)
}
return 1
}