Ejemplo n.º 1
0
        /// <summary>
        /// 数据帧构造函数
        /// </summary>
        /// <param name="task"></param>
        public Frame(TaskArge task)
        {
            this.Adress        = task.IoTMac;
            this.ControlCode   = task.ControlCode;
            this.DataItem      = task.Data;
            this._protocolType = task.IotProtocolType;

            mkey = task.MKey;
            if (this.DataItem != null)
            {
                this.dataLength = this.DataItem.Length;
            }
        }
Ejemplo n.º 2
0
        public string Initi(string mac, MeterLink link, byte control, byte[] data, IotProtocolType protocolType = IotProtocolType.RanQiBiao)
        {
            if (this._meterLink != null)
            {
                return("IsExit");
            }

            this._meterLink = link;
            this._meterLink.OnConnectClosed += _meterLink_OnConnectClosed;
            try
            {
                //读取当前表的信息并初始化
                //Stopwatch sw = new Stopwatch();
                //sw.Start();
                meter = tms.GetMeter(mac);

                this._meterLink.OnReviced += _meterLink_OnReviced;

                //应答并上报数据
                ReportData(mac, control, data, protocolType);

                if (meter == null)
                {
                    return("");
                }
                //读取当前表任务
                List <Task> taskList = tms.GetTaskList(mac);

                //Log.getInstance().Write(MsgType.Information, string.Format("处理MAC上报数据:{0} Time:{1}", mac, sw.ElapsedMilliseconds / 1000.00));
                //Log.getInstance().Write(new OneMeterDataLogMsg(mac, string.Format("处理MAC上报数据:{0} Time:{1}; 时间:{2}", mac, sw.ElapsedMilliseconds / 1000.00, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))));


                this._reportWatch.Start();
                //创建并启动任务执行线程
                this._taskThread = new Thread(new ParameterizedThreadStart(DoTask));
                this._reportWatch.Restart();
                this._taskThread.Start(taskList);
            }
            catch (Exception e)
            {
                Log.getInstance().Write(MsgType.Error, "创建IoTMetre对象失败,原因:" + e.Message);
                Log.getInstance().Write(new OneMeterDataLogMsg(this.MAC, "创建IoTMetre对象失败,原因:" + e.Message + e.ToString()));
                Log.getInstance().Write(e, MsgType.Error);
                return("创建IoTMetre对象失败,原因:" + e.Message);
            }
            return("");
        }
Ejemplo n.º 3
0
 public TaskArge(string mac, DataItem data, ControlCode controlcode, IotProtocolType protocolType, byte[] key = null)
 {
     this._data         = data;
     this._controlcode  = controlcode;
     this._protocolType = protocolType;
     this._MKey         = key;
     if (mac.Length > 14)
     {
         this._lotMac = mac.Substring(0, 14);
     }
     else if (mac.Length < 14)
     {
         this._lotMac = mac.PadLeft(14, '0');
     }
     else
     {
         this._lotMac = mac;
     }
 }
