Ejemplo n.º 1
0
        public void Unserialize(byte[] stream, int offset = 0)
        {
            try
            {
                if (stream == null || stream.Length <= 0)
                {
                    throw new Exception("NotifBase.Unserialize take invalid parameter");
                }
                if (stream.Length < (offset + Len))
                {
                    throw new Exception("NotifBase.Unserialize take invalid Index");
                }

                NotifyType = (enNotifyType)stream[offset];
            }
            catch (Exception ex)
            {
                CommStackLog.RecordErr(enLogLayer.eAdapter, ex.Message);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// 接受新的数据帧解析函数
        /// </summary>
        /// <param name="rxFrame">帧数据及</param>
        /// <param name="rxFrameLen">帧长度</param>
        private void rxHdlcFrame(byte[] rxFrame, byte rxFrameLen)
        {
            if (rxFrame == null)
            {
                return;
            }
            if (isInvalidCmd(rxFrame[1]))
            {
                CommStackLog.RecordErr(enLogLayer.eSerial, "Err cmd(0x" + rxFrame[1].ToString("X2") + ")");
                return;
            }

            bool isAck       = false;
            bool shouldAck   = false;
            bool isRepeatId  = false;
            bool isNotifData = false;

            //接收报文的个数
            m_i32RxFrameCnt++;
            // parse header
            m_u8RxControl = rxFrame[0];
            m_RxCmdId     = (enCmd)rxFrame[1];
            m_u8RxSeqNum  = rxFrame[2];
            m_u8RxPyldLen = rxFrame[3];
            enNotifyType notType = (enNotifyType)rxFrame[4];

            if (m_RxCmdId == enCmd.CMDID_NOTIFICATION &&
                (notType == enNotifyType.NOTIFID_NOTIFDATA || notType == enNotifyType.NOTIFID_NOTIFEVENT))
            {
                isNotifData = true;
            }

            // 提取出HDLC帧中负载数据
            Array.Copy(rxFrame, 4, m_u8aRxPayload, 0, m_u8RxPyldLen);
            // 解析接受到的HDLC帧是响应帧还是数据帧(请求帧)
            isAck = ((m_u8RxControl & FLAG_ACK) != 0);
            // 如果HDLC帧是数据帧解析接受到的HDLC帧是否需要应答
            shouldAck = ((m_u8RxControl & FLAG_ACKNOWLEDGED) != 0);
            // 应答报文
            if (isAck)
            {
                // 通知上层响应帧到达
                if (m_u8RxPyldLen > 0)
                {
                    // Kous: 是上层应用请求的响应报文,回调上层应用定义的响应通知函数
                    dispatchResponse(m_RxCmdId, m_u8aRxPayload, m_u8RxPyldLen);
                }
            }
            // 请求报文
            else
            {
                // 非数据通知时才检测更新m_u8RxPacketId
                if (!isNotifData)
                {
                    // 是否为重复请求报文
                    if (m_bRxPacketIdInit && m_u8RxSeqNum == m_u8RxPacketId)
                    {
                        CommStackLog.RecordInf(enLogLayer.eSerial, "SO(" + m_u8RxSeqNum.ToString() + ") repeats");
                        isRepeatId = true;
                    }
                    else
                    {
                        isRepeatId        = false;
                        m_bRxPacketIdInit = true;
                        m_u8RxPacketId    = m_u8RxSeqNum; // 记录接收到的报文序列号
                    }
                }
                // 如果报文是需要响应的报文,则在Ser层直接回应
                if (shouldAck)
                {
                    byte   len     = 1;
                    byte[] payload = new byte[len];
                    payload[0] = (byte)eRC.RC_OK;
                    //Thread.Sleep(20);
                    output1Frame(FLAG_ACK | FLAG_ACKNOWLEDGED, (byte)m_RxCmdId, m_u8RxPacketId, len, payload, true);
                }

                switch (m_RxCmdId)
                {
                case enCmd.CMID_HELLO_RESPONSE:
                {
                    if (m_u8RxPyldLen >= 5 &&
                        m_u8aRxPayload[HELLO_RESP_OFFS_RC] == 0 &&
                        m_u8aRxPayload[HELLO_RESP_OFFS_VERSION] == API_VERSION)
                    {
                        // change state
                        m_SerStatus = enSerStatus.SER_ST_CONNECTED;
                        // record manager sequence number
                        m_bRxPacketIdInit = true;
                        m_u8RxPacketId    = m_u8aRxPayload[HELLO_RESP_OFFS_MGRSEQNO];
                        // 通知会话层新的会话已经建立
                        if (m_evStatusChanged != null)
                        {
                            m_evStatusChanged(m_SerStatus);
                        }

                        // 新的会话建立完成,则下发CLI命令
                        m_hdlcore.MoniterCli();
                    }
                    ;
                    break;
                }

                case enCmd.CMID_MGR_HELLO:
                {
                    // 以下8行用于过滤短时间内收到的重复MgrHello报文
                    TimeSpan tsMgrHello = DateTime.Now - m_dtLastMgrHello;
                    m_dtLastMgrHello = DateTime.Now;
                    // 4秒内收到的MgrHello认为为重复
                    if (tsMgrHello.TotalMilliseconds < 2000)
                    {
                        CommStackLog.RecordInf(enLogLayer.eSerial, "Redundant MgrHello");
                        break;
                    }
                    // 以上8行用于过滤短时间内收到的重复MgrHello报文

                    if (m_u8RxPyldLen >= 2)
                    {
                        // change state
                        m_SerStatus = enSerStatus.SER_ST_DISCONNECTED;
                        // 通知会话层新的当前会话已经失效
                        if (m_evStatusChanged != null)
                        {
                            m_evStatusChanged(m_SerStatus);
                        }
                    }
                    break;
                }

                default:
                {
                    // dispatch
                    //if (m_u8RxPyldLen > 0 && m_evRequestArrived != null && isRepeatId == false)
                    //    m_evRequestArrived(m_RxCmdId, m_u8RxControl, m_u8aRxPayload, m_u8RxPyldLen);
                    if (m_u8RxPyldLen > 0 && m_evRequestArrived != null)
                    {
                        if (isNotifData)
                        {
                            m_evRequestArrived(m_RxCmdId, m_u8RxControl, m_u8aRxPayload, m_u8RxPyldLen);
                        }
                        else if (isRepeatId == false)
                        {
                            m_evRequestArrived(m_RxCmdId, m_u8RxControl, m_u8aRxPayload, m_u8RxPyldLen);
                        }
                    }

                    break;
                }
                }

                // Kous: 清空接收负载缓存
                Array.Clear(m_u8aRxPayload, 0, m_u8RxPyldLen);
                m_u8RxPyldLen = 0;
            }
        }