Ejemplo n.º 1
0
        /// <summary>
        /// 进行WS固件升级前的“终曲”工作
        /// </summary>
        public bool PostludeUpdate()
        {
            m_asigSetNwCfg.Reset();
            m_asigResetSys.Reset();
            m_bSetNwCfgTimeout = false;
            m_bResetSysTimeout = false;

            CommStackLog.RecordInf(enLogLayer.eAdapter, "PostludeUpdate");

            /*
             * if (!dismuteWsUpstream())
             * {
             *  CommStackLog.RecordErr(enLogLayer.eAdapter, "allowUpstream failed");
             *  return false;
             * }*/

            // 关闭双向主干网模式
            SetBackboneMode(enBBMode.Off, 1);
            m_asigSetNwCfg.WaitOne();
            // 关闭主干网超时
            if (m_bSetNwCfgTimeout)
            {
                m_bSetNwCfgTimeout = false;
                CommStackLog.RecordErr(enLogLayer.eAdapter, "SetBackboneMode failed");
                return(false);
            }
            // 重启网络,以使设置生效
            ResetSystem(true);
            m_asigResetSys.WaitOne();

            // 重启网络超时
            if (m_bResetSysTimeout)
            {
                m_bResetSysTimeout = false;
                CommStackLog.RecordErr(enLogLayer.eAdapter, "ResetSystem failed");
                return(false);
            }

            lock (m_dicOnLineWs)
            {
                for (int i = 0; i < m_dicOnLineWs.Count; i++)
                {
                    var item = m_dicOnLineWs.ElementAt(i);
                    if (item.Value)
                    {
                        m_dicOnLineWs[item.Key] = false;
                    }
                }
            }

            m_bUpdating = false;
            // 启动心跳
            startHeartbeat();

            return(true);
        }
