Skip to content

Commit

Permalink
支持JT1078转GB,通过HTTP接口汇报车辆上下线。
Browse files Browse the repository at this point in the history
  • Loading branch information
vanjoge committed Aug 5, 2024
1 parent e7e0d86 commit f411023
Show file tree
Hide file tree
Showing 20 changed files with 715 additions and 69 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,4 @@ FodyWeavers.xsd
/GBWeb/wwwroot/iconfont.js
/GBWeb/wwwroot/css
/GBWeb/wwwroot/favicon.ico
/SipServer/SipServer.xml
58 changes: 58 additions & 0 deletions GBWeb/Controllers/JT2GBController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using GB28181.XML;
using GBWeb.Attribute;
using GBWeb.Models;
using Microsoft.AspNetCore.Mvc;
using SipServer.Models.JT;

namespace GBWeb.Controllers
{
/// <summary>
/// JT1078转GB28181接口
/// </summary>
[Route("api/[controller]/[action]")]
[ApiController, AuthApi]
public class JT2GBController : ControllerBase
{
/// <summary>
/// JT1078车机上线/心跳通知(批量)
/// </summary>
/// <param name="lst"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult> Online(List<JTItem> lst)
{
try
{
await Program.sipServer.JT2GB.AddJTItems(lst);

return new ApiResult(200);
}
catch
{
return new ApiResult(500) { message = "err" };
}
}
/// <summary>
/// JT1078车机下线通知(批量)
/// </summary>
/// <param name="lst"></param>
/// <returns></returns>
[HttpPost]
public async Task<ApiResult> Offline(List<JTKey> lst)
{
try
{
await Program.sipServer.JT2GB.RemoveJTItems(lst);

return new ApiResult(200);
}
catch
{
return new ApiResult(500) { message = "err" };
}
}
}
}
22 changes: 15 additions & 7 deletions GBWeb/Controllers/RTVSController.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using GB28181.MANSRTSP;
using GB28181.XML;
using GBWeb.Attribute;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SQ.Base;
using Swashbuckle.AspNetCore.Annotations;

namespace GBWeb.Controllers
{
Expand Down Expand Up @@ -45,6 +38,16 @@ public async Task<string> Invite(string DeviceID, string Channel, string InviteI
{
return await client.Send_INVITE(Channel, InviteID, Base64ToStr(SDP), TalkCov);
}
else if (Program.sipServer.TryGetJTClient(DeviceID, out var jtclient))
{
var ret = await jtclient.Send_INVITE(Channel, InviteID, Base64ToStr(SDP), TalkCov);
if (ret == "1")
{
//此处不等待,因为ACK后会发流,如果等待可能出现流媒体还没收到应答不接收流。
_ = jtclient.On_ACK(InviteID);
}
return ret;
}
else
{
return "0";
Expand Down Expand Up @@ -106,6 +109,11 @@ public async Task<string> Bye(string DeviceID, string Channel, string InviteID,
await client.Send_Bye(InviteID);
return "1";
}
else if (Program.sipServer.TryGetJTClient(DeviceID, out var jtclient))
{
var ret = await jtclient.On_BYE(InviteID);
return "1";
}
else
{
return "0";
Expand Down
1 change: 1 addition & 0 deletions GBWeb/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ public void ConfigureServices(IServiceCollection services)
c.SwaggerDoc("api", new OpenApiInfo { Title = "API", Version = "v1" });
c.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, "GBWeb.xml"), true);
c.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, "GB28181.xml"), true);
c.IncludeXmlComments(System.IO.Path.Combine(AppContext.BaseDirectory, "SipServer.xml"), true);

c.OperationFilter<SecurityFilter>();

Expand Down
34 changes: 25 additions & 9 deletions SipServer/Cascade/CascadeChannelItem.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,42 @@
using GB28181.Client;
using GB28181.XML;
using SipServer.JT2GB;
using SipServer.Models;
using System;
using System.Collections.Generic;
using System.Text;

namespace SipServer.Cascade
{

/// <summary>
/// 级联通道项
/// </summary>
public class CascadeChannelItem : ChannelItem
{
/// <summary>
/// 级联KEY GUID
/// </summary>
public string SuperiorId;
/// <summary>
/// 设备ID
/// </summary>
public string DeviceId;
/// <summary>
/// 真实通道ID 如果上报自定义了会包含在CatalogItem.DeviceID里
/// </summary>
public string ChannelId;
/// <summary>
/// 设备对象
/// </summary>
public GBChannel GBChannel;
/// <summary>
/// 1078对象 不为null时表示此通道为1078转28181模式
/// </summary>
public JT2GBChannel J2GChannel;

public CascadeChannelItem(string SuperiorId, string DeviceId, string ChannelId, Catalog.Item CatalogItem) : base(CatalogItem)
public CascadeChannelItem(string superiorId, string deviceId, string channelId, Catalog.Item catalogItem, JT2GBChannel j2gChannel) : base(catalogItem)
{
this.SuperiorId = SuperiorId;
this.ChannelId = ChannelId;
this.DeviceId = DeviceId;
this.SuperiorId = superiorId;
this.ChannelId = channelId;
this.DeviceId = deviceId;
this.J2GChannel = j2gChannel;
}

}
}
93 changes: 53 additions & 40 deletions SipServer/Cascade/CascadeClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using GB28181.MANSRTSP;
using GB28181.XML;
using JTServer.Model.RTVS;
using SipServer.JT2GB;
using SipServer.Models;
using SIPSorcery.Net;
using SIPSorcery.SIP;
Expand Down Expand Up @@ -34,7 +35,11 @@ protected override string GetKey(CascadeChannelItem item)
protected override void OnChannelItemAdd(CascadeChannelItem item)
{
bool Online = false;
if (client.manager.sipServer.TryGetClient(item.DeviceId, out var gbClient) && gbClient.TryGetChannel(item.ChannelId, out var gbChannel))
if (item.J2GChannel != null)
{
Online = item.J2GChannel.IsOnline();
}
else if (client.manager.sipServer.TryGetClient(item.DeviceId, out var gbClient) && gbClient.TryGetChannel(item.ChannelId, out var gbChannel))
{
Online = gbChannel.Data.Online;
item.GBChannel = gbChannel;
Expand Down Expand Up @@ -73,19 +78,16 @@ protected override void OnChannelItemUpdate(CascadeChannelItem old, CascadeChann
}
}
}
protected class fromTagCache
{
public string TaskID;

public SDP28181 sdp;
}
private CascadeManager manager;
public string Key { get; protected set; }
/// <summary>
/// 通道信息
/// </summary>
protected ConcurrentDictionary<string, SuperiorChannel> ditChannels = new ConcurrentDictionary<string, SuperiorChannel>();
protected ConcurrentDictionary<string, fromTagCache> ditFromTagCache = new ConcurrentDictionary<string, fromTagCache>();
public string DeviceID { get { return deviceInfo.DeviceID; } }
public List<string> GroupIds { get; internal protected set; }
///// <summary>
///// 通道信息
///// </summary>
//protected ConcurrentDictionary<string, SuperiorChannel> ditChannels = new ConcurrentDictionary<string, SuperiorChannel>();
//TODO:需超时回收
protected ConcurrentDictionary<string, FromTagCache> ditFromTagCache = new ConcurrentDictionary<string, FromTagCache>();
public CascadeClient(CascadeManager manager, string Key, string server, string server_id, DeviceInfo deviceInfo, List<SuperiorChannel> channels, string authUsername = null, string password = "123456", int expiry = 7200, string UserAgent = "rtvs v1", bool EnableTraceLogs = false, double heartSec = 60, double timeOutSec = 300, int localPort = 0)
: base(server, server_id, deviceInfo, authUsername, password, expiry, UserAgent, EnableTraceLogs, heartSec, timeOutSec)
{
Expand All @@ -105,7 +107,7 @@ public CascadeClient(CascadeManager manager, string Key, string server, string s
this.ditChild = new CascadeChannelDictionary(this);
foreach (var item in channels)
{
AddChannel(item);
AddChannel(item, null);
}
}

Expand Down Expand Up @@ -171,14 +173,21 @@ protected override async Task<SDP28181> On_INVITE(string fromTag, SDP28181 sdp,
try
{
var did = sipRequest.Header.To.ToURI.User;
if (ditChannels.TryGetValue(did, out var channel))
if (ditChild.TryGetValue(did, out var channel))
{
var str = await HttpHelperByHttpClient.HttpRequestHtml(manager.sipServer.Settings.RTVSAPI + $"api/GB/CreateSendRTPTask?Protocol=2&Sim={channel.DeviceId}&Channel={did}&RTPServer={sdp.RtpIp}&RTPPort={sdp.RtpPort}&UseUdp={(sdp.NetType == SDP28181.RTPNetType.TCP ? "false" : "true")}", false, CancellationToken.None);

var res = str.ParseJSON<SendRTPTask>();
SendRTPTask res;
if (channel.J2GChannel != null)
{
res = await channel.J2GChannel.INVITE_API(sdp);
}
else
{
var str = await HttpHelperByHttpClient.HttpRequestHtml(manager.sipServer.Settings.RTVSAPI + $"api/GB/CreateSendRTPTask?Protocol=2&Sim={channel.DeviceId}&Channel={did}&RTPServer={sdp.RtpIp}&RTPPort={sdp.RtpPort}&UseUdp={(sdp.NetType == SDP28181.RTPNetType.TCP ? "false" : "true")}", false, CancellationToken.None);
res = str.ParseJSON<SendRTPTask>();
}
if (res.Code == StateCode.Success)
{
ditFromTagCache[fromTag] = new fromTagCache
ditFromTagCache[fromTag] = new FromTagCache
{
TaskID = res.TaskID,
sdp = sdp
Expand All @@ -197,34 +206,38 @@ protected override async Task<SDP28181> On_INVITE(string fromTag, SDP28181 sdp,

protected override async Task<RecordInfo> On_RECORDINFO(RecordInfoQuery res, SIPRequest sipRequest)
{
if (ditChannels.TryGetValue(res.DeviceID, out var channel) && manager.sipServer.TryGetClient(channel.DeviceId, out var client))
if (ditChild.TryGetValue(res.DeviceID, out var channel))
{
var oldsn = res.SN;
await client.Send_GetRecordInfo(res, p =>
if (channel.J2GChannel != null)
{
p.SN = oldsn;
return AnsRecordInfo(sipRequest, p);
});
return null;
}
else
{
return new RecordInfo
//channel.J2GChannel.
}
else if (manager.sipServer.TryGetClient(channel.DeviceId, out var client))
{
DeviceID = res.DeviceID,
Name = channel?.Name ?? "Unknown",
SN = res.SN,
SumNum = 0,
};
var oldsn = res.SN;
await client.Send_GetRecordInfo(res, p =>
{
p.SN = oldsn;
return AnsRecordInfo(sipRequest, p);
});
return null;
}
}
return new RecordInfo
{
DeviceID = res.DeviceID,
Name = channel?.CatalogItem?.Name ?? "Unknown",
SN = res.SN,
SumNum = 0,
};
}
protected override async Task<RTSPResponse> On_MANSRTSP(string fromTag, SIPRequest sipRequest)
{
try
{
if (ditFromTagCache.TryGetValue(fromTag, out var item))
{
if (ditChannels.TryGetValue(item.sdp.Owner, out var channel) && manager.sipServer.TryGetClient(channel.DeviceId, out var client))
if (ditChild.TryGetValue(item.sdp.Owner, out var channel) && manager.sipServer.TryGetClient(channel.DeviceId, out var client))
{
if (await client.Send_MANSRTSP(fromTag, sipRequest.Body, async p =>
{
Expand Down Expand Up @@ -260,10 +273,10 @@ public override void Stop(bool waitStop = true)
}
}

protected internal void AddChannel(SuperiorChannel item)
protected internal void AddChannel(SuperiorChannel item, JT2GBChannel j2gChannel)
{
var channel_id = item.GetChannelId();
ditChannels[channel_id] = item;
//ditChannels[channel_id] = item;
var ci = new Catalog.Item
{
DeviceID = channel_id,
Expand All @@ -282,7 +295,7 @@ protected internal void AddChannel(SuperiorChannel item)
Password = Empty2Null(item.Password),
Status = item.Status,
};
if (item.DType < 1 || item.DType > 3)
if (item.IsDevice())
{
ci.Parental = item.Parental ? 1 : 0;
ci.SafetyWay = item.SafetyWay;
Expand All @@ -300,11 +313,11 @@ protected internal void AddChannel(SuperiorChannel item)
ci.Longitude = item.Longitude;
if (item.Latitude > 0)
ci.Latitude = item.Latitude;
ditChild.AddOrUpdate(new CascadeChannelItem(item.SuperiorId, item.DeviceId, item.ChannelId, ci));
ditChild.AddOrUpdate(new CascadeChannelItem(item.SuperiorId, item.DeviceId, item.ChannelId, ci, j2gChannel));
}
protected internal void RemoveChannel(string ChannelId)
{
ditChannels.Remove(ChannelId, out var item);
//ditChannels.Remove(ChannelId, out var item);
ditChild.TryRemove(ChannelId, out var citem);
}

Expand Down
Loading

0 comments on commit f411023

Please sign in to comment.