/// <summary> /// 发送命令并返回新增命令的id,外部捕获这个id并轮询这条命令的发送状态 /// </summary> /// <param name="Sim">sim卡号码(11位数字,everdigm的sim卡号码后面带三个0,如89001435000)</param> /// <param name="Content">命令内容</param> /// <param name="sender">命令发送者的ID</param> /// <returns>命令记录的id,后续通过这个id查询命令状态</returns> private static int SendSMSCommand(TB_Terminal terminal, string Content, int sender) { string simno = terminal.Sim; // 判断Unitel的卡号,前面两位是89,且长度是8位数字 simno = simno[0] == '8' && simno[1] == '9' ? simno.Substring(0, 8) : simno; string ret = SMSUtility.SendSMS(simno, Content); using (var bll = new CommandBLL()) { // 查看发送成功与否的状态 CommandStatus cs = ret.Equals("SUCCESS") ? CommandStatus.SentBySMS : CommandStatus.SentFail; // 新建一个命令发送类实体 TB_Command ct = bll.GetObject(); simno = (simno[0] == '8' && simno[1] == '9' && simno.Length < 11) ? (simno + "000") : simno; ct.DestinationNo = simno; ct.Status = (byte)cs; ct.Content = Content; ct.ActualSendTime = DateTime.Now; ct.Terminal = terminal.id; ct.SendUser = (0 == sender ? (int?)null : sender); var id = bll.Add(ct).id; // 保存终端的命令发送条数 return(id); } }
private void handleBB0F(string sender, byte terminalType) { // 170020140FBB10FFFF0890014950000101089001495000 string cmd = "170020" + Utility.GetHex(terminalType) + "0FBB10FFFF0" + sender + "00001010" + sender + "000"; var TerminalInstance = new TerminalBLL(); var terminal = TerminalInstance.Find(f => f.Sim.Equals(sender)); var CommandInstance = new CommandBLL(); var obj = CommandInstance.GetObject(); //var simno = (simno[0] == '8' && simno[1] == '9' && simno.Length < 11) ? (simno + "000") : simno; obj.DestinationNo = sender + "000"; obj.Status = (byte)CommandStatus.Waiting; obj.Content = cmd; //obj.ActualSendTime = DateTime.Now; obj.Terminal = null == terminal ? (int?)null : terminal.id; obj.SendUser = (int?)null; obj = CommandInstance.Add(obj); //CommandUtility.SendSMSCommand(obj); // 保存SMS发送流量 //saveTerminalFlow(null == terminal ? -1 : terminal.id, sender); }
/// <summary> /// 处理查询命令的请求 /// </summary> private void HandleCommandRequest() { using (var bll = new CommandBLL()) { if (string.IsNullOrEmpty(cmd)) { var ret = "[]"; var obj = bll.Find(f => f.ScheduleTime >= DateTime.Now.AddSeconds(-60) && f.Status <= (byte)CommandStatus.WaitingForSMS && f.TB_Terminal.OnlineStyle == (byte)LinkType.SATELLITE); var command = new Command(obj); ret = JsonConverter.ToJson(command); ResponseJson(ret); } else { // 更新命令发送状态 bll.Update(f => f.id == int.Parse(cmd), act => { act.Status = (byte)CommandStatus.SentBySAT; act.ActualSendTime = DateTime.Now; }); } } }
/// <summary> /// 更新铱星方式发送命令的状态 /// </summary> /// <param name="obj"></param> /// <param name="status"></param> private void UpdateIridiumCommand(TB_Command obj, CommandStatus status, CommandBLL bll) { bll.Update(f => f.id == obj.id, act => { act.Status = (byte)status; act.ActualSendTime = DateTime.Now; }); }
/// <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> /// 根据CC00的返回时间更新之前的0xBB0F命令发送状态为成功返回状态 /// </summary> private void Handle0xBB0FStatus() { using (var bll = new CommandBLL()) { bll.Update(f => f.ScheduleTime >= DateTime.Now.AddMinutes(-10) && f.Status == (byte)CommandStatus.SentBySMS && f.Command == "0xBB0F", act => { act.Status = (byte)CommandStatus.Returned; }); } }
/// <summary> /// 更新命令的发送状态 /// </summary> /// <param name="obj"></param> private void UpdateGsmCommand(TB_Command obj, CommandStatus status, CommandBLL bll) { bll.Update(f => f.id == obj.id, act => { act.Status = (byte)status; if (status == CommandStatus.SentByTCP) { act.ActualSendTime = DateTime.Now; } }); }
/// <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> /// 清理超时的命令为发送失败状态 /// </summary> private void ClearTimedoutCommands(CommandBLL bll) { // 更新GSM状态下的命令超时的记录 bll.Update(f => f.ScheduleTime <= DateTime.Now.AddMinutes(-5) && GsmStatus.Contains(f.Status.Value), act => { act.Status = (byte)CommandStatus.Timedout; }); // 更新卫星发送下的超时命令记录,超过80分钟没有回复的,当作超时 bll.Update(f => IridiumStatus.Skip(2).Contains(f.Status.Value) && f.ScheduleTime <= DateTime.Now.AddMinutes(-IRIDIUM_MT_TIMEOUT), act => { act.Status = (byte)CommandStatus.Timedout; }); }
/// <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> /// 处理查询命令发送状态的请求 /// </summary> /// <returns></returns> private string HandleQueryCommandStatusRequest() { string ret = ""; using (var bll = new CommandBLL()) { var cmd = bll.Find(f => f.id == ParseInt(data)); if (null == cmd) { ret = ResponseMessage(-1, "No such command record exists."); } else { byte status = cmd.Status.Value; CommandStatus state = (CommandStatus)status; if (state == CommandStatus.Returned) { using (var dbll = new DataBLL()) { var list = dbll.FindList <TB_HISTORIES>(f => f.command_id.Equals(cmd.Command) && f.terminal_id.Equals(cmd.DestinationNo) && f.receive_time > cmd.ActualSendTime, "receive_time", true); var data = list.FirstOrDefault(); var desc = CommandUtility.GetCommandStatus(state); if (null != data) { desc += GetCommandData(data); } ret = ResponseMessage(status, desc); } } else { ret = ResponseMessage(status, CommandUtility.GetCommandStatus(state)); if (cmd.Command == "0x4000" && (state == CommandStatus.SentBySMS || state == CommandStatus.SentByTCP)) { // 将重置终端连接的命令状态改成不需要回复的状态 bll.Update(f => f.id == cmd.id, act => { act.Status = (byte)CommandStatus.NotNeedReturn; }); } } } } return(ret); }
/// <summary> /// 处理EE00命令 /// </summary> /// <param name="obj"></param> /// <param name="equipment"></param> /// <param name="terminal"></param> private void Handle0xEE00(TX300 obj, TB_Equipment equipment, TB_Terminal terminal) { _0xEE00 xee00 = new _0xEE00(); xee00.Content = obj.MsgContent; xee00.Unpackage(); // 更新终端发送命令的结果 if (null != equipment && xee00.ErrorCommand.Equals("0x6007")) { // 更新锁车状态 using (var bll = new EquipmentBLL()) { bll.Update(f => f.id == equipment.id, act => { act.LockStatus = xee00.ErrorParamenter; }); } } // 更新命令的发送状态 using (var bll = new CommandBLL()) { bll.Update(f => f.DestinationNo == obj.TerminalID && f.Command == xee00.ErrorCommand && f.ScheduleTime >= DateTime.Now.AddMinutes(-3) && f.Status >= (byte)CommandStatus.SentByTCP && f.Status <= (byte)CommandStatus.SentToDest, act => { byte b = 0x10; switch (xee00.Error) { case 0x20: b = (byte)CommandStatus.EposFail; break; case 0x30: b = (byte)CommandStatus.EngNotStart; break; default: b = (byte)CommandStatus.NoFunction; break; } act.Status = b; }); } }
/// <summary> /// 检测需要用铱星方式发送的命令 /// </summary> public void CheckIridiumCommand() { if (null == _server) { return; } using (var bll = new CommandBLL()) { var list = bll.FindList(f => f.ScheduleTime >= DateTime.Now.AddSeconds(-30) && f.Status == (byte)CommandStatus.WaitingForSatellite && f.ActualSendTime == (DateTime?)null).ToList(); if (null != list && list.Count > 0) { HandleIridiumCommand(list.First(), bll); } } }
/// <summary> /// 处理GSM命令回复状态 /// </summary> /// <param name="tx300"></param> private void HandleGsmCommandResponsed(TX300 tx300) { using (var bll = new CommandBLL()) { // 查找定期时间内发送的相同命令记录,直取最后一条命令 var cmd = bll.FindList <TB_Command>(f => f.DestinationNo.Equals(tx300.TerminalID) && f.Command.Equals("0x" + CustomConvert.IntToDigit(tx300.CommandID, CustomConvert.HEX, 4)) && f.ScheduleTime >= DateTime.Now.AddMinutes(tx300.ProtocolType == Protocol.ProtocolTypes.SATELLITE ? -60 : -3), "ScheduleTime", true).FirstOrDefault(); if (null != cmd) { bll.Update(f => f.id == cmd.id, act => { act.Status = (byte)CommandStatus.Returned; }); } //bll.Update(f => f.DestinationNo == tx300.TerminalID && // f.Command == "0x" + CustomConvert.IntToDigit(tx300.CommandID, CustomConvert.HEX, 4) && // f.ScheduleTime >= DateTime.Now.AddMinutes(-3) //&& // //GsmStatus.Skip(2).Contains(f.Status.Value), // , act => { act.Status = (byte)CommandStatus.Returned; }); } }
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> /// <param name="security">是否查询保安命令</param> /// <returns></returns> private string HandleCommandHistoryRequest(bool security) { var ret = "[]"; try { var id = ParseInt(Utility.Decrypt(data)); using (var ebll = new EquipmentBLL()) { var obj = ebll.Find(f => f.id == id && f.Deleted == false); if (null != obj) { // 终端不为空时才查询 if ((int?)null != obj.Terminal) { var start = DateTime.Parse(GetParamenter("start") + " 00:00:00"); var end = DateTime.Parse(GetParamenter("end") + " 23:59:59"); var sim = obj.TB_Terminal.Sim; if (sim[0] == '8' && sim[1] == '9' && sim.Length < 11) { sim += "000"; } // 查询的命令 //string _command = ""; Command command = null; if (!string.IsNullOrEmpty(cmd)) { command = CommandUtility.GetCommand(cmd); //_command = command.Code; } using (var bll = new CommandBLL()) { var list = bll.FindList <TB_Command>(f => f.DestinationNo.Equals(sim) && f.ScheduleTime >= start && f.ScheduleTime <= end && f.Command != "0xBB0F", "ScheduleTime", true); if (security) { list = list.Where(w => w.Command == "0x6007" || w.Command == "0x4000" || w.Command == "0x3000" || w.Command == "0xDD02"); } else { list = list.Where(w => w.Command != "0x6007" && w.Command != "0x4000" && w.Command != "0x3000" && w.Command != "0xDD02"); } //&& // (string.IsNullOrEmpty(_command) ? f.u_sms_command.IndexOf("0x") >= 0 : f.u_sms_command.IndexOf(_command) >= 0), // "u_sms_schedule_time", true); if (null != command) { list = list.Where(w => w.Command.IndexOf(command.Code) >= 0); if (security && command.Code.Equals("6007")) { list = list.Where(w => w.Content.Substring(w.Content.Length - 2) == command.Param); } else if (security && command.Code.Equals("3000")) { list = list.Where(w => w.Content.Substring(w.Content.Length - 4, 2) == command.Param); } else if (security && command.Code.Equals("4000")) { list = list.Where(w => w.Content.Substring(w.Content.Length - 4, 2) == command.Param); } } if (list.Count() > 0) { // 将command_id替换 //List<Command> commands = CommandUtility.GetCommand(); foreach (var record in list) { string param = ""; if (record.Command == "0x6007") { param = record.Content.Substring(record.Content.Length - 2); } if (record.Command == "0x3000") { param = record.Content.Substring(record.Content.Length - 4, 2); } if (record.Command == "0x4000") { param = record.Content.Substring(record.Content.Length - 4, 2); } if (record.Command == "0xDD02") { param = record.Content.Substring(record.Content.Length - 8, 2); } Command _cmd = CommandUtility.GetCommand(record.Command.Replace("0x", ""), param); var func = (EquipmentFunctional)obj.Functional; var called = (func == EquipmentFunctional.Mechanical || func == EquipmentFunctional.Electric) ? "Equipment" : "Loader"; record.Command = (null == _cmd ? "" : _cmd.Title.Replace("Equipment", called).Replace("Loader", called)); // 加入命令发送者 2015/09/18 10:36 record.Content = (int?)null == record.SendUser ? "Server" : record.TB_Account.Name; } } ret = JsonConverter.ToJson(list); } } else { ret = ResponseMessage(-1, "No terminal bond with this equipment."); } } else { ret = ResponseMessage(-1, "Equipment is not exist."); } } } catch (Exception e) { ret = ResponseMessage(-1, "Handle History request error:" + e.Message); } return(ret); }
/// <summary> /// 发送命令 /// </summary> /// <param name="Sim"></param> /// <param name="code"></param> /// <param name="sms"></param> /// <param name="sender">发送者的ID,一般为当前登陆者的ID</param> /// <returns></returns> public static int SendCommand(TB_Terminal terminal, string code, bool sms, int sender, string extra = "") { Command cmd = GetCommand(code); string content = cmd.Content; if (cmd.Code.Equals("6007")) { // 保安命令 // DX 的保安命令需要增加一个日期 content += DateTime.Now.ToString("yyMMddHHmm") + cmd.Param; // DX 的保安命令长度不一样 content = "1700" + content.Substring(4); } else if (cmd.Code.Equals("3000")) { // 装载机的锁车、解锁命令 content = content.Substring(0, content.Length - 4) + cmd.Param + "00"; } else if (cmd.Code.Equals("600B")) { uint time = uint.Parse(extra); byte[] tm = BitConverter.GetBytes(time); string t = tm[0].ToString("X2") + tm[1].ToString("X2") + tm[2].ToString("X2") + tm[3].ToString("X2"); content = content.Substring(0, content.Length - 8) + t; } else if (cmd.Code.Equals("DD02")) { content = content.Substring(0, content.Length - 8) + cmd.Param + "000000"; } else if (cmd.Code.Equals("4000")) { content = content.Substring(0, content.Length - 4) + cmd.Param + "00"; } string sim = terminal.Sim; sim = (sim[0] == '8' && sim[1] == '9' && sim.Length < 11) ? (sim + "000") : sim; content = content.Replace(SIMNO, sim); // 终端类型更改,电子式的挖掘机和装载机一个类型,普通DX挖掘机一个类型 byte ttype = terminal.Type.Value; ttype = (ttype == TerminalTypes.DXE || ttype == TerminalTypes.LD) ? TerminalTypes.LD : TerminalTypes.DX; var type = CustomConvert.IntToDigit(ttype, CustomConvert.HEX, 2); content = content.Substring(0, 6) + type + content.Substring(8); // 终端不是卫星方式连接且需要SMS方式发送时,发送SMS命令 //if (terminal.OnlineStyle != (byte)LinkType.SATELLITE && sms) //{ // return SendSMSCommand(terminal, content, sender); //} //else //{ using (var bll = new CommandBLL()) { var command = bll.GetObject(); command.DestinationNo = sim; // 终端是卫星方式连接则使用卫星方式发送命令 command.Status = (terminal.OnlineStyle == (byte)LinkType.SATELLITE ? (byte)CommandStatus.WaitingForSatellite : // SMS发送时值为 re-sending (byte)(sms ? CommandStatus.WaitingForSMS : CommandStatus.Waiting)); command.Content = content; command.SendUser = (0 == sender ? (int?)null : sender); command.Terminal = terminal.id; return(bll.Add(command).id); } //} }
/// <summary> /// 处理接收到的数据 /// </summary> /// <param name="data"></param> private void HandleReceivedData(AsyncUserDataBuffer data) { int index = 0, len = data.Buffer.Length; while (index < len) { byte[] temp = new byte[len - index]; Buffer.BlockCopy(data.Buffer, index, temp, 0, len - index); TX300 x300 = new TX300(); x300.Content = temp; temp = null; x300.package_to_msg(); // 保存历史记录 //SaveTX300History(x300, data.ReceiveTime); // 更新设备状态 HandleTX300Status(x300, data); // 处理命令回复 if (x300.CommandID != 0xBB0F) { // 不要处理0xBB0F的命令返回数据 HandleGsmCommandResponsed(x300); } // 是否需要返回包 bool isNeedResponse = false; // SMS消息不需要返回包 if (x300.ProtocolType > Protocol.ProtocolTypes.SMS) { if (x300.CommandID == 0xCC00 || x300.CommandID == 0xBB0F) { isNeedResponse = true; } } else { isNeedResponse = true; } if (null != _server && isNeedResponse) { if (x300.CommandID == 0xCC00) { byte[] cc00 = Get0xCC00(x300); var ret = 0; if (data.PackageType == AsyncDataPackageType.TCP) { ret = _server.Send(data.SocketHandle, cc00); } else { ret = _server.Send(Port, IP, cc00); } if (1 != ret) { ShowUnhandledMessage(format("{0}Cannot send data to ip:{1}({2}): {3} [{4}]", Now, IP, Port, CustomConvert.GetHex(cc00), data.PackageType)); } cc00 = null; } else if (x300.CommandID == 0xBB0F) { byte smsType = byte.Parse(ConfigurationManager.AppSettings["SMS_SUBMIT_TYPE"]); // 0xBB0F命令需要服务器发送时 // 2600200A0FBB1001000000000000000101383938363030363631353039313130303136343302 if (smsType == SMSUtility.SUBMIT_BY_DB) { string sender = x300.TerminalID; // 170020140FBB10FFFF0139535986930101089001495000 string cmd = "170020" + CustomConvert.GetHex(x300.TerminalType) + "0FBB10FFFF0" + sender + "01010" + sender; using (var bll = new TerminalBLL()) { var terminal = bll.Find(f => f.Sim.Equals(sender)); using (var cbll = new CommandBLL()) { var obj = cbll.GetObject(); obj.DestinationNo = sender; obj.Status = (byte)CommandStatus.Waiting; obj.Content = cmd; obj.Terminal = null == terminal ? (int?)null : terminal.id; obj.SendUser = null; obj = cbll.Add(obj); } } } } else { // 返回回执 TX300Resp resp = new TX300Resp(); resp.CommandID = x300.CommandID; resp.PackageID = x300.PackageID; resp.SequenceID = x300.SequenceID; resp.Status = 0; resp.Package(); var ret = 0; if (data.PackageType == AsyncDataPackageType.TCP) { ret = _server.Send(data.SocketHandle, resp.Content); } else { ret = _server.Send(Port, IP, resp.Content); } if (1 != ret) { ShowUnhandledMessage(format("{0}Cannot send data to {1}:{2}: {3} [{4}]", Now, IP, Port, CustomConvert.GetHex(resp.Content), data.PackageType)); } } } index += x300.TotalLength; x300 = null; } }
/// <summary> /// 检索是否有TCP在线终端的命令待发送。 /// 条件: /// 1、预定发送时间在30s以内 /// 2、命令的状态为等待发送状态(等待发送或等待重发) /// 3、终端为TCP链接状态的 /// </summary> /// <returns></returns> public void CheckGSMCommand() { if (null == _server) { return; } var bll = new CommandBLL(); try { // 取出当前30s内的新命令 var list = bll.FindList(f => f.ScheduleTime >= DateTime.Now.AddSeconds(-30) && GsmStatus.Take(2).Contains(f.Status.Value) && f.TB_Terminal.OnlineStyle != (byte)LinkType.SATELLITE).ToList(); foreach (var cmd in list) { var sim = cmd.DestinationNo; if (sim[0] == '8' || sim[0] == '9') { sim = sim.Substring(0, 8); } // 0==链接不存在1=发送成功2=网络处理错误3=强制SMS发送 byte ret = 0; CommandStatus cs = (CommandStatus)cmd.Status; // 所有GSM命令都强制SMS方式发送 if (cs == CommandStatus.WaitingForSMS) { // 强制SMS发送的 ret = 3; } else { if (cmd.TB_Terminal.OnlineStyle == (byte)LinkType.TCP) { // 0==链接不存在1=发送成功2=网络处理错误 ret = _server.Send(cmd.TB_Terminal.Socket.Value, CustomConvert.GetBytes(cmd.Content)); } } if (ret != 1) { // 非强制SMS发送时,先保存一下命令的发送状态为等待SMS发送状态 if (ret < 3) { UpdateGsmCommand(cmd, CommandStatus.WaitingForSMS, bll); ShowUnhandledMessage(Now + "Send Command(TCP: Fail, force this command to SMS): " + cmd.Content); } else { // url直链方式发送短信时,直接可以发送 byte type = byte.Parse(ConfigurationManager.AppSettings["SMS_SUBMIT_TYPE"]); if (type == SMSUtility.SUBMIT_BY_URL) { // TCP链接丢失,重新用SMS方式发送 bool b = CommandUtility.SendSMSCommand(cmd); if (b) { SaveTerminalData((int?)null == cmd.Terminal ? -1 : cmd.Terminal.Value, sim, AsyncDataPackageType.SMS, 1, false, DateTime.Now); } ShowUnhandledMessage(Now + "Send Command(SMS: " + (b ? "Success" : "Fail") + "): " + cmd.Content); } } } else { // 保存TCP方式的命令发送结果 SaveTerminalData((int?)null == cmd.Terminal ? -1 : cmd.Terminal.Value, sim, AsyncDataPackageType.TCP, cmd.Content.Length / 2, false, DateTime.Now); ShowUnhandledMessage(Now + "Send command(" + (1 == ret ? CommandStatus.SentByTCP : CommandStatus.TCPNetworkError) + "): " + cmd.Content); UpdateGsmCommand(cmd, (1 == ret ? CommandStatus.SentByTCP : CommandStatus.TCPNetworkError), bll); } } // 待发送的命令发送完之后,清理超时的命令 ClearTimedoutCommands(bll); } finally { bll.Close(); } }