/// <summary> /// 铱星发送命令事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnIridiumSend(object sender, IridiumDataEvent e) { SendIMEI = e.Data.IMEI; SendContent = new byte[e.Data.Length];//CustomConvert.GetHex(e.Data.Payload); Buffer.BlockCopy(e.Data.Payload, 0, SendContent, 0, e.Data.Length); // 服务器生成的MTMSN SendMTMSN = e.Data.MTMSN; // 加入新生成的MTMSN到监控列表里 _iridium.AddMTMSN(e.Data.MTMSN); e = null; BeginInvoke((MyInvoker) delegate { performSend(); ShowHistory(Environment.NewLine + Now + "Iridium Command: " + CustomConvert.GetHex(SendContent), false); }); }
private void HandleIridiumCommand(TB_Command obj, CommandBLL bll) { if (null != OnIridiumSend) { IridiumDataEvent e = new IridiumDataEvent(); e.Data = new IridiumData() { Payload = CustomConvert.GetBytes(obj.Content), IMEI = obj.TB_Terminal.TB_Satellite.CardNo, MTMSN = GetIridiumMTMSN() }; e.Data.Payload[2] = ProtocolTypes.SATELLITE; OnIridiumSend(this, e); // 更新命令发送状态 bll.Update(f => f.id == obj.id, act => { act.Status = (byte)CommandStatus.SatelliteHandled; }); if (obj.TB_Terminal.Satellite != (int?)null) { HandleIridiumMTFlow(obj.TB_Terminal.Satellite.Value, obj.Content.Length / 2); } } }
/// <summary> /// 处理接收到的铱星数据包 /// </summary> private void HandleIridiumPackage() { int sleep = 100; int index = 0; ushort momsn = 0; IridiumBuffer obj; bool NeedConfirmation = false; while (!IsStop) { Thread.Sleep(sleep); obj = null; if (!_pool.TryDequeue(out obj)) { obj = null; } if (null != obj) { bool showPayload = false; try { NeedConfirmation = false; momsn = 0; _history.Add(Now + "Iridium package(length: " + obj.length + "): " + Utilities.CustomConvert.GetHex(obj.buffer)); // 分析整包铱星数据 Iridium iridum = new Iridium(); iridum.PackageContent = obj.buffer; iridum.Unpackage(); try { // 从铱星数据体中分别解析各个IE字段 index = 0; IridiumDataEvent data = new IridiumDataEvent(); int length = 0, total = iridum.OverallMessageLength; while (index < iridum.OverallMessageLength) { IE ie = new IE(); ie.Content = new byte[total - index]; Buffer.BlockCopy(iridum.Content, index, ie.Content, 0, total - index); ie.Unpackage(); length = ie.Length + Iridium.HEADER_SIZE; switch (ie.IEI) { case IE.MO_HEADER: MOHeader moh = new MOHeader(); moh.Content = new byte[length]; Buffer.BlockCopy(ie.Content, 0, moh.Content, 0, length); moh.Unpackage(); _history.Add(Now + moh.ToString()); data.Data = new IridiumData(); // 默认为终端接收数据的状态 data.Data.Type = IridiumDataType.MTModelReceiveStatus; data.Data.IMEI = moh.IMEI; data.Data.MTMSN = moh.MTMSN; momsn = moh.MTMSN; data.Data.Time = moh.Time; data.Data.Status = moh.SessionStatus; moh = null; NeedConfirmation = true; break; case IE.MO_LOCATION: MOLocation mol = new MOLocation(); mol.Content = new byte[length]; Buffer.BlockCopy(ie.Content, 0, mol.Content, 0, length); mol.Unpackage(); _history.Add(Now + mol.ToString()); mol = null; NeedConfirmation = true; break; case IE.MO_PAYLOAD: MOPayload mop = new MOPayload(); mop.Content = new byte[length]; Buffer.BlockCopy(ie.Content, 0, mop.Content, 0, length); mop.Unpackage(); _history.Add(Now + mop.ToString()); // 终端发送了数据上来 data.Data.Type = IridiumDataType.MOPayload; data.Data.Payload = mop.Payload; mop = null; showPayload = true; NeedConfirmation = true; break; case IE.MO_CONFIRMATION: MOConfirmation moc = new MOConfirmation(); moc.Content = new byte[length]; Buffer.BlockCopy(ie.Content, 0, moc.Content, 0, length); moc.Unpackage(); _history.Add(Now + moc.ToString()); moc = null; break; case IE.MT_CONFIRMATION: MTConfirmation mtc = new MTConfirmation(); mtc.Content = new byte[length]; Buffer.BlockCopy(ie.Content, 0, mtc.Content, 0, length); mtc.Unpackage(); // MTConfirmation消息没有Header结构 data.Data = new IridiumData(); data.Data.Type = IridiumDataType.MTServerSendStatus; data.Data.MTMSN = (ushort)mtc.UniqueID; momsn = (ushort)mtc.UniqueID; data.Data.IMEI = mtc.IMEI; data.Data.Status = mtc.Status; _history.Add(Now + mtc.ToString()); mtc = null; break; case IE.MT_HEADER: MTHeader mth = new MTHeader(); mth.Content = new byte[length]; Buffer.BlockCopy(ie.Content, 0, mth.Content, 0, length); mth.Unpackage(); momsn = (ushort)mth.UniqueID; _history.Add(Now + mth.ToString()); mth = null; break; case IE.MT_PAYLOAD: MTPayload mtp = new MTPayload(); mtp.Content = new byte[length]; Buffer.BlockCopy(ie.Content, 0, mtp.Content, 0, length); mtp.Unpackage(); _history.Add(Now + mtp.ToString()); mtp = null; break; case IE.MT_PRIORITY: break; } ie = null; index += length; } // 分析完毕之后看是否为终端发送的数据 if (null != data) { if (null != data.Data) { OnIridiumReceive?.Invoke(this, data); } else { data = null; } } } finally { // 反馈MO Confirmation包 if (NeedConfirmation) { MOConfirmation confirm = new MOConfirmation(); confirm.Package(); iridum.OverallMessageLength = 0; iridum.Content = confirm.Content; iridum.Package(); try { obj.socket.Send(iridum.PackageContent); _history.Add(Now + "Send MO Confirmation: " + Utilities.CustomConvert.GetHex(iridum.PackageContent)); } catch (Exception send) { HandleOnMessage(format("{0} Send iridiu package error: {1}, Trace: {2}", Now, send.Message, send.StackTrace)); } AddQueue(iridum.PackageContent); //HandleOnMessage(Now + "MO confirmation: " + Wbs.Utilities.CustomConvert.GetHex(iridum.PackageContent)); iridum = null; } } } catch (Exception e) { HandleOnMessage(format("{0} HandleIridiumPackage error: {1}, Trace: {2}", Now, e.Message, e.StackTrace)); } finally { obj.Dispose(); obj = null; } // 检测是否可以显示当前分析的数据包 string text = ""; lock (lock_momsn) { if (!_showPackage) { var m = MOMSNs.FirstOrDefault(f => f.mtmsn == momsn); if (null != m) { showPayload = true; m.HandleTimes++; } } else { // 如果显示数据包数据则直接显示 showPayload = true; } if (showPayload) { foreach (var s in _history) { text += s + Environment.NewLine; } } // 移除超时的MTMSN监控记录 MOMSNs.RemoveAll(r => r.HandleTimes >= 3 || r.time < DateTime.Now.AddDays(-7)); } if (!string.IsNullOrEmpty(text)) { HandleOnMessage(text); } // 清空分析的历史记录 _history.Clear(); } } }
/// <summary> /// 接收到铱星模块发送的数据 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void OnIridiumReceive(object sender, IridiumDataEvent e) { // 加入铱星数据待处理列表 _server.EnqueueIridiumData(e); }
private void DataHandler_OnIridiumSend(object sender, IridiumDataEvent e) { OnIridiumSend?.Invoke(this, e); }
/// <summary> /// 将接收到的卫星数据放入待处理缓冲区 /// </summary> /// <param name="e"></param> public void EnqueueIridiumData(IridiumDataEvent e) { _iridiumPool.Enqueue(e.Data); }