Ejemplo n.º 4
0
        private bool _lastDowith = false;      //上一条上报数据是否处理完成,已处理完成则丢弃
        /// <summary>
        /// 处理主动上报数据
        /// </summary>
        /// <param name="control"></param>
        /// <param name="data"></param>
        public void ReportData(string mac, byte control, byte[] data, IotProtocolType protocolType)
        {
            lock (this._meterLink)
            {
                this._reportWatch.Restart();
                CY.IoTM.Protocol.Frame frame = null;
                if (protocolType == IotProtocolType.RanQiBiao)
                {
                    //燃气表协议
                    //解密数据
                    byte[]        desData   = Encryption.Decry(data, MKey);
                    DataItem_C001 item_C001 = new DataItem_C001(desData);
                    if (this._lastReportData == null || this._lastReportData.ReadDate != item_C001.ReadDate)
                    {
                        this._lastReportData = item_C001;
                        _lastDowith          = false;
                    }
                    //else if (_lastDowith)
                    //{
                    //    //上报的数据重复,并上条记录已处理过
                    //    return;
                    //}

                    //解析并应答
                    DataItem_C001_Answer itemAnswer = new DataItem_C001_Answer(item_C001.SER);
                    TaskArge             taskArge   = new TaskArge(mac, itemAnswer, ControlCode.CTR_7, MKey);
                    frame = new Protocol.Frame(taskArge);
                    if (this._reportWatch.ElapsedMilliseconds < Answer_YanShi)
                    {
                        Thread.Sleep(Answer_YanShi - (int)this._reportWatch.ElapsedMilliseconds);
                    }
                    this._meterLink.Send(frame.GetBytes());//应答数据
                    //检查上线的表是否登记到系统中
                    if (this.meter == null)
                    {
                        Log.getInstance().Write(MsgType.Information, "表:" + mac + " 在系统中未登记。");
                        Log.getInstance().Write(new OneMeterDataLogMsg(mac, "表:" + mac + "  在系统中未登记。"));
                        return;
                    }
                    Thread.Sleep(300);

                    //将接收到抄表数据提交给数据中心处理
                    Stopwatch _watch = new Stopwatch();
                    _watch.Start();
                    ReportData(item_C001);
                    //new Thread(new ParameterizedThreadStart(ReportData)).Start(item_C001);
                    Console.WriteLine("处理表:{0} 上报数据总用时:{1} 毫秒", mac, _watch.ElapsedMilliseconds);

                    //Log.getInstance().Write(MsgType.Information, "处理表:" + this.MAC + " 上报数据总用时:" + _watch.ElapsedMilliseconds + " 毫秒");
                    //Log.getInstance().Write(new OneMeterDataLogMsg(this.MAC, "处理表:" + this.MAC + " 上报数据总用时:" + _watch.ElapsedMilliseconds + " 毫秒" + "; 时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
                    _lastDowith = true;
                    //_watch.Stop();
                }
                else if (protocolType == IotProtocolType.LCD)
                {
                    //LCD屏协议
                    if (data[0] == 0xc0 && data[1] == 0x02)
                    {
                        //下载
                        DataItem_C002 item_C002 = new DataItem_C002(data);
                        Log.getInstance().Write(new OneMeterDataLogMsg(mac, $"[{this._meterLink.socketHandle}]接收到LCD下载请求,文件名:{item_C002.FileName} 文件长度:{item_C002.FileLength} 请求段号:{item_C002.CurrentSegmentsIndex}"));

                        MemoryStream stream = new MemoryStream();
                        string       str    = ADFileCacheService.getInstance().ReadFileSeg(stream, item_C002.FileName.Substring(0, 4), item_C002.FileName, item_C002.FileLength, item_C002.TotalSegments, item_C002.CurrentSegmentsIndex, item_C002.DataLength);


                        DataItem answerItem = null;
                        TaskArge answerArge = null;
                        if (str != "")
                        {
                            //没有读取到要下载的文件,返回异常应答信息
                            answerItem = new DataItem_C002_Answer_Err(item_C002.SER);
                            answerArge = new TaskArge(mac, answerItem, ControlCode.CTR_8);
                            //TODO:记录异常应答记录
                        }
                        else
                        {
                            byte[] tmp = new byte[stream.Length];
                            stream.Position = 0;
                            stream.Read(tmp, 0, tmp.Length);
                            answerItem = new DataItem_C002_Answer(item_C002.SER, item_C002.FileName, item_C002.FileLength, item_C002.TotalSegments, item_C002.CurrentSegmentsIndex, tmp);
                            answerArge = new TaskArge(mac, answerItem, ControlCode.CTR_7, IotProtocolType.LCD);
                        }
                        //发送应答数据
                        frame = new Protocol.Frame(answerArge);
                        //if (this._reportWatch.ElapsedMilliseconds < Answer_YanShi)
                        //    Thread.Sleep(Answer_YanShi - (int)this._reportWatch.ElapsedMilliseconds);

                        this._meterLink.Send(frame.GetBytes());//应答数据
                        if (this.meter == null)
                        {
                            Log.getInstance().Write(MsgType.Information, "表:" + mac + " 在系统中未登记。");
                            Log.getInstance().Write(new OneMeterDataLogMsg(mac, "表:" + mac + "  在系统中未登记。"));
                            return;
                        }
                    }
                    else
                    {
                        Log.getInstance().Write(new OneMeterDataLogMsg(mac, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}接收到错误的请求指令:{data[0]} {data[1]} "));
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 接收数据的线程函数
        /// </summary>
        void ReceiveData()
        {
            //提供用于数据解析的内存流
            //System.IO.MemoryStream ms = new System.IO.MemoryStream();
            //FE FE 68 30 39 61 51 23 35 51 04 21 1E C0 01 20 40 14 16 22 04 15 20 18 56 42 37 18 56 02 00 18 56 02 00 18 56 02 00 23 00 00 00 6F 16
            byte[] b = new byte[1];
            b[0] = 0x01;
            while (isRun)
            {
                if (this._socket == null)
                {
                    break;
                }
                try
                {
                    System.Threading.Thread.Sleep(50);
                    if (!isRun)
                    {
                        break;         //
                    }
                    if (_socket.Poll(10, SelectMode.SelectRead))
                    {
                        int dLength = this._socket.Available;
                        if (dLength <= 0)
                        {
                            isRun = false;
                            this.Close();
                            break;
                        }
                        byte[] buffer = null;
                        if (dLength > 0)
                        {
                            if (dLength != this._socket.Available)
                            {
                                System.Threading.Thread.Sleep(100);
                                dLength = this._socket.Available;
                            }

                            buffer = new byte[dLength];
                            this._socket.Receive(buffer);
                            int index = 0;//查找报文头
                            for (int i = 0; i < buffer.Length - 2; i++)
                            {
                                if (buffer[i] == 0XFE && buffer[i + 1] == 0X68)
                                {
                                    index = ++i;
                                    break;
                                }
                            }
                            //检查仪表类型是否为燃气表或LCD屏协议,否则抛弃
                            IotProtocolType pType   = (IotProtocolType)buffer[index + 1];
                            int             iOffset = 11; //定义从包头(0x68)到数据区域字节数

                            if (pType != IotProtocolType.LCD && pType != IotProtocolType.RanQiBiao)
                            {
                                continue;
                            }

                            int DataLength = DataLength = buffer[index + 10];
                            if (pType == IotProtocolType.RanQiBiao)
                            {
                                DataLength = buffer[index + 10];
                            }
                            else if (pType == IotProtocolType.LCD)
                            {
                                iOffset     = 12;//LCD协议中,数据长度字段修改为2个字节,所以偏移量为12
                                DataLength += buffer[index + 11] << 8;
                            }
                            byte checkSum = 0;

                            //检查校验码
                            for (int i = index; i < index + DataLength + iOffset; i++)
                            {
                                checkSum += Convert.ToByte(buffer[i]);
                            }
                            if (checkSum != buffer[index + iOffset + DataLength])
                            {
                                //校验和错误
                                continue;
                            }
                            //取出数据部分(该数据为加密数据)注:LCD协议不加密
                            byte[] DATA = new byte[DataLength];
                            for (int i = 0; i < DataLength; i++)
                            {
                                DATA[i] = buffer[i + index + iOffset];
                            }

                            StringBuilder sb = new StringBuilder();
                            for (int i = index + 8; i > index + 1; i--)
                            {
                                sb.Append(string.Format("{0:X2}", buffer[i]));
                            }
                            this._MAC = sb.ToString();
                            //
                            if (!this.isLogin)
                            {
                                this.isLogin = true;
                                Log.getInstance().Write(new OneMeterDataLogMsg(this._MAC, string.Format("上线-> [{0}] ", socketHandle) + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
                                RecordRevDataToLog(this._MAC, buffer, socketHandle.ToString());//添加日志
                                this._ioTMeter.Initi(this._MAC, this, buffer[index + 9], DATA, pType);
                            }
                            else
                            {
                                RecordRevDataToLog(this._MAC, buffer, socketHandle.ToString());//添加日志
                                //在此需要判端是下位机请求
                                if (buffer[index + 9] == 0xA1)
                                {
                                    //下位机请求,(包括:上报燃气表数据、请求LCD文件、请求交易等)
                                    this._ioTMeter.ReportData(this._MAC, buffer[index + 9], DATA, pType);
                                }
                                else if (this.OnReviced != null)
                                {
                                    this.OnReviced(new Meter_DATA()
                                    {
                                        Control = buffer[index + 9], DataLength = DataLength, m_buffer = DATA, ProtocolType = pType
                                    });
                                }
                            }
                            //else if(result != "")
                            //{
                            //    //Console.WriteLine(result);
                            //    Log.getInstance().Write(MsgType.Information,result);
                            //}
                        }
                        else
                        {
                            //检查网络连接有效性
                            if (((this._socket.Poll(1000, SelectMode.SelectRead) && (this._socket.Available == 0)) || !this._socket.Connected))
                            {
                                isRun = false;
                                this.Close();
                            }
                            continue;
                        }
                    }
                    else
                    {
                        //检查网络连接有效性
                        if (((this._socket.Poll(1000, SelectMode.SelectRead) && (this._socket.Available == 0)) || !this._socket.Connected))
                        {
                            isRun = false;
                            this.Close();
                        }
                        continue;
                    }
                }
                catch (ObjectDisposedException e)
                {
                    Log.getInstance().Write(MsgType.Information, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 在MeterLink.ReceiveData产生ObjectDisposedException异常,详细如下:\r\nMAC:{this._MAC}[{this.socketHandle}]\r\n  {e} ");

                    //Socket已关闭
                    isRun = false;
                    this.Close();
                    break;
                }
                catch (SocketException e1)
                {
                    Log.getInstance().Write(MsgType.Information, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 在MeterLink.ReceiveData产生SocketException异常ErrorCode={e1.ErrorCode},详细如下:\r\nMAC:{this._MAC}[{this.socketHandle}]\r\n {e1} ");

                    if (e1.ErrorCode != 10035)
                    {
                        //当前链接已断开或连接已关闭。
                        isRun = false;
                        this.Close();
                        break;
                    }
                    //Log.getInstance().Write(e1, MsgType.Error);
                }
                catch (OutOfMemoryException e2)
                {
                    //Log.getInstance().Write(e2, MsgType.Error);
                    Log.getInstance().Write(MsgType.Information, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 在MeterLink.ReceiveData产生OutOfMemoryException异常,详细如下:\r\nMAC:{this._MAC}[{this.socketHandle}]\r\n  {e2} ");
                    GC.Collect();
                }
                catch (Exception e3)
                {
                    Log.getInstance().Write(MsgType.Information, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")} 在MeterLink.ReceiveData产生Exception异常,详细如下:\r\nMAC:{this._MAC}[{this.socketHandle}]\r\n  {e3} ");
                    //Log.getInstance().Write(e3, MsgType.Error);
                }
            }
            //ms.Close();
        }