Ejemplo n.º 2
0
        private void moniterNewSessinWorker()
        {
            CommStackLog.RecordInf(enLogLayer.eAdapter, "Wait 1 munites for new session");
            Thread.Sleep(60000);
            if (m_Session.Status != enSerStatus.SER_ST_CONNECTED)
            {
                managerLost();
                CommStackLog.RecordInf(enLogLayer.eAdapter, "managerLost");
            }

            m_ThreadMoniterNewSessin = null;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 日志处理主线程函数
        /// </summary>
        private static void CommStackLogger()
        {
            CommStackLog.RecordInf(enLogLayer.eAdapter, "CommStackLogger running");
            while (!bExit && logQ.HaveLogElement)
            {
                LogElement logElem = logQ.DeQ();
                if (logElem != null)
                {
                    WriteLog(logElem.LogType, logElem.ToString(), logElem.NewLine);
                }
            }

            asigThreadExit.Set();
        }
Ejemplo n.º 4
0
 /// <summary>
 /// 停止心跳
 /// </summary>
 private bool stopHeartbeat()
 {
     m_bHaultHeartbeat = true;
     if (m_asigHaultHeartbeat.WaitOne(SYC_WAIT_MAX_TIME))
     {
         CommStackLog.RecordInf(enLogLayer.eAdapter, "Stop heartbeatHandler ok");
         return(true);
     }
     else
     {
         CommStackLog.RecordInf(enLogLayer.eAdapter, "Stop heartbeatHandler failed");
         return(false);
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// 整理日志线程主函数
        /// </summary>
        private static void NeatenLog()
        {
            CommStackLog.RecordInf(enLogLayer.eAdapter, "NeatenLog running");
            DeleteExpiredLog();
            // 如果当前时间以上次压缩间隔超过配置的压缩频率,则进行日志压缩
            if ((DateTime.Now.Date - LastCompressDate.Date).Days >= cfgLogCopressFreq)
            {
                CompressInfoLog();
                CompressErrLog();
                CompressCLILog();
                LastCompressDate = DateTime.Now;
            }

            bNeatening = false;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// HDLC层发送数据结束
        /// </summary>
        public void OutputClose()
        {
            UInt16 u16finalCrc = 0;

            u16finalCrc = (UInt16)(~m_u16OutputCrc);
            // write the CRC value
            OutputWrite((byte)((u16finalCrc >> 0) & 0xFF));
            OutputWrite((byte)((u16finalCrc >> 8) & 0xFF));
            // write closing HDLC flag
            lock (CommStackLog.LockLog)
            {
                //m_Com.Send(HDLC_FLAG);
                m_u8aOutputBuf[m_u8OutputBufFill++] = HDLC_FLAG;
                m_Com.SendArr(m_u8aOutputBuf, m_u8OutputBufFill);
                CommStackLog.RecordInf(enLogLayer.eHdlc, "Tx: " + CommStackLog.ToHexString(m_u8aOutputPacketBuf, m_u8OutputPacketFill));
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// 建立新会话的线程处理主函数
        /// </summary>
        /// <param name="threadParam"></param>
        private void createNewSessionWorker()
        {
            CommStackLog.RecordInf(enLogLayer.eAdapter, "Creating new session...");
            m_asigAutoNwResetEvt.Reset();
            // 重新构建系统及会话
            if (preludeSystem(false))
            {
                //m_u8ResetManagerTime = 0;
                // 当重启是因为升级
                if (m_bUpdateReset)
                {
                    // Manager已经重启,清除标志位
                    m_bUpdateReset = false;
                    // 等待Manager自身重启事件失败,准备手动触发Manager重启事件
                    if (!m_asigAutoNwResetEvt.WaitOne(WAIT_MGR_RSTEVT_TIMEOUT))
                    {
                        GetNetworkInfo(true);
                    }
                }
            }
            // 构建失败则重启manager
            else
            {
                //// 如果重启Manager多次仍不能建立新的会话,则通知上层与Manager会话断开
                //if (++m_u8ResetManagerTime > RESET_MANAGER_MAX_TIME)
                //{
                //    m_u8ResetManagerTime = 0;
                //    managerLost();
                //    CommStackLog.RecordErr(enLogLayer.eAdapter, "Manager Lost!");
                //    return;
                //}
                //// 否则,需要硬件重启
                //else
                if (m_ThreadMoniterNewSessin == null)
                {
                    m_Manager.ResetManager();
                    CommStackLog.RecordInf(enLogLayer.eAdapter, "ResetManager HW!");
                    // 准备新的会话建立
                    m_ThreadMoniterNewSessin = new Thread(moniterNewSessinWorker);
                    m_ThreadMoniterNewSessin.Start();
                }
            }

            m_bProcessingNewSessin = false;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// 发送字节数组
        /// </summary>
        /// <param name="arr">发送数据</param>
        /// <param name="len">发送数据长度</param>
        public void SendArr(byte[] arr, int len)
        {
            if (m_ApiDevice.IsOpen)
            {
                try
                {
                    if (cfgAPIMode == enAPIMode.Mod2)
                    {
                        Dtr(true);//Dtr(true) = 低电平
                        while (!Cts())
                        {
                            CommStackLog.RecordInf(enLogLayer.eDevice, "Cts is invalid!");
                            Thread.Sleep(2);
                            continue;
                        }
                        m_ApiDevice.Write(arr, 0, len);

                        while (m_ApiDevice.BytesToWrite != 0)
                        {
                            CommStackLog.RecordInf(enLogLayer.eDevice, "BytesToWrite = " + m_ApiDevice.BytesToWrite.ToString());
                            Thread.Sleep(1);
                            continue;
                        }

                        Thread.Sleep(5);
                        Dtr(false);
                    }
                    else
                    {
                        m_ApiDevice.Write(arr, 0, len);
                    }
                }
                catch (Exception ex)
                {
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Message:" + ex.Message);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Source: " + ex.Source);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "StackTrace: " + ex.StackTrace);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "ToString: " + ex.ToString());
                }
            }
            else
            {
                CommStackLog.RecordErr(enLogLayer.eDevice, "SendArr not open");
            }
        }
 /// <summary>
 /// 自描述报告的响应
 /// </summary>
 private bool ReplyWSDescribe(tMeshSelfReportResult resault, bool urgent = false)
 {
     lock (objectLock)
     {
         byte[] appStream = new byte[resault.Len];
         resault.Serialize(appStream);
         if (SendData(resault.mac, appStream, urgent, enPktPriority.High) == enURErrCode.ERR_NONE)
         {
             CommStackLog.RecordInf(enLogLayer.eAdapter, "ReplyDescribe mac(" + resault.mac.ToHexString() + ")");
             return(true);
         }
         else
         {
             CommStackLog.RecordInf(enLogLayer.eAdapter, "ReplyDescribe mac(" + resault.mac.ToHexString() + ")" + " unadmissible");
             return(false);
         }
     }
 }
Ejemplo n.º 10
0
 /// <summary>
 /// HDLC层接收数据结束
 /// </summary>
 private void InputClose()
 {
     lock (CommStackLog.LockLog)
     {
         if (m_u16InputCrc == HDLC_CRCGOOD)
         {
             // remove the CRC from the input buffer
             m_u8InputBufFill -= 2;
             CommStackLog.RecordInf(enLogLayer.eHdlc, "Rx: " + CommStackLog.ToHexString(m_u8aInputBuf, m_u8InputBufFill));
         }
         else
         {
             CommStackLog.RecordErr(enLogLayer.eHdlc, "Rx crc error: " + m_u16InputCrc.ToString("X4"));
             m_u8InputBufFill = 0;
         }
         // reset escaping
         m_bInputEscaping = false;
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// 会话状态变更回调函数,Serial层通过此函数通知Session层,当前会话状态变更
        /// </summary>
        /// <param name="newStatus">新的会话状态</param>
        private void SessionStatusChanged(enSerStatus newStatus)
        {
            switch (newStatus)
            {
            case enSerStatus.SER_ST_DISCONNECTED:
            {
                Status = newStatus;
                CommStackLog.RecordInf(enLogLayer.eSession, "Disconnected!");
                m_sigDisconnected.Set();
                m_sigConnected.Reset();
                m_sigSessionOK.Reset();
                // 然后通知上层新的会话需求
                if (SessionLost != null)
                {
                    SessionLost();
                }

                break;
            }

            case enSerStatus.SER_ST_CONNECTED:
            {
                Status = newStatus;
                CommStackLog.RecordInf(enLogLayer.eSession, "Connected!");
                m_sigDisconnected.Reset();
                // 新的会话构建完成,设置通知信号量
                m_sigConnected.Set();
                m_sigSessionOK.Set();

                if (SessionBuilt != null)
                {
                    SessionBuilt();
                }

                break;
            }

            default:
                break;
            }
        }
        /// <summary>
        /// mesh的自描述报告的处理
        /// </summary>
        private void SelfReportAnalysis(tMeshSelfReportParam param)
        {
            tVer NewVer = new tVer();

            NewVer.u8Main  = param.verMcuFw.u8Main;
            NewVer.u8Sub   = param.verMcuFw.u8Sub;
            NewVer.u8Rev   = param.verMcuFw.u8Rev;
            NewVer.u8Build = param.verMcuFw.u8Build;
            NetworkWSInfo[param.mac.ToHexString()] = NewVer;
            tMeshSelfReportResult date = new tMeshSelfReportResult();

            date.mac.Assign(param.mac);
            date.u8RC = 0;
            if (param.u8RC == 0)
            {
                //ReplyWSDescribe(date);
            }
            CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + param.mac.ToHexString() + "):V" + NetworkWSInfo[param.mac.ToHexString()].u8Main.ToString() + "."
                                   + NetworkWSInfo[param.mac.ToHexString()].u8Sub.ToString() + "."
                                   + NetworkWSInfo[param.mac.ToHexString()].u8Rev.ToString() + "."
                                   + NetworkWSInfo[param.mac.ToHexString()].u8Build.ToString());
        }
        /// <summary>
        /// 重启WS的结果
        /// </summary>
        private void ResetWSresultAnalysis(tMeshResetWSResult result)
        {
            tResetWSResult Reset = new tResetWSResult();

            Reset.mac.Assign(result.mac);
            Reset.u16RC = result.u8RC;
            if (result.u8RC == 0)
            {
                CommStackLog.RecordInf(enLogLayer.eAdapter, "ResetWSResult of ws(" + result.mac.ToHexString() + ") is " + result.u8RC);
                if (ResetWSReaultNotify != null)
                {
                    ResetWSReaultNotify(Reset);
                }
            }
            else
            {
                CommStackLog.RecordInf(enLogLayer.eAdapter, "ResetWSResult of ws(" + result.mac.ToHexString() + ") is " + result.u8RC);
                if (resetWSFailed != null)
                {
                    resetWSFailed(result.mac);
                }
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// 新的升级方案中,在升级后先将网络中的所有WS解言(允许上传数据)
        /// </summary>
        /// <returns>允许上传数据是否成功</returns>
        private bool dismuteWsUpstream()
        {
            int iWsCnt = 0;

            lock (m_dicOnLineWs) { iWsCnt = m_dicOnLineWs.Count; }
            if (iWsCnt == 0)
            {
                CommStackLog.RecordErr(enLogLayer.eAdapter, "No online WS");
                return(false);
            }
            else
            {
                // 打印当前在线WS集合,方便问题定位
                lock (m_dicOnLineWs)
                {
                    foreach (string ws in m_dicOnLineWs.Keys)
                    {
                        if (m_dicOnLineWs[ws])
                        {
                            CommStackLog.RecordInf(enLogLayer.eAdapter, ws + " online");
                        }
                        else
                        {
                            CommStackLog.RecordInf(enLogLayer.eAdapter, ws + " offline");
                        }
                    }
                }

                // 进入使言期
                m_bMuteOrDismute = false;
                List <string> lstDismutedSuccess = new List <string>();
                lock (m_listMutedWs)
                {
                    foreach (string key in m_listMutedWs)
                    {
                        lock (m_dicOnLineWs)
                        {
                            try
                            {
                                if (!m_dicOnLineWs[key])
                                {
                                    continue;
                                }
                            }
                            catch (Exception ex)
                            {
                                continue;
                            }
                        }

                        tCtlWsUpstrParam param = new tCtlWsUpstrParam();
                        tMAC             mac   = new tMAC(key);
                        param.mac.Assign(mac);
                        param.u8Control = 0;

                        m_asigDismute.Reset();
                        m_bDismuteTimeout = false;

                        CtlWsUpstr(param);
                        // 判定是否迷失
                        if (m_asigDismute.WaitOne(SYC_WAIT_MAX_TIME))
                        {
                            if (m_bDismuteTimeout)
                            {
                                m_asigDismute.Reset();
                                m_bDismuteTimeout = false;
                                CommStackLog.RecordErr(enLogLayer.eAdapter, "Dismuted(" + key + ") timeout");
                                continue;
                            }
                            else
                            {
                                m_asigDismute.Reset();
                                m_bDismuteTimeout = false;
                                CommStackLog.RecordInf(enLogLayer.eAdapter, "Dismuted(" + key + ") ok");
                                lstDismutedSuccess.Add(key);
                            }
                        }
                        else
                        {
                            m_asigDismute.Reset();
                            m_bDismuteTimeout = false;
                            CommStackLog.RecordInf(enLogLayer.eAdapter, "Dismuted(" + key + ") lost");
                        }
                    }

                    // 从禁言列表中删除已经成功解言的WS
                    foreach (string key in lstDismutedSuccess)
                    {
                        m_listMutedWs.Remove(key);
                    }
                    lstDismutedSuccess.Clear();

                    // 如果目前还有未解言的WS,则很有可能是最后一个升级的WS,最多再等待10分钟
                    if (m_listMutedWs.Count != 0)
                    {
                        int waitWsOnlineTolerance = 600000;
                        int waitWsOnlineCheckTime = 0;
                        while (waitWsOnlineCheckTime < waitWsOnlineTolerance)
                        {
                            // 每间隔1秒钟检查是否有新的WS加入
                            Thread.Sleep(1000);
                            waitWsOnlineCheckTime += 1000;
                            // 检查是否未解言的WS加入网络
                            foreach (string key in m_listMutedWs)
                            {
                                lock (m_dicOnLineWs)
                                {
                                    try
                                    {
                                        if (!m_dicOnLineWs[key])
                                        {
                                            continue;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        continue;
                                    }
                                }

                                // 一旦未解言成功的WS加入网络,则进行解言
                                tCtlWsUpstrParam param = new tCtlWsUpstrParam();
                                param.mac.Assign(new tMAC(key));
                                param.u8Control = 0;
                                m_asigDismute.Reset();
                                m_bDismuteTimeout = false;
                                CtlWsUpstr(param);
                                // 判定是否迷失
                                if (m_asigDismute.WaitOne(SYC_WAIT_MAX_TIME))
                                {
                                    if (m_bDismuteTimeout)
                                    {
                                        m_asigDismute.Reset();
                                        m_bDismuteTimeout = false;
                                        CommStackLog.RecordErr(enLogLayer.eAdapter, "Dismuted(" + key + ") timeout");
                                        continue;
                                    }
                                    else
                                    {
                                        m_asigDismute.Reset();
                                        m_bDismuteTimeout = false;
                                        CommStackLog.RecordInf(enLogLayer.eAdapter, "Dismuted(" + key + ") ok");
                                        lstDismutedSuccess.Add(key);
                                    }
                                }
                                else
                                {
                                    m_asigDismute.Reset();
                                    m_bDismuteTimeout = false;
                                    CommStackLog.RecordInf(enLogLayer.eAdapter, "Dismuted(" + key + ") lost");
                                }
                            }

                            // 从禁言列表中删除已经成功解言的WS
                            foreach (string key in lstDismutedSuccess)
                            {
                                m_listMutedWs.Remove(key);
                            }
                            lstDismutedSuccess.Clear();

                            // 所有该解言的WS都解言完成,退出解言过程
                            if (m_listMutedWs.Count == 0)
                            {
                                return(true);
                            }
                        }

                        if (waitWsOnlineCheckTime >= waitWsOnlineTolerance)
                        {
                            return(false);
                        }
                    }
                }

                return(true);
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// 进行WS固件升级前的“前奏”工作
        /// </summary>
        public bool PreludeUpdate()
        {
            m_asigSetNwCfg.Reset();
            m_asigResetSys.Reset();
            m_bSetNwCfgTimeout = false;
            m_bResetSysTimeout = false;

            CommStackLog.RecordInf(enLogLayer.eAdapter, "PreludeUpdate");

            m_bUpdating = true;
            // 暂停心跳
            if (!stopHeartbeat())
            {
                return(false);
            }

            if (!muteWsUpstream())
            {
                CommStackLog.RecordErr(enLogLayer.eAdapter, "muteWsUpstream failed");
                // 启动心跳
                startHeartbeat();
                return(false);
            }

            // 设置双向主干网模式
            SetBackboneMode(enBBMode.Bidirectional, 2, true);
            m_asigSetNwCfg.WaitOne();
            // 设置主干网超时
            if (m_bSetNwCfgTimeout)
            {
                m_bSetNwCfgTimeout = false;
                CommStackLog.RecordErr(enLogLayer.eAdapter, "SetBackboneMode failed");
                // 通知上层升级失败
                startHeartbeat();
                return(false);
            }

            // 重启网络,以使设置生效
            ResetSystem(true);
            m_asigResetSys.WaitOne();
            // 重启网络超时
            if (m_bResetSysTimeout)
            {
                m_bResetSysTimeout = false;
                CommStackLog.RecordErr(enLogLayer.eAdapter, "ResetSystem failed");
                // 启动心跳
                startHeartbeat();
                return(false);
            }

            m_bUpdateReset = true;

            lock (m_dicOnLineWs)
            {
                for (int i = 0; i < m_dicOnLineWs.Count; i++)
                {
                    var item = m_dicOnLineWs.ElementAt(i);
                    if (item.Value)
                    {
                        m_dicOnLineWs[item.Key] = false;
                    }
                }
            }

            CommStackLog.RecordInf(enLogLayer.eAdapter, "PreludeUpdate finish");
            return(true);
        }
Ejemplo n.º 16
0
        /// <summary>
        /// 升级过程处理函数
        /// </summary>
        private void UpdateHandler()
        {
            CommStackLog.RecordInf(enLogLayer.eAdapter, "UpdateHandler running");

            SetFwDescReaultArrived += setFwDescSucess;
            SetFwDescFailed        += setFwDescFail;
            SetFwDataReaultArrived += setFwDatReault;

            // 等待WS重新加入网络的忍耐时间,单位是ms
            //int waitWsOnlineTolerance = 600000;
            int updateHandlerSleepTime = 1000;
            int noWsOnlineTime         = 0;

            while (m_bUpdating)
            {
                try
                {
                    lock (lstUpdWs)
                    {
                        // 升级队列中无请求的WS则通知上层升级过程结束
                        if (lstUpdWs.Count <= 0)
                        {
                            dismuteWsUpstream();
                            if (updateFinished != null)
                            {
                                updateFinished();
                            }

                            return;
                        }

                        // 寻找可以升级的WS
                        foreach (tMAC mote in lstUpdWs)
                        {
                            lock (m_dicOnLineWs)
                            {
                                foreach (string onlineWS in m_dicOnLineWs.Keys)
                                {
                                    // 检查已经在线的WS
                                    if (m_dicOnLineWs[onlineWS])
                                    {
                                        tMAC checkWs = new tMAC(onlineWS);
                                        // 当前WS在线,且是上层请求升级中的一员
                                        if (checkWs.isEqual(mote))
                                        {
                                            curUpdatingWs = checkWs;
                                            CommStackLog.RecordInf(enLogLayer.eAdapter, "hit ws");
                                            noWsOnlineTime = 0;
                                            // 寻找到可升级的WS,则结束对在线WS的遍历
                                            break;
                                        }
                                    }
                                }
                            }

                            // 寻找到可升级的WS,则结束对升级队列的遍历
                            if (curUpdatingWs != null)
                            {
                                break;
                            }
                        }
                    }

                    if (curUpdatingWs != null)
                    {
                        CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + curUpdatingWs.ToHexString() + ")update!");
                        // 通知上层开始升级新的WS
                        if (updatingWs != null)
                        {
                            updatingWs(curUpdatingWs);
                        }
                        // 下发固件描述信息
                        if (!SendFwDesc(curUpdatingWs))
                        {
                            // 通知上层升级当前WS失败
                            if (updatedWsFailed != null)
                            {
                                updatedWsFailed(curUpdatingWs);
                            }
                            // 升级失败,从请求升级队列中删除当前WS
                            deleteReqUpdatedWs(curUpdatingWs);
                            curUpdatingWs = null;
                            // 升级当前WS失败,则转为升级下一个WS
                            continue;
                        }
                        // 下发固件数据
                        if (!SendFwData(curUpdatingWs))
                        {
                            m_bExitUpdat = false;
                            // 通知上层升级当前WS失败
                            if (updatedWsFailed != null)
                            {
                                updatedWsFailed(curUpdatingWs);
                            }
                            // 升级失败,从请求升级队列中删除当前WS
                            deleteReqUpdatedWs(curUpdatingWs);
                            curUpdatingWs = null;
                            // 升级当前WS失败,则转为升级下一个WS
                            continue;
                        }
                        // 通知上层升级当前WS成功
                        if (updatedWsSucess != null)
                        {
                            updatedWsSucess(curUpdatingWs);
                        }
                        // 升级成功,从请求升级队列中删除当前WS
                        deleteReqUpdatedWs(curUpdatingWs);
                        curUpdatingWs = null;
                        continue;
                    }
                }
                catch (Exception ex)
                {
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Message:" + ex.Message);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Source: " + ex.Source);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "StackTrace: " + ex.StackTrace);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "ToString: " + ex.ToString());
                }

                if (noWsOnlineTime >= waitWsOnlineTolerance)
                {
                    lock (lstUpdWs)
                    {
                        // 剩下的WS都是迟迟不能加入网络的WS,通知上层这些WS升级失败
                        foreach (tMAC mote in lstUpdWs)
                        {
                            if (updatedWsFailed != null)
                            {
                                updatedWsFailed(mote);
                            }
                        }

                        // 清空所有未升级完成的WS
                        lstUpdWs.Clear();
                        dismuteWsUpstream();
                        if (updateFinished != null)
                        {
                            updateFinished();
                        }

                        return;
                    }
                }

                Thread.Sleep(updateHandlerSleepTime);
                noWsOnlineTime += updateHandlerSleepTime;
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// 在升级前先将网络中的所有WS禁言(禁止上传数据)
        /// </summary>
        /// <returns>禁止上传数据是否成功</returns>
        private bool muteWsUpstream()
        {
            int iWsCnt = 0;

            lock (m_dicOnLineWs) { iWsCnt = m_dicOnLineWs.Count; }
            if (iWsCnt == 0)
            {
                CommStackLog.RecordErr(enLogLayer.eAdapter, "No online WS");
                return(false);
            }
            else
            {
                lock (m_dicOnLineWs)
                {
                    foreach (string ws in m_dicOnLineWs.Keys)
                    {
                        if (m_dicOnLineWs[ws])
                        {
                            dicExpectedMutedWs.Add(ws, true);
                            CommStackLog.RecordInf(enLogLayer.eAdapter, ws + " online");
                        }
                        else
                        {
                            CommStackLog.RecordInf(enLogLayer.eAdapter, ws + " offline");
                        }
                    }
                }

                // 进入禁言期
                m_bMuteOrDismute = true;
                // 清空已控制WS列表
                m_listMutedWs.Clear();
                lock (m_listMutedWs)
                {
                    foreach (string key in dicExpectedMutedWs.Keys)
                    {
                        tCtlWsUpstrParam param = new tCtlWsUpstrParam();
                        param.mac.Assign(new tMAC(key));
                        param.u8Control = 1;
                        m_asigMute.Reset();
                        m_bMuteTimeout = false;
                        // 通知WS暂不上传波形数据
                        CtlWsUpstr(param);
                        // 判定是否迷失
                        if (m_asigMute.WaitOne(SYC_WAIT_MAX_TIME))
                        {
                            if (m_bMuteTimeout)
                            {
                                m_asigMute.Reset();
                                m_bMuteTimeout = false;
                                CommStackLog.RecordErr(enLogLayer.eAdapter, "Muted(" + key + ") timeout");
                            }
                            else
                            {
                                m_asigMute.Reset();
                                m_bMuteTimeout = false;
                                // 记录已经禁言成功的WS MAC地址
                                m_listMutedWs.Add(key);
                                CommStackLog.RecordInf(enLogLayer.eAdapter, "Muted(" + key + ") ok");
                            }
                        }
                        else
                        {
                            m_asigMute.Reset();
                            m_bMuteTimeout = false;
                            // 迷失的情况也算是禁言成功
                            CommStackLog.RecordInf(enLogLayer.eAdapter, "Muted(" + key + ") lost");
                        }
                    }

                    dicExpectedMutedWs.Clear();
                }

                // 如果没有一个WS能够控制成功,则告诉上层不能升级
                if (m_listMutedWs.Count == 0)
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// 对特定WS下发固件数据
        /// </summary>
        /// <param name="moteMac">升级的WS</param>
        /// <returns>成功与否</returns>
        private bool SendFwData(tMAC moteMac)
        {
            tSetFwDataParam fwData = new tSetFwDataParam();

            fwData.mac.Assign(moteMac);
            // 等待WS升级完成响应的忍耐时间,单位是ms
            //int waitFwUpdRspTolerance = 50000;
            //int maxFwResendReqCnt = 6;
            double sendoverFwGap     = 0;
            int    waitFwDataTimeout = maxFwResendReqCnt * cfgAgtReq2MshRepTimeout;

            StartSendFwdateTime = DateTime.Now;
            for (ushort i = 0; i < fw.DicFwBlockDat.Count; i++)
            {
                if (m_bExitUpdat)
                {
                    CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + moteMac.ToHexString() + ") lost,Update fail!");
                    return(false);
                }
                fwData.u8DataPacketSize = (byte)fw.DicFwBlockDat[i].size;
                fwData.u8aData          = fw.DicFwBlockDat[i].data;
                fwData.u16BlkIdx        = i;

                asigFwDatSent.Reset();
                // 发送固件数据
                SetFwData(fwData, true);
                // 等待数据发送成功
                if (!asigFwDatSent.WaitOne(waitFwDataTimeout))
                {
                    CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + moteMac.ToHexString() + ")" + "SinglePacket Update fail!");
                    return(false);
                }
                TimeSpan tsWaitAppRsp = DateTime.Now - StartSendFwdateTime;
                sendoverFwGap = tsWaitAppRsp.TotalMilliseconds / (i + 1);
                if (sendoverFwGap > SendupdateSinglePacketGap)
                {
                    CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + moteMac.ToHexString() + ")" + "SinglePacket Update Timeout!");
                    return(false);
                }
            }
            byte resendTime = 0;

RESENT_FW_DAT:
            asigFwUpdateResponse.Reset();
            // 等待WS发送的升级数据响应
            if (!asigFwUpdateResponse.WaitOne(waitFwUpdRspTolerance))
            {
                CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + moteMac.ToHexString() + ")" + "Update timeout fail!");
                return(false);
            }
            if (fwUpdateResult == null)
            {
                CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + moteMac.ToHexString() + ")" + "fwUpdateResult is null!");
                return(false);
            }
            // 等到WS发送的升级数据响应
            // 升级成功
            if (fwUpdateResult.u8RC == 0)
            {
                return(true);
            }
            // 升级重传
            else if (fwUpdateResult.u8RC == 1)
            {
                // 超过最大重试次数,则退出对本WS的升级
                if (resendTime++ >= maxFwResendReqCnt)
                {
                    CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + moteMac.ToHexString() + ")" + "Update resendCnt Fail!");
                    return(false);
                }

                for (UInt16 i = 0; i < fwUpdateResult.u16FwBlock.Length; i++)
                {
                    if (m_bExitUpdat)
                    {
                        CommStackLog.RecordInf(enLogLayer.eAdapter, "WS(" + moteMac.ToHexString() + ") lost,Update fail!");
                        return(false);
                    }
                    fwData.u8DataPacketSize = (byte)fw.DicFwBlockDat[fwUpdateResult.u16FwBlock[i]].size;
                    fwData.u8aData          = fw.DicFwBlockDat[fwUpdateResult.u16FwBlock[i]].data;
                    fwData.u16BlkIdx        = fwUpdateResult.u16FwBlock[i];

                    asigFwDatSent.Reset();
                    // 发送固件数据
                    SetFwData(fwData, true);
                    // 等待数据发送成功
                    if (!asigFwDatSent.WaitOne(waitFwDataTimeout))
                    {
                        CommStackLog.RecordInf(enLogLayer.eAdapter, "SinglePacket Update fail!");
                        return(false);
                    }
                }
                goto RESENT_FW_DAT;
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// 获取接收缓存区的数据
        /// </summary>
        private void readApiBufferWorker()
        {
            CommStackLog.RecordInf(enLogLayer.eDevice, "readApiBufferWorker running");
            m_ApiDevice.ReadTimeout = 4000;
            while (m_bKeepReading)
            {
                if (m_ApiDevice.IsOpen)
                {
                    try
                    {
                        if (cfgAPIMode == enAPIMode.Mod2)
                        {
                            if (!Dsr())     //Dsr=false代表低电平
                            {
                                Rts(false); // Rts(false)代表此时低电平
                                int buffSize = m_ApiDevice.BytesToRead;
                                if (buffSize == 0)
                                {
                                    Thread.Sleep(2);
                                    continue;
                                }

                                byte[] readBuffer = new byte[buffSize];
                                int    count      = m_ApiDevice.Read(readBuffer, 0, buffSize);
                                if (count != buffSize)
                                {
                                    CommStackLog.RecordErr(enLogLayer.eDevice, "readApiBufferWorker disappointed");
                                }

                                for (int loop = 0; loop < count; loop++)
                                {
                                    if (m_evByteArrived != null)
                                    {
                                        m_evByteArrived(readBuffer[loop]);
                                    }
                                    else
                                    {
                                        CommStackLog.RecordErr(enLogLayer.eDevice, "Event ByteArrived is null");
                                    }
                                }
                            }
                            else
                            {
                                Rts(true);
                            }
                        }
                        else
                        {
                            int buffSize = m_ApiDevice.BytesToRead;
                            if (buffSize == 0)
                            {
                                if (cfgReadApiInterval > 0)
                                {
                                    Thread.Sleep(cfgReadApiInterval);
                                }
                                continue;
                            }

                            byte[] readBuffer = new byte[buffSize];
                            int    count      = m_ApiDevice.Read(readBuffer, 0, buffSize);
                            if (count != buffSize)
                            {
                                CommStackLog.RecordErr(enLogLayer.eDevice, "readApiBufferWorker disappointed");
                            }

                            for (int loop = 0; loop < count; loop++)
                            {
                                if (m_evByteArrived != null)
                                {
                                    m_evByteArrived(readBuffer[loop]);
                                }
                                else
                                {
                                    CommStackLog.RecordErr(enLogLayer.eDevice, "Event ByteArrived is null");
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        CommStackLog.RecordErr(enLogLayer.eAdapter, "Message:" + ex.Message);
                        CommStackLog.RecordErr(enLogLayer.eAdapter, "Source: " + ex.Source);
                        CommStackLog.RecordErr(enLogLayer.eAdapter, "StackTrace: " + ex.StackTrace);
                        CommStackLog.RecordErr(enLogLayer.eAdapter, "ToString: " + ex.ToString());
                    }
                }
                else
                {
                    CommStackLog.RecordErr(enLogLayer.eDevice, "API Port not open");
                    TimeSpan waitTime = new TimeSpan(0, 0, 0, 1, 0);
                    Thread.Sleep(waitTime);
                }
            }
        }
Ejemplo n.º 20
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;
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// iMesh组件使用前的前奏工作
        /// 建立新的会话->注册系统关注事件->获取网络当前配置->获取网络时间
        /// </summary>
        /// <param name="bFirstTime">表示是否第一次启动调用此函数</param>
        /// <returns>系统前奏工作是否成功</returns>
        private bool preludeSystem(bool bFirstTime = false)
        {
            m_asigSubs.Reset();
            m_asigGetNwCfg.Reset();
            m_asigGetTime.Reset();

            m_bSubsTimeout     = false;
            m_bGetNwCfgTimeout = false;
            m_bGetTimeTimeout  = false;

            // 打开新的会话
            byte u8CreateSsnTimes = 0;

            while (u8CreateSsnTimes++ < cfgCreateSsnRetryCnt)
            {
                if (!m_Session.Open())
                {
                    continue;
                }
                else
                {
                    break;
                }
            }
            // 尝试多次建立新的会话失败,返回
            if (u8CreateSsnTimes >= cfgCreateSsnRetryCnt)
            {
                CommStackLog.RecordInf(enLogLayer.eAdapter, "Retry " + u8CreateSsnTimes + " times for new-session fialed");
                u8CreateSsnTimes = 0;
                return(false);
            }
            u8CreateSsnTimes = 0;

            // 此时,可以启动iMesh组件的主要处理线程
            m_msigMainThreadRun.Set();
            // 是否第一次启动iMesh组件
            if (bFirstTime)
            {
                // 重新订阅网络事件
                Subscribe(enSubFilters.ICmsFocus, true);
                if (!m_asigSubs.WaitOne(SYC_WAIT_MAX_TIME))
                {
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Wait Subscribe ack too long");
                    return(false);
                }
                else if (m_bSubsTimeout)
                {
                    m_bSubsTimeout = false;
                    return(false);
                }

                // 获取当前网络配置
                GetNetworkConfig(true);
                if (!m_asigGetNwCfg.WaitOne(SYC_WAIT_MAX_TIME))
                {
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Wait GetNetworkConfig ack too long");
                    return(false);
                }
                else if (m_bGetNwCfgTimeout)
                {
                    m_bGetNwCfgTimeout = false;
                    return(false);
                }

                // 获取当前网络时间
                GetTime(true);
                if (!m_asigGetTime.WaitOne(SYC_WAIT_MAX_TIME))
                {
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Wait GetTime ack too long");
                    return(false);
                }
                else if (m_bGetTimeTimeout)
                {
                    m_bGetTimeTimeout = false;
                    return(false);
                }

                return(true);
            }
            else
            {
                // 重新订阅网络事件
                Subscribe(enSubFilters.ICmsFocus, true);
                //m_asigSubs.WaitOne();
                if (!m_asigSubs.WaitOne(SYC_WAIT_MAX_TIME))
                {
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Wait Subscribe ack too long");
                    return(false);
                }
                else if (m_bSubsTimeout)
                {
                    m_bSubsTimeout = false;
                    return(false);
                }
                // 升级状态下,来到此处是因为软件重启Manager,需要重新建立新的会话,并需订阅系统关注事件
                // 但,软件重启Manager后,伴随NetworkReset事件会调用GetTime,故此处不用主动调用
                if (!m_bUpdating)
                {
                    GetTime(true);
                    if (!m_asigGetTime.WaitOne(SYC_WAIT_MAX_TIME))
                    {
                        CommStackLog.RecordErr(enLogLayer.eAdapter, "Wait GetTime ack too long");
                        return(false);
                    }
                    else if (m_bGetTimeTimeout)
                    {
                        m_bGetTimeTimeout = false;
                        return(false);
                    }
                }

                return(true);
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// 系统脉搏定时器超时处理函数
        /// </summary>
        private void heartbeatHandler()
        {
            CommStackLog.RecordInf(enLogLayer.eAdapter, "heartbeatHandler running");

            while (m_bKeepRunning)
            {
                m_msigMainThreadRun.WaitOne();
                m_asigHaultHeartbeat.Reset();
                if (m_bHaultHeartbeat)
                {
                    m_asigHaultHeartbeat.Set();
                    Thread.Sleep(200);
                    continue;
                }

                try
                {
                    if (m_Mesh.IsQueryingAllWs)
                    {
                        tMAC queryIter = new tMAC("0000000000000000");
ITERATOR:
                        m_asigGetMtCfg.Reset();
                        m_bGetMtCfgTimeout = false;
                        if (GetNextMoteConfig(queryIter) != enURErrCode.ERR_NONE)
                        {
                            CommStackLog.RecordInf(enLogLayer.eAdapter, "QueryAllWs unadmissible");
                            m_Mesh.IsQueryingAllWs = false;
                            if (queryAllWsFailed != null)
                            {
                                queryAllWsFailed();
                            }
                            continue;
                        }
                        else if (queryIter.isEqual(new tMAC("0000000000000000")))
                        {
                            CommStackLog.RecordInf(enLogLayer.eAdapter, "QueryAllWs start");
                            lock (m_dicOnLineWs) { m_dicOnLineWs.Clear(); }
                            m_i32MoniterWsIdx = 0;
                        }

                        if (!m_asigGetMtCfg.WaitOne(m_Mesh.AgtReq2MgrRepTimeout))
                        {
                            m_bGetMtCfgTimeout = true;
                        }
                        if (!m_bGetMtCfgTimeout)
                        {
                            if (m_cacheGetMtCfgResult.RC == eRC.RC_OK)
                            {
                                if (!m_cacheGetMtCfgResult.isAP)
                                {
                                    // Kous: 此处决定只要Mote不为Lost状态,则认为为在线
                                    if (m_cacheGetMtCfgResult.u8State != (byte)enMoteState.Lost)
                                    {
                                        lock (m_dicOnLineWs) { m_dicOnLineWs.Add(m_cacheGetMtCfgResult.mac.ToHexString(), true); }
                                    }
                                    else
                                    {
                                        lock (m_dicOnLineWs) { m_dicOnLineWs.Add(m_cacheGetMtCfgResult.mac.ToHexString(), false); }
                                    }
                                }
                                else
                                {
                                    m_macManager = (string)(m_cacheGetMtCfgResult.mac.ToHexString()).Clone();
                                }

                                queryIter.Assign(m_cacheGetMtCfgResult.mac);
                                goto ITERATOR;
                            }
                            else if (m_cacheGetMtCfgResult.RC == eRC.RC_END_OF_LIST)
                            {
                                queryIter.Assign(new tMAC("0000000000000000"));
                                m_Mesh.IsQueryingAllWs = false;
                                lock (m_dicOnLineWs)
                                {
                                    if (QueryAllWsReaultNotify != null)
                                    {
                                        QueryAllWsReaultNotify(m_dicOnLineWs);
                                    }
                                }
                                CommStackLog.RecordInf(enLogLayer.eAdapter, "QueryAllWs end");
                            }
                            else
                            {
                                m_Mesh.IsQueryingAllWs = false;
                                if (queryAllWsFailed != null)
                                {
                                    queryAllWsFailed();
                                }
                            }
                        }
                        else
                        {
                            m_Mesh.IsQueryingAllWs = false;
                            if (queryAllWsFailed != null)
                            {
                                queryAllWsFailed();
                            }
                        }

                        continue;
                    }

                    int iWsCnt1 = 0;
                    lock (m_dicOnLineWs) { iWsCnt1 = m_dicOnLineWs.Count; }
                    if (iWsCnt1 == 0)    // 1 网络中无在线的WS
                    {
                        // 1.1 本次心跳周期内无接收到的报文
                        if (m_Serial.RxFrameCnt <= 0)
                        {
                            if (m_macManager == string.Empty)
                            {
                                Thread.Sleep(200);
                                continue;
                            }
                            // 1.1.0 通过GetMoteConfig(Manager)感知系统脉搏
                            m_asigGetMtCfg.Reset();
                            m_bGetMtCfgTimeout = false;
                            GetMoteConfig(new tMAC(m_macManager));
                            m_asigGetMtCfg.WaitOne();
                            // 1.1.1 GetMoteConfig(Manager)超时
                            if (m_bGetMtCfgTimeout)
                            {
                                if (m_u8HeartbeatRetryCnt++ > HEARTBEET_RETRY_TIMES)
                                {
                                    m_u8HeartbeatRetryCnt = 0;
                                    CommStackLog.RecordInf(enLogLayer.eAdapter, "Pace-making failed!");
                                    sessnLost();
                                }
                                else
                                {
                                    CommStackLog.RecordInf(enLogLayer.eAdapter, "Pace-making timeout!");
                                }
                            }
                            // 1.1.2 GetMoteConfig(Manager)正常
                            else
                            {
                                CommStackLog.RecordInf(enLogLayer.eAdapter, "Pace-making");
                            }
                        }
                        // 1.2 本次心跳周期内有接收到的报文
                        else
                        {
                            CommStackLog.RecordInf(enLogLayer.eAdapter, "Pace-making(Rx " + m_Serial.RxFrameCnt + ")");
                            // Added in 2016.10.21 by Kous,添加下一条语句
                            m_Serial.RxFrameCnt = 0;
                        }
                    }
                    else   // 2 网络中有在线的WS
                    {
                        // 2.0 通过GetMoteConfig感知系统脉搏
                        m_asigGetMtCfg.Reset();
                        m_bGetMtCfgTimeout = false;
                        lock (m_dicOnLineWs) { GetMoteConfig(new tMAC(m_dicOnLineWs.Keys.ElementAt(m_i32MoniterWsIdx))); }
                        m_asigGetMtCfg.WaitOne();
                        // 2.1 GetMoteConfig超时
                        if (m_bGetMtCfgTimeout)
                        {
                            if (m_u8HeartbeatRetryCnt++ > HEARTBEET_RETRY_TIMES)
                            {
                                m_u8HeartbeatRetryCnt = 0;
                                CommStackLog.RecordInf(enLogLayer.eAdapter, "Pace-making failed!");
                                sessnLost();
                            }
                            else
                            {
                                CommStackLog.RecordInf(enLogLayer.eAdapter, "Pace-making timeout!");
                            }
                        }
                        // 2.2 GetMoteConfig正常
                        else
                        {
                            CommStackLog.RecordInf(enLogLayer.eAdapter, "Pace-making");
                            m_u8HeartbeatRetryCnt = 0;
                            int iWsCnt2 = 0;
                            lock (m_dicOnLineWs) { iWsCnt2 = m_dicOnLineWs.Count; }
                            // 轮询完毕,从头开始
                            if (++m_i32MoniterWsIdx >= iWsCnt2)
                            {
                                m_i32MoniterWsIdx = 0;
                            }
                        }
                    }

                    int residueSleepTime = cfgHeartbeatInterval;
                    while (residueSleepTime > 200)
                    {
                        Thread.Sleep(200);
                        if (m_Mesh.IsQueryingAllWs)
                        {
                            break;
                        }
                        residueSleepTime = residueSleepTime - 200;
                    }

                    if (m_Mesh.IsQueryingAllWs)
                    {
                        continue;
                    }

                    if (residueSleepTime > 0)
                    {
                        Thread.Sleep(residueSleepTime);
                    }

                    continue;
                }
                catch (Exception ex)
                {
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Message:" + ex.Message);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "Source: " + ex.Source);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "StackTrace: " + ex.StackTrace);
                    CommStackLog.RecordErr(enLogLayer.eAdapter, "ToString: " + ex.ToString());
                }
            }
        }