public bool isEqual(tMAC refer) { for (int i = 0; i < LEN; i++) { if (u8aData[i] != refer.u8aData[i]) { return(false); } } return(true); }
public void Assign(object right) { tMAC val = right as tMAC; if (val == null) { throw new Exception("object is not tMAC type!"); } else { Array.Copy(val.u8aData, 0, this.u8aData, 0, LEN); } }
/// <summary> /// 从请求升级队列中删除特定的WS /// </summary> /// <param name="deleteMote">删除的WS地址</param> private void deleteReqUpdatedWs(tMAC deleteMote) { lock (lstUpdWs) { foreach (tMAC mote in lstUpdWs) { if (mote.isEqual(deleteMote)) { lstUpdWs.Remove(mote); break; } } } }
/// <summary> /// 进行WS固件升级 /// </summary> /// <param name="macList">请求升级的WS列表</param> /// <param name="firmware">请求升级的固件信息</param> /// <returns>请求成功与否</returns> public bool Update(List <tMAC> macList, tFirmware firmware) { if (macList == null || macList.Count == 0 || firmware == null || firmware.DicFwBlockDat == null || firmware.DicFwBlockDat.Count == 0) { return(false); } try { // 复制一份升级mote列表 lstUpdWs = new List <tMAC>(); foreach (tMAC mote in macList) { tMAC addMote = new tMAC(); addMote.Assign(mote); lstUpdWs.Add(addMote); } // 复制一份固件信息 fw = new tFirmware(firmware); // 构造升级线程 Thread threadUpdateWorker = new Thread(UpdateHandler); threadUpdateWorker.Name = "UpdateHandler"; threadUpdateWorker.Priority = ThreadPriority.AboveNormal; // 线程升级线程 threadUpdateWorker.Start(); return(true); } 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()); return(false); } }
/// <summary> /// 对特定WS下发固件描述信息 /// </summary> /// <param name="moteMac">升级的WS</param> /// <returns>成功与否</returns> private bool SendFwDesc(tMAC moteMac) { tSetFwDescInfoParam FwDescInfoParam = new tSetFwDescInfoParam(); FwDescInfoParam.u32MagicWord = fw.FwDesc.u32MagicWord; FwDescInfoParam.FwVer.u8Main = fw.FwDesc.verFw.u8Main; FwDescInfoParam.FwVer.u8Sub = fw.FwDesc.verFw.u8Sub; FwDescInfoParam.FwVer.u8Rev = fw.FwDesc.verFw.u8Rev; FwDescInfoParam.FwVer.u8Build = fw.FwDesc.verFw.u8Build; FwDescInfoParam.u32FwSize = fw.FwDesc.u32Size; FwDescInfoParam.u8MaxBlkSize = fw.FwDesc.u8BlockSize; FwDescInfoParam.u32EntryPoint = fw.FwDesc.u32EntryPoint; FwDescInfoParam.mac.Assign(moteMac); asigFwDescSent.Reset(); fwDescSentOK = false; // 发送固件描述信息 SetFwDescInfo(FwDescInfoParam, true); // 等待固件描述信息应用层响应 asigFwDescSent.WaitOne(); return(fwDescSentOK); }
/// <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> /// 升级过程处理函数 /// </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> /// <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> /// <param name="wsMac"></param> private void setFwDescFail(tMAC wsMac) { fwDescSentOK = false; asigFwDescSent.Set(); }
/// <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()); } } }