/// <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); }
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; }
/// <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(); }
/// <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); } }
/// <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; }
/// <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)); } }
/// <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; }
/// <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); } } }
/// <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; } }
/// <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); } } }
/// <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); } }
/// <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); }
/// <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; } }
/// <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); } } }
/// <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); } }
/// <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); } } }
/// <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; } }
/// <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); } }
/// <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()); } } }