/// <summary> /// Expect an Acknowledge message from GPS serial device /// </summary> /// <param name="classId">Class ID of expected acknowledge message</param> /// <param name="messageId">Message ID of expected acknowledge message</param> /// <returns>True if ACK message is received, False if NOT-ACK message is received</returns> /// <remarks> /// Use this method to wait acknowledge message (ACK/NOT-ACK) from serial device after transmitting /// configuration message to the device. This method will wait indefinitely until ACK/NOT-ACK message /// for specified class and message ID is received. /// </remarks> public async Task <bool> ExpectAcknowledgeAsync(byte classId, byte messageId) { var expectingDesc = new ExpectingDescription(classId, messageId); if (expectingList.ContainsKey(expectingDesc)) { throw new InvalidOperationException(String.Format("Already expecting ACK for Class {0}, MessageID {1}", classId, messageId)); } var expectingContext = new ExpectingContext(); expectingList.Add(expectingDesc, expectingContext); await expectingContext.WaitForResponse(); expectingList.Remove(expectingDesc); var retVal = expectingContext.ResponseReceived; if (retVal is Acknowledge) { return(true); } else { return(false); } }
/// <summary> /// Expect a message of specific type from GPS serial device. /// </summary> /// <typeparam name="T">Type of message which is expected</typeparam> /// <returns>The message which is expected</returns> /// <remarks> /// This method is performed asynchronously and it should be awaited. The method will complete /// when it receive the <u>first message</u> with required type or if it is aborted by calling /// <see cref="AbortExpectAsync{T}"/>. /// </remarks> public async Task <T> ExpectAsync <T>() where T : UBXModelBase { // Create expecting description as key var expectingDesc = new ExpectingDescription(typeof(T)); // invalid operation if other context already expecting the same type at the same time if (expectingList.ContainsKey(expectingDesc)) { throw new InvalidOperationException(String.Format("Already expecting type {0}", typeof(T).FullName)); } // Create expecting context var expectingContext = new ExpectingContext(); // Add to expecting list expectingList.Add(expectingDesc, expectingContext); // Wait indefinitely until the response of the type is received await expectingContext.WaitForResponse(); // At this point, the message is received // Remove from expecting list expectingList.Remove(expectingDesc); // Return the message object to the caller return((T)expectingContext.ResponseReceived); }
public override bool Equals(object obj) { if (base.Equals(obj)) { return(true); } else { ExpectingDescription desc = obj as ExpectingDescription; if (desc != null) { if (this.expectedMessageMode == desc.expectedMessageMode) { if (this.expectedMessageMode == ExpectingMode.Regular) { return(this.expectingType.Equals(desc.expectingType)); } else { return(this.classId == desc.classId && this.messageId == desc.messageId); } } } } return(false); }
/// <summary> /// Abort the asynchronous ExpectAsync operation. /// </summary> /// <typeparam name="T"></typeparam> /// <remarks> /// This method is used if you want to implement timeout on <see cref="ExpectAsync{T}"/> execution. /// The ExpectAsync method will return null if it is awaited. /// </remarks> public void AbortExpectAsync <T>() { var expectingDesc = new ExpectingDescription(typeof(T)); if (!expectingList.ContainsKey(expectingDesc)) { return; } var expectingContext = expectingList[expectingDesc]; expectingList.Remove(expectingDesc); expectingContext.Cancel(); }
/// <summary> /// Notify any party if waits a message of this type /// </summary> /// <param name="obj">The message to be notified</param> /// <returns>True if there is a party that is waiting for this kind of message, false otherwise.</returns> public bool NotifyIfExpected(UBXModelBase obj) { var expectingDesc = new ExpectingDescription(obj); try { var expectingContext = expectingList[expectingDesc]; expectingContext.NotifyResponseReceived(obj); return(true); } catch (KeyNotFoundException) { return(false); } }