/// <summary> /// Remove message from wait queue /// </summary> /// <param name="msgId">The message Id corresponding to the message that needs to be removed</param> public void RemoveFromWaitQ(UInt16 msgId) { bool found = false; this._waitEvent.WaitOne();//Wait for thread to release the queue try { int count = 0; for (count = 0; count < this._conMessageQ.Count; count++) { AbstractCoAPMessage coapMsgInQ = (AbstractCoAPMessage)this._conMessageQ[count]; if (coapMsgInQ.ID.Value == msgId) { found = true; break; } } if (found && count < this._conMessageQ.Count) { this._conMessageQ.RemoveAt(count); } } catch (Exception e) { AbstractLogUtil.GetLogger().LogError(e.ToString()); ;; //TOCHECK::nothing for now } finally { this._waitEvent.Set();//Now allow others to work on the queue } }
/// <summary> /// The thread procedure that continues to poll /// the queue for timeout /// </summary> protected void PollQ() { bool timedOut = false; int count = 0; while (!this._isDone) { Thread.Sleep((int)this._minTimeoutSecs * 1000); _waitEvent.WaitOne();//Wait for others to release the Q for (count = 0; count < this._conMessageQ.Count; count++) { AbstractCoAPMessage coapMsg = (AbstractCoAPMessage)this._conMessageQ[count]; DateTime timeoutAt = coapMsg.DispatchDateTime.AddSeconds(coapMsg.Timeout); if (timeoutAt < DateTime.Now /*Message timed out*/) { timedOut = true; break;//We process one timeout at a time } } if (timedOut && count < this._conMessageQ.Count) { AbstractCoAPMessage coapMsg = (AbstractCoAPMessage)this._conMessageQ[count]; this._conMessageQ.RemoveAt(count); this._waitEvent.Set();//Release Q count = 0; timedOut = false; if (this.OnResponseTimeout != null) { try { this.OnResponseTimeout(coapMsg); } catch (Exception e) { AbstractLogUtil.GetLogger().LogError(e.ToString()); /*we do not want to crash the Q because client crashed processing*/} } } this._waitEvent.Set();//Release Q...for all cases } }
/// <summary> /// Get the request message that was pending response /// </summary> /// <param name="msgId">The message Id corresponding to the message that needs to be extracted</param> /// <returns>A copy of the request object pending response (if found), else null</returns> public CoAPRequest GetRequestPendingResponse(UInt16 msgId) { this._waitEvent.WaitOne();//Wait for thread to release the queue CoAPRequest foundReq = null; try { int count = 0; for (count = 0; count < this._conMessageQ.Count; count++) { AbstractCoAPMessage coapMsgInQ = (AbstractCoAPMessage)this._conMessageQ[count]; if (coapMsgInQ.ID.Value == msgId) { /*Found*/ foundReq = new CoAPRequest(coapMsgInQ.MessageType.Value, coapMsgInQ.Code.Value, coapMsgInQ.ID.Value); foreach (CoAPHeaderOption option in coapMsgInQ.Options) foundReq.AddOption(option.Number, option.Value); foundReq.Token = coapMsgInQ.Token; foundReq.Payload = coapMsgInQ.Payload; foundReq.RemoteSender = coapMsgInQ.RemoteSender; break; } } } catch (Exception e) { AbstractLogUtil.GetLogger().LogError(e.ToString()); ; ;//TOCHECK::nothing for now } finally { this._waitEvent.Set();//Now allow others to work on the queue } return foundReq; }
/// <summary> /// Handle error conditions during CoAP exchange /// </summary> /// <param name="ex">The exception that occurred</param> /// <param name="coapMsg">The CoAP message</param> protected void HandleError(Exception ex, AbstractCoAPMessage coapMsg) { CoAPErrorHandler errHandler = CoAPError; try { if (errHandler != null) { errHandler(ex, coapMsg); } } catch (Exception e) { AbstractLogUtil.GetLogger().LogError(e.ToString()); //Do nothing else...do not want to bring down the whole thing because handler failed } }
/// <summary> /// Raised when a CoAP response is received /// </summary> /// <param name="coapResp">CoAPResponse</param> protected void HandleResponseReceived(CoAPResponse coapResp) { CoAPResponseReceivedHandler respRxHandler = CoAPResponseReceived; try { if (respRxHandler != null) { respRxHandler(coapResp); } } catch (Exception e) { AbstractLogUtil.GetLogger().LogError(e.ToString()); //Do nothing else...do not want to bring down the whole thing because handler failed } }