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