Files
2025-12-11 14:04:39 +08:00

562 lines
19 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Data;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Common;
using CommonEntity;
using LogCap.Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Diagnostics;
using NLog;
using RestSharp;
using RestSharp.Authenticators;
using ViewModels;
namespace EMQX_HttpAuth.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class SocketTcpController : ControllerBase
{
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
public static string tcp_server = "http://localhost:8086";
public static string mqtt_server = "http://43.138.217.154:18083";
public IList<char> HexSet = new List<char>() { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f' };
public IConfiguration Configuration { get; set; }
public SocketTcpController(IConfiguration config)
{
this.Configuration = config;
}
/// <summary>
/// 获取所有在线的 下位机 客户端,返回的数据是 IP:端口的形式
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost()]
async public Task<string> Get_all_TCPClients([FromBody] Data data)
{
RestClient client1 = new RestClient(tcp_server);
//Console.WriteLine("发送MQTT的数据为" + str);
var request1 = new RestRequest("/blw/tcphandle", Method.Post);
//注意方法是POST
//Console.WriteLine("Topic: " + debug_log_report_mqtt_topic);
request1.AddParameter("cmd", "get_tcp_info");
request1.AddParameter("parameterlist", "");
var Q = await client1.ExecuteAsync(request1);
return Q.Content;
}
/// <summary>
/// 获取所有在线的MQTTClient
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost()]
async public Task<object> Get_all_MQTTClients([FromBody] QueryData data)
{
string? Key = Configuration["Key"];
string? Security = Configuration["Security"];
var option = new RestClientOptions()
{
BaseUrl = new Uri(mqtt_server),
Authenticator = new HttpBasicAuthenticator(Key, Security)
};
RestClient client1 = new RestClient(option);
//Console.WriteLine("发送MQTT的数据为" + str);
var request1 = new RestRequest("/api/v5/clients", Method.Get);
//注意方法是POST
//Console.WriteLine("Topic: " + debug_log_report_mqtt_topic);
request1.AddQueryParameter("limit", data.Limit);
request1.AddQueryParameter("page", data.Page);
request1.AddQueryParameter("isTrusted", true);
var Q = await client1.ExecuteAsync(request1);
//返回的数据是
//{
// "data": [
// {
// "recv_oct": 147525,
// "send_msg.dropped.expired": 0,
// "recv_msg.qos0": 0,
// "inflight_max": 32,
// "recv_msg.qos1": 3320,
// "send_msg.qos0": 0,
// "recv_msg.qos2": 0,
// "expiry_interval": 0,
// "send_msg.dropped": 0,
// "mqueue_len": 0,
// "proto_ver": 5,
// "keepalive": 60,
// "inflight_cnt": 0,
// "node": "emqx@127.0.0.1",
// "created_at": "2025-06-09T16:08:38.394+08:00",
// "send_cnt": 9436,
// "ip_address": "43.138.217.154",
// "clean_start": true,
// "proto_name": "MQTT",
// "enable_authn": true,
// "mountpoint": null,
// "is_persistent": false,
// "send_msg.qos1": 6113,
// "send_msg.dropped.too_large": 0,
// "send_oct": 331649,
// "recv_msg": 3320,
// "heap_size": 6772,
// "username": "admin",
// "send_msg.dropped.queue_full": 0,
// "send_msg": 6113,
// "clientid": "newemqttclient",
// "subscriptions_max": "infinity",
// "mqueue_max": 1000,
// "recv_pkt": 9436,
// "user_property": {},
// "port": 36036,
// "connected_at": "2025-06-09T16:08:38.394+08:00",
// "mailbox_len": 0,
// "recv_msg.dropped": 0,
// "subscriptions_cnt": 1,
// "is_bridge": false,
// "awaiting_rel_max": 100,
// "awaiting_rel_cnt": 0,
// "mqueue_dropped": 0,
// "send_pkt": 9436,
// "send_msg.qos2": 0,
// "recv_msg.dropped.await_pubrel_timeout": 0,
// "connected": true,
// "reductions": 130011309,
// "recv_cnt": 9436,
// "listener": "tcp:default"
// }
// ],
// "meta": {
// "count": 3,
// "limit": 20,
// "page": 1,
// "hasnext": false
// }
//}
var DDD = System.Text.Json.JsonSerializer.Deserialize<MQTTData>(Q.Content);
var DDD1 = DDD.data.Select(A => new NiMingOO
{
Listener = A["listener"].ToString(),
UserName = A["username"].ToString(),
WWWWIP = A["ip_address"].ToString(),
WWWWPort = A["port"].ToString(),
ClientId = A["clientid"].ToString(),
Connected = A["connected"].ToString(),
connected_DateTime = A["connected_at"].ToString()
}).ToList();
return DDD1;
}
public static string FrameNoKey = "FrameNoKey";
[HttpPost()]
async public Task<RMsg> send_data_to_target([FromBody] Data data)
{
RMsg r = new RMsg();
try
{
RestClient client1 = new RestClient(tcp_server);
var request1 = new RestRequest("/blw/tcphandle", Method.Post);
request1.AddParameter("cmd", data.Cmd);
var VData = data.Parameterlist;
string? HHH1 = VData.data;
string? HHH2 = HHH1.Replace(" ", "");
if (IsIllegalHexadecimal(HHH2) == false)
{
request1.AddParameter("parameterlist", JsonSerializer.Serialize(VData));
var Q = await client1.ExecuteAsync(request1);
r.isok = true;
r.message = "success";
}
else
{
r.isok = false;
r.message = "错误,发送的数据必须是 16进制";
}
}
catch (Exception ex)
{
r.message = ex.Message;
r.isok = false;
}
return r;
}
/// <summary>
/// 发送控制数据
/// 也可以 发送控制指令通过clientid
/// 接口加好了。发送控制指令接口 地址:
///http://iot-manage.uts-data.com:5001/api/sockettcp/send_data_to_targetnew
///
///发送数据如下:
///{
/// "Cmd": "tcp_send_data_clientid",
/// "Parameterlist": {
/// "device_clientid": "71",
/// "command_word":"04",
/// "data": "AA BB CC DD EE FF AA FF AA"
/// }
///}
///command_word 是命令字device_clientid是CID。data 是要发送的 控制数据
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[HttpPost()]
async public Task<RMsg> send_data_to_targetnew([FromBody] Data data)
{
RMsg r = new RMsg();
try
{
var KKK = CSRedisCacheHelper.ForeverGet<ushort>(FrameNoKey);
if (KKK == 0)
{
CSRedisCacheHelper.Forever(FrameNoKey, 0);
}
else
{
CSRedisCacheHelper.GenericSerNo(FrameNoKey);
}
ushort Xuhao = CSRedisCacheHelper.ForeverGet<ushort>(FrameNoKey);
ushort NewXuHao = 0;
if (Xuhao == ushort.MaxValue)
{
NewXuHao = 0;
}
else
{
NewXuHao = (ushort)(Xuhao + 1);
}
CSRedisCacheHelper.Forever<ushort>(FrameNoKey, NewXuHao);
RestClient client1 = new RestClient(tcp_server);
var request1 = new RestRequest("/blw/tcphandle", Method.Post);
//cmd 是 tcp_send_data
request1.AddParameter("cmd", data.Cmd);
var VData = data.Parameterlist;
//组装命令
List<byte> lll = new List<byte>();
//包头
lll.Add(0xAA);
//整包长度
lll.Add(0x00);
lll.Add(0x00);
//包序号
byte[] XXX = BitConverter.GetBytes(NewXuHao);
lll.AddRange(XXX);
//重发次数
lll.Add(0x00);
string SSS = VData.device_clientid;
int SXSX = int.Parse(SSS);
//设备序列号
byte[] SXBy = BitConverter.GetBytes(SXSX);
lll.AddRange(SXBy);
// 要加密的数据
List<byte> = new List<byte>();
//命令字
var UUU = VData.command_word;
ushort III = ushort.Parse(UUU);
byte[] CCC = BitConverter.GetBytes(III);
.AddRange(CCC);
string? HHH1 = VData.data;
string? HHH2 = HHH1.Replace(" ", "");
byte[] finally_data = Tools.HEXString2ByteArray(HHH2);
.AddRange(finally_data);
//将数据头复制一份
//List<byte> jisuan = new List<byte>(lll);
//加上数据段部分
//jisuan.AddRange(加密数据表);
//jisuan.Add(0x00);
//jisuan.Add(0x00);
//var dainfo = jisuan.ToArray();
//byte[] CRCList = BitConverter.GetBytes(crc);
//加密数据表.AddRange(CRCList);
byte[] key = new byte[] { };
var TST = CSRedisCacheHelper.HMGet<string>(0, CacheKey.DeviceInfo, VData.device_clientid);
if (TST != null)
{
if (TST[0] != null)
{
key = Encoding.ASCII.GetBytes(TST[0]);
}
else
{
key = Encoding.ASCII.GetBytes("abcdefg123456");
}
}
byte[] decryptedContent = Tools.IHIOT_Message_Content_Encrypt(NewXuHao, key, .ToArray());
lll.AddRange(decryptedContent);
var dainfo = lll.ToArray();
int changdu = dainfo.Length;
changdu = changdu + 2 + 6;
ushort sss1 = (ushort)changdu;
byte[] bas = BitConverter.GetBytes(sss1);
dainfo[1] = bas[0];
dainfo[2] = bas[1];
//CRC
ushort crc = Tools.CRC16(dainfo, dainfo.Length);//最后两个字节加CRC16校验
//dainfo[dainfo.Length - 2] = Convert.ToByte(crc & 0xff);
//dainfo[dainfo.Length - 1] = Convert.ToByte((crc >> 8) & 0xff);
var USB = dainfo.ToList();
byte[] CRCList = BitConverter.GetBytes(crc);
USB.AddRange(CRCList);
USB.AddRange(new byte[] { 0x2D, 0x2D, 0x0D, 0x0A, 0x2D, 0x2D });
var CMDdata = USB.ToArray();
VData.data = Tools.ByteToString(CMDdata);
if (IsIllegalHexadecimal(HHH2) == false)
{
request1.AddParameter("parameterlist", JsonSerializer.Serialize(VData));
var Q = await client1.ExecuteAsync(request1);
r.isok = true;
r.message = "success";
}
else
{
r.isok = false;
r.message = "错误,发送的数据必须是 16进制";
}
}
catch (Exception ex)
{
r.message = ex.Message + ex.StackTrace;
r.isok = false;
}
return r;
}
[HttpPost()]
async public Task<RMsg> send_data_to_lowermachine([FromBody] Data data)
{
RMsg r = new RMsg();
try
{
var KKK = CSRedisCacheHelper.ForeverGet<ushort>(FrameNoKey);
if (KKK == 0)
{
CSRedisCacheHelper.Forever(FrameNoKey, 0);
}
else
{
CSRedisCacheHelper.GenericSerNo(FrameNoKey);
}
var Xuhao = CSRedisCacheHelper.ForeverGet<ushort>(FrameNoKey);
RestClient client1 = new RestClient(tcp_server);
var request1 = new RestRequest("/blw/tcphandle", Method.Post);
//cmd 是 tcp_send_data
request1.AddParameter("cmd", data.Cmd);
var VData = data.Parameterlist;
//var HHH = JsonSerializer.Deserialize<SendData>(VData);
List<byte> lll = new List<byte>();
//包头
lll.Add(0xAA);
//整包长度
lll.Add(0x00);
lll.Add(0x00);
//包序号
byte[] XXX = BitConverter.GetBytes(Xuhao);
lll.AddRange(XXX);
//重发次数
lll.Add(0x00);
string SSS = VData.device_clientid;
int SXSX = int.Parse(SSS);
//设备序列号
byte[] SXBy = BitConverter.GetBytes(SXSX);
lll.AddRange(SXBy);
List<byte> lll_new = new List<byte>(lll.ToArray());
//命令字
List<byte> jia_mi_bytes = new List<byte>();
var UUU = VData.command_word;
ushort III = ushort.Parse(UUU);
byte[] CCC = BitConverter.GetBytes(III);
lll.AddRange(CCC);
jia_mi_bytes.AddRange(CCC);
string? HHH1 = VData.data;
string? HHH2 = HHH1.Replace(" ", "");
byte[] finally_data = Tools.HEXString2ByteArray(HHH2);
lll.AddRange(finally_data);
jia_mi_bytes.AddRange(finally_data);
lll.Add(0x00);
lll.Add(0x00);
var dainfo = lll.ToArray();
//CRC
ushort crc = Tools.CRC16(dainfo, dainfo.Length - 2);//最后两个字节加CRC16校验
dainfo[dainfo.Length - 2] = Convert.ToByte(crc & 0xff);
dainfo[dainfo.Length - 1] = Convert.ToByte((crc >> 8) & 0xff);
var dataF = dainfo.ToList();
byte[] CRCList = BitConverter.GetBytes(crc);
jia_mi_bytes.AddRange(CRCList);
byte[] key = new byte[] { };
var TST = CSRedisCacheHelper.HMGet<DeviceCacheInfo>(0, CacheKey.DeviceInfo, VData.device_clientid);
if (TST != null)
{
key = Encoding.ASCII.GetBytes(TST[0].SecretKey);
}
byte[] decryptedContent = Tools.IHIOT_Message_Content_Encrypt(Xuhao, key, jia_mi_bytes.ToArray());
dataF.AddRange(new byte[] { 0x2D, 0x2D, 0x0D, 0x0A, 0x2D, 0x2D });
var CMDdata = dataF.ToArray();
int len = CMDdata.Length;
ushort sss1 = (ushort)len;
byte[] bas = BitConverter.GetBytes(sss1);
CMDdata[1] = bas[0];
CMDdata[2] = bas[1];
VData.data = Tools.ByteToString(CMDdata);
if (IsIllegalHexadecimal(HHH2) == false)
{
request1.AddParameter("parameterlist", JsonSerializer.Serialize(VData));
var Q = await client1.ExecuteAsync(request1);
r.isok = true;
r.message = "success";
}
else
{
r.isok = false;
r.message = "错误,发送的数据必须是 16进制";
}
}
catch (Exception ex)
{
_logger.Error("错误:" + ex.Message);
r.message = ex.Message;
r.isok = false;
}
return r;
}
/// <summary>
/// 判断十六进制字符串hex是否正确
/// </summary>
/// <param name="hex">十六进制字符串</param>
/// <returns>true不正确false正确</returns>
public bool IsIllegalHexadecimal(string hex)
{
foreach (char item in hex)
{
if (!HexSet.Contains<char>(item))
return true;
}
return false;
}
}
public class MQTTData
{
public List<Dictionary<string, object>> data { get; set; }
public Dictionary<string, object> meta { get; set; }
}
public class NiMingOO
{
public string? Listener { get; set; }
public string? UserName { get; set; }
public string? WWWWIP { get; set; }
public string? WWWWPort { get; set; }
public string? ClientId { get; set; }
public string? Connected { get; set; }
public string? connected_DateTime { get; set; }
}
public class QueryData
{
public int Limit { get; set; }
public int Page { get; set; }
}
public class RMsg
{
public string message { get; set; }
public bool isok { get; set; }
}
public class Data
{
public string? Cmd { get; set; }
public SendData? Parameterlist { get; set; }
}
public class SendData
{
public string? endpoint { get; set; }
/// <summary>
/// 设备序号
/// </summary>
public string? device_clientid { get; set; }
public string? command_word { get; set; }
public string? data { get; set; }
}
}