/// <summary>
 /// 记录铱星的MO次数和长度
 /// </summary>
 /// <param name="data"></param>
 private void HandleIridiumMOFlow(IridiumData data)
 {
     using (var bll = new SatelliteBLL())
     {
         var iridium = bll.Find(f => f.CardNo.Equals(data.IMEI));
         if (null != iridium)
         {
             var monthly = int.Parse(DateTime.Now.ToString("yyyyMM"));
             using (var fbll = new IridiumFlowBLL())
             {
                 var flow = fbll.Find(f => f.Iridium == iridium.id && f.Monthly == monthly);
                 if (null == flow)
                 {
                     flow           = fbll.GetObject();
                     flow.Iridium   = iridium.id;
                     flow.MOTimes   = 1;
                     flow.MOPayload = data.Length;
                     fbll.Add(flow);
                 }
                 else
                 {
                     fbll.Update(f => f.id == flow.id, act =>
                     {
                         act.MOTimes   += 1;
                         act.MOPayload += data.Length;
                     });
                 }
             }
         }
     }
 }
 /// <summary>
 /// 处理铱星终端接收命令的状态
 /// </summary>
 /// <param name="data"></param>
 private void HandleIridiumMTModelReceiveStatus(IridiumData data)
 {
     using (var bll = new CommandBLL())
     {
         bll.Update(f => f.TB_Terminal.TB_Satellite.CardNo.Equals(data.IMEI) && f.IridiumMTMSN == data.MTMSN && f.Status == (byte)CommandStatus.SentBySAT, act =>
         {
             act.Status = (byte)CommandStatus.SentToDestBySAT;
         });
     }
 }
 /// <summary>
 /// 处理铱星命令发送状态
 /// </summary>
 /// <param name="data"></param>
 private void HandleIridiumMTServerSendStatus(IridiumData data)
 {
     using (var bll = new CommandBLL())
     {
         bll.Update(f => f.TB_Terminal.TB_Satellite.CardNo.Equals(data.IMEI) && f.Status == (byte)CommandStatus.SatelliteHandled && f.ActualSendTime == null, action =>
         {
             // 更新等待铱星处理的终端的命令为已发送状态
             action.Status         = (byte)CommandStatus.SentBySAT;
             action.IridiumMTMSN   = data.MTMSN;
             action.ActualSendTime = DateTime.Now;
         });
     }
 }
 /// <summary>
 /// 处理1小时内已被卫星模块接收了的命令为正常返回状态
 /// </summary>
 private void HandleIridiumCommandResponseed(IridiumData data)
 {
     // 更新之前发送到网关或终端已读取的命令为发送成功  2015/11/27 12:38
     using (var bll = new CommandBLL())
     {
         bll.Update(f => f.TB_Terminal.TB_Satellite.CardNo.Equals(data.IMEI) &&
                    f.Command == "0x1000" &&
                    (f.Status == (byte)CommandStatus.SentToDestBySAT || f.Status == (byte)CommandStatus.SentBySAT) &&
                    f.ActualSendTime > DateTime.Now.AddMinutes(-60), act =>
         {
             act.Status = (byte)CommandStatus.Returned;
         });
     }
 }
 /// <summary>
 /// 处理铱星模块发送回来的MO信息
 /// </summary>
 /// <param name="data"></param>
 private void HandleIridiumModelMOPayload(IridiumData data)
 {
     // 如果是正式的协议则以正常的方式处理
     if (data.Length >= TX300Items.header_length)
     {
         // TX300通讯协议首字节必定大于等于17
         // 卫星通讯协议首字节必定等于01
         if (data.Payload[0] >= 17 &&
             ProtocolTypes.IsTX300(data.Payload[2]) &&
             TerminalTypes.IsTX300(data.Payload[3]))
         {
             // 根据卫星号码查询终端的Sim卡号码并将其填入包头结构里
             using (var bll = new TerminalBLL())
             {
                 var terminal = bll.Find(f => f.TB_Satellite.CardNo.Equals(data.IMEI) && f.Delete == false);
                 if (null != terminal)
                 {
                     var sim = terminal.Sim;
                     sim += sim.Length < 11 ? "000" : "";
                     sim  = "0" + sim;
                     var s = CustomConvert.GetBytes(sim);
                     Buffer.BlockCopy(s, 0, data.Payload, 9, s.Length);
                     s = null;
                     // 更新命令的MTMSN状态为返回状态
                     HandleData(new Sockets.AsyncUserDataBuffer()
                     {
                         Buffer       = data.Payload,
                         DataType     = Sockets.AsyncUserDataType.ReceivedData,
                         IP           = "",
                         PackageType  = Sockets.AsyncDataPackageType.SAT,
                         Port         = 0,
                         ReceiveTime  = DateTime.Now,
                         SocketHandle = 0
                     });
                 }
                 else
                 {
                     ShowUnhandledMessage("Unbind satellite report data: " + CustomConvert.GetHex(data.Payload));
                 }
             }
         }
         else
         {
             HandleIridiumNewProtocolPackage(data);
         }
         // 统计铱星的接收数据次数和数据长度
         HandleIridiumMOFlow(data);
     }
     data.Dispose();
 }
        /// <summary>
        /// 处理掉铱星发过来的数据
        /// </summary>
        /// <param name="data"></param>
        public void HandleIridiumData(IridiumData data)
        {
            switch (data.Type)
            {
            case IridiumDataType.MTServerSendStatus:
                HandleIridiumMTServerSendStatus(data);
                break;

            case IridiumDataType.MTModelReceiveStatus:
                HandleIridiumMTModelReceiveStatus(data);
                break;

            case IridiumDataType.MOPayload:
                HandleIridiumModelMOPayload(data);
                break;
            }
        }
        /// <summary>
        /// 处理新版的卫星通讯协议
        /// </summary>
        /// <param name="data"></param>
        private void HandleIridiumNewProtocolPackage(IridiumData data)
        {
            if (data.Payload[0] == 0x01)
            {
                // 新版的卫星通讯协议
                uint   thisWorkTime = BitConverter.ToUInt32(data.Payload, 13);
                string locks        = CustomConvert.GetHex(data.Payload[1]);
                string alarms       = CustomConvert.IntToDigit(data.Payload[2], CustomConvert.BIN, 8) +
                                      CustomConvert.IntToDigit(data.Payload[3], CustomConvert.BIN, 8);
                IridiumLocation location = new IridiumLocation();
                location.LatLng = new byte[IridiumLocation.SIZE];
                Buffer.BlockCopy(data.Payload, 4, location.LatLng, 0, IridiumLocation.SIZE);
                location.Unpackate();

                // 通过卫星的IMEI号码查找终端
                using (var tbll = new TerminalBLL())
                {
                    using (var ebll = new EquipmentBLL())
                    {
                        var          terminal  = tbll.Find(f => f.TB_Satellite.CardNo.Equals(data.IMEI));
                        TB_Equipment equipment = null;
                        if (null != terminal)
                        {
                            // 只有第一版的终端才需要计算补偿时间
                            var compensated = terminal.Version == 1;

                            tbll.Update(f => f.id == terminal.id, act =>
                            {
                                act.OnlineStyle = (byte)LinkType.SATELLITE;
                                // 同时更新终端的最后链接时间
                                act.OnlineTime = data.Time;
                            });
                            equipment = ebll.Find(f => f.Terminal == terminal.id);
                            if (null != equipment)
                            {
                                // 旧的运转时间
                                var oldRuntime = equipment.Runtime;
                                var interval   = 0 == oldRuntime ? 0 : (thisWorkTime - oldRuntime);
                                // 粗略增加的小时数,启动时加2小时
                                var    addMin         = interval > 60 ? interval / 60 : 1 + (location.EngFlag.Equals("On") ? 1 : 0);
                                int    addHour        = (int)(interval > 60 ? interval / 60 : 1);// 显示历史记录
                                string oldCompensated = format("WorkHours {0}, UsedHours {1}, Efficiency {2}, AddHours {3}, Compensated {4}", equipment.WorkHours, equipment.UsedHours, equipment.HourWorkEfficiency, equipment.AddedHours, equipment.CompensatedHours);
                                string newCompensated = "";
                                // 更新设备的总运转时间
                                HandleEquipmentRuntime(equipment, thisWorkTime);
                                if (null != equipment)
                                {
                                    string calculated = "";
                                    ebll.Update(f => f.id == equipment.id, act =>
                                    {
                                        act.OnlineStyle = (byte)LinkType.SATELLITE;
                                        act.OnlineTime  = data.Time;
                                        // 更新设备的报警状态 2015/09/10 14:04
                                        act.Alarm = alarms;

                                        act.LastAction     = "0x1000";
                                        act.LastActionBy   = "SAT";
                                        act.LastActionTime = data.Time;
                                        // 更新定位信息 2015/09/09 23:29
                                        if (location.Available)
                                        {
                                            act.Latitude  = location.Latitude;
                                            act.Longitude = location.Longitude;
                                        }
                                        // 更新启动与否状态 2015/08/31
                                        act.Voltage = location.EngFlag.Equals("On") ? "G2400" : "G0000";

                                        // 更新总运转时间
                                        act.Runtime             = equipment.Runtime;
                                        act.AccumulativeRuntime = equipment.AccumulativeRuntime;
                                        // 更新 version 终端为1的版本的运转时间的补偿
                                        if (compensated && interval > 0)
                                        {
                                            // 实际工作小时数
                                            act.WorkHours += interval / 60.0;
                                            // 实际所用小时数
                                            act.UsedHours += addHour;
                                            // 重新计算每小时工作效率
                                            act.HourWorkEfficiency = act.WorkHours / act.UsedHours;
                                            // 补偿的小时数
                                            act.AddedHours += addMin / 60.0;
                                            // 实际补偿的小时数
                                            act.CompensatedHours = act.AddedHours * act.HourWorkEfficiency;
                                        }
                                        // 如果回来的运转时间比当前时间大则更新成为On状态  暂时  2015/09/02
                                        //if (worktime > act.Runtime)
                                        //{
                                        //    // act.Voltage = "G2400";
                                        //    act.Runtime = (int)worktime;
                                        //}
                                        //else
                                        //{
                                        //    if (worktime > 0)
                                        //    {
                                        //        // 运转时间不为零的话,更新运转时间
                                        //        act.Runtime = (int)worktime;
                                        //    }
                                        //}
                                        // 锁车状态 2015/08/14
                                        if (act.LockStatus != locks)
                                        {
                                            act.LockStatus = locks;
                                        }
                                        // 判断锁车的有效状态
                                        if (locks.Equals("40") || locks.Equals("0F") || locks.Equals("FF"))
                                        {
                                            // 锁车时还有开机状态
                                            if (location.EngFlag.Equals("On"))
                                            {
                                                // 锁车了,但未关机,还在工作中
                                                if (act.LockEffected == (byte)LockEffect.Locked)
                                                {
                                                    act.LockEffected = (byte)LockEffect.LockedAndStillWork;
                                                }
                                                else if (act.LockEffected == (byte)LockEffect.LockedAndEngineOff)
                                                {
                                                    // 锁车了且已关机了,此时再开机则需要报警(没锁住车)
                                                    act.LockEffected = (byte)LockEffect.LockedAndNoEffect;
                                                }
                                            }
                                            else
                                            {
                                                // 锁车了,且已关机了
                                                if (act.LockEffected == (byte)LockEffect.Locked)
                                                {
                                                    act.LockEffected = (byte)LockEffect.LockedAndEngineOff;
                                                }
                                            }
                                        }
                                    });
                                    if (compensated && interval > 0)
                                    {
                                        equipment      = ebll.Find(f => f.id == equipment.id);
                                        newCompensated = format("WorkHours {0}, UsedHours {1}, Efficiency {2}, AddHours {3}, Compensated {4}", equipment.WorkHours, equipment.UsedHours, equipment.HourWorkEfficiency, equipment.AddedHours, equipment.CompensatedHours);

                                        calculated = format("Compensate changed(interval: {0}){1} from {2}{3} to {4}", interval, Environment.NewLine, oldCompensated, Environment.NewLine, newCompensated);
                                    }
                                    if (!string.IsNullOrEmpty(calculated))
                                    {
                                        OnUnhandledMessage(this, new Sockets.UIEventArgs()
                                        {
                                            Message = format("{0}{1}{2}", Now, calculated, Environment.NewLine)
                                        });
                                    }
                                }
                            }
                            else
                            {
                                OnUnhandledMessage(this, new Sockets.UIEventArgs()
                                {
                                    Message = format("{0} Iridium has not bind with any equipment.", Now, Environment.NewLine)
                                });
                            }
                        }
                        else
                        {
                            OnUnhandledMessage(this, new Sockets.UIEventArgs()
                            {
                                Message = format("{0} Satellite has no terminal, data will save as terminal number: \"{1}\".{2}",
                                                 Now, data.IMEI.Substring(4), Environment.NewLine)
                            });
                        }
                        // 保存TX300历史记录
                        SaveTX300History(new TX300()
                        {
                            CommandID    = 0x1000,
                            MsgContent   = data.Payload,
                            ProtocolType = ProtocolTypes.SATELLITE,
                            // 默认装载机终端类型 2015/09/22 09:40
                            TerminalType = null == terminal ? TerminalTypes.LD : terminal.Type.Value,
                            // 没有终端时,用IMEI号码的末尾11位数字表示终端号码 2015/09/22 09:40
                            TerminalID  = null == terminal ? data.IMEI.Substring(4) : terminal.Sim,
                            TotalLength = (ushort)data.Payload.Length
                        }, data.Time, ebll.GetFullNumber(equipment));

                        try
                        {
                            long?posId = null;
                            if (location.Available)
                            {
                                using (var posbll = new PositionBLL())
                                {
                                    var pos = posbll.GetObject();
                                    pos.Latitude   = location.Latitude;
                                    pos.Longitude  = location.Longitude;
                                    pos.NS         = location.NSI;
                                    pos.EW         = location.EWI;
                                    pos.StoreTimes = null == equipment ? 0 : equipment.StoreTimes;
                                    pos.GpsTime    = data.Time;
                                    pos.Equipment  = null == equipment ? (int?)null : equipment.id;
                                    // 没有终端时,用IMEI号码的末尾11位数字表示终端号码 2015/09/22 09:40
                                    pos.Terminal = null == terminal?data.IMEI.Substring(4) : (terminal.Sim.Length < 11 ? (terminal.Sim + "000") : terminal.Sim);

                                    pos.Type = location.Report + "(Eng " + location.EngFlag + ")(SAT)";
                                    posbll.Add(pos);
                                    posId = pos.id;
                                }
                            }

                            // 处理报警信息
                            if (alarms != ALARM)
                            {
                                using (var armbll = new AlarmBLL())
                                {
                                    var arm = armbll.GetObject();
                                    arm.Code       = alarms;
                                    arm.AlarmTime  = data.Time;
                                    arm.Equipment  = null == equipment ? (int?)null : equipment.id;
                                    arm.Position   = posId;
                                    arm.StoreTimes = null == equipment ? 0 : equipment.StoreTimes;
                                    // 没有终端时,用IMEI号码的末尾11位数字表示终端号码 2015/09/22 09:40
                                    arm.Terminal = null == terminal?data.IMEI.Substring(4) : (terminal.Sim.Length < 11 ? (terminal.Sim + "000") : terminal.Sim);

                                    armbll.Add(arm);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            OnUnhandledMessage(this, new Sockets.UIEventArgs()
                            {
                                Message = format("{0}{1}{2}{3}", Now, e.Message, Environment.NewLine, e.StackTrace)
                            });
                        }
                        // 更新卫星方式的命令状态(只处理命令回复的1000,其他的命令在普通命令过程中处理)
                        if (location.ReportType == 1 && data.Payload.Length <= 17)
                        {
                            HandleIridiumCommandResponseed(data);
                        }
                        location.Dispose();
                        location = null;
                    }
                }
            }
        }