using System; using System.Collections.Generic; using System.Linq; using System.Text; using SuperSocket.SocketBase.Command; using SuperSocket.SocketBase.Protocol; using SensorHub.Servers; using SensorHub.Servers.JsonFormat; using Newtonsoft.Json; using System.Threading; using SensorHub.Servers.Commands.CASICCommands; using System.IO; using System.Configuration; namespace SensorHub.Concentrator { public class Concentrator : CommandBase<CasicSession, StringRequestInfo> { public override void ExecuteCommand(CasicSession session, StringRequestInfo requestInfo) { //TODO: construct the receving casic data String preamble = requestInfo.Parameters[0]; String version = requestInfo.Parameters[1]; String leng = requestInfo.Parameters[2]; String devCode = requestInfo.Parameters[3]; String routeFlag = requestInfo.Parameters[4]; String dstNodeAddr = requestInfo.Parameters[5]; String pduType = requestInfo.Parameters[6]; String seq = requestInfo.Parameters[7]; String settings = requestInfo.Parameters[8]; //print the receving data String operType = Common.getOpeTypeByPdu(pduType); session.Logger.Info("接收集中器心跳数据:" + requestInfo.Body); session.Logger.Info("会话:" + session.SessionID); List<Tag> tags = Common.getTags(settings, session); String softwareVersion = ""; uint offset = 0; uint size = 0; foreach (Tag tag in tags) { if (!(tag is UploadTag)) { //非业务处理 if (tag != null && tag is SoftwareVersionTag) { SoftwareVersionTag versionTag = (SoftwareVersionTag)tag; softwareVersion = versionTag.Version; continue; } if (tag != null && tag is OffsetTag) { OffsetTag offsetTag = (OffsetTag)tag; offset = offsetTag.Offset; continue; } if (tag != null && tag is SizeTag) { SizeTag tagTag = (SizeTag)tag; size = tagTag.Size; continue; } } } byte[] btPdu = new byte[2]; btPdu[0] = Common.getRespOperType(operType, true);//0x07; btPdu[1] = 0x85; if (session.HubAddr == null)//集中器新连接到来 { session.Logger.Info("集中器新建立连接"); session.HubAddr = devCode; if (Common.concentratorWithSessionIdMap.ContainsKey(devCode)) { String sessionID = Common.concentratorWithSessionIdMap[devCode]; CasicSession s = session.AppServer.GetSessionByID(sessionID); session.Logger.Info("存在旧连接" + devCode + "," + sessionID); if (s != null && s.Connected) { s.HubAddr = null; s.Close(); session.Logger.Info("断开旧连接"); } Common.concentratorWithSessionIdMap[devCode] = session.SessionID; //该集中器之前已连接,更新会话,断开旧连接 Common.sender433Config(session, devCode, btPdu, 0x00); return; } else { session.Logger.Info("添加新连接"); Common.concentratorWithSessionIdMap.Add(devCode, session.SessionID); } DateTime now = DateTime.Now; DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区 long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数 String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd") + now.ToString("HH") + now.ToString("mm") + now.ToString("ss"); String message = JsonConvert.SerializeObject(new Json("Event", "Concentrator", devCode, new DataJson("ConcentratorOnline", -1, null, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); } else { session.Logger.Info("未连接上第三方服务器"); } //集中器上线,完成之前未完成的缓存的下发配置操作 RedisHelper redis = new RedisHelper(0); redis.Publish("Config", devCode);//主动发布消息 } else//心跳数据到来,10次心跳发送一次在线消息 { if (Common.concentratorWithHeartbeatMap.ContainsKey(devCode)) { if (++Common.concentratorWithHeartbeatMap[devCode] >= 10) { DateTime now = DateTime.Now; DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1)); //当地时区 long timeStamp = (long)(now - startTime).TotalMilliseconds; //相差毫秒数 String logtime = now.ToString("yyyy") + now.ToString("MM") + now.ToString("dd") + now.ToString("HH") + now.ToString("mm") + now.ToString("ss"); String message = JsonConvert.SerializeObject(new Json("Event", "Concentrator", devCode, new DataJson("ConcentratorOnline", -1, null, logtime), timeStamp)); if (Common.SendMessage(message)) { session.Logger.Info("往第三方发送数据:" + message); Common.concentratorWithHeartbeatMap[devCode] = 0; } else { session.Logger.Info("未连接上第三方服务器"); } } } else { Common.concentratorWithHeartbeatMap.Add(devCode, 0); } } if (!String.IsNullOrEmpty(softwareVersion))//有上传版本号,进行升级回复 { //读取文件 //String path = Directory.GetCurrentDirectory(); String path = Common.GetWindowsServiceInstallPath(ConfigurationManager.AppSettings["ServiceName"]); path += "\\Update\\Concentrator"; String lastestFilePath = String.Empty; var files = Directory.GetFiles(path); foreach (var file in files) { if (String.IsNullOrEmpty(lastestFilePath)) { lastestFilePath = file; continue; } if (lastestFilePath.CompareTo(file) < 0) { lastestFilePath = file; } } int index = lastestFilePath.LastIndexOf('_'); String lastestVersion = lastestFilePath.Substring(index + 2); if (softwareVersion.CompareTo(lastestVersion) < 0)//判断是否需要升级 { //读取二进制文件 BinaryReader br = null; try { br = new BinaryReader(new FileStream(lastestFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)); long length = br.BaseStream.Length; byte[] data = br.ReadBytes((int)length); byte[] crc = Common.getCRC(data); Common.sender433UpdateConfig(session, devCode, btPdu, 0x00, (uint)br.BaseStream.Length, crc); } catch (IOException e) { session.Logger.Error(e.Message + "\n Cannot read from file."); Common.sender433Config(session, devCode, btPdu, 0x00);//回复不升级 } br.Close(); return; } else { Common.sender433Config(session, devCode, btPdu, 0x00); return; } } else if (operType == "GetRequest" && size > 0)//下发升级数据包 { //String path = Directory.GetCurrentDirectory(); String path = Common.GetWindowsServiceInstallPath(ConfigurationManager.AppSettings["ServiceName"]); path += "\\Update\\Concentrator"; String lastestFilePath = String.Empty; var files = Directory.GetFiles(path); foreach (var file in files) { if (String.IsNullOrEmpty(lastestFilePath)) { lastestFilePath = file; continue; } if (lastestFilePath.CompareTo(file) < 0) { lastestFilePath = file; } } //读取二进制文件 BinaryReader br = null; try { br = new BinaryReader(new FileStream(lastestFilePath, FileMode.Open, FileAccess.Read, FileShare.Read)); byte[] data; int left = (int)br.BaseStream.Length - (int)offset; if (left >= size) { data = new byte[size]; br.BaseStream.Position = offset; br.Read(data, 0, (int)size); } else { data = new byte[left]; br.BaseStream.Position = offset; br.Read(data, 0, left); } //byte[] crc = Common.getCRC(data); Common.sender433UpdateDataConfig(session, devCode, btPdu, 0x00, data); } catch (IOException e) { session.Logger.Error(e.Message + "\n Cannot read from file."); } br.Close(); return; } Common.sender433Config(session, devCode, btPdu, 0x00); } } }