//Thread safety in this method assumes that each thread will have unique comparers public GetMessageResults GetMessages(int NumMsgs, int Timeout, Predicate <J2534Message> ComparerHandle, bool Remove) { bool GetMoreMessages; Stopwatch FunctionTimer = new Stopwatch(); FunctionTimer.Start(); do { GetMessageResults RxMessages = GetMessages(CONST.HEAPMESSAGEBUFFERSIZE, 0); if (RxMessages.Status == J2534ERR.STATUS_NOERROR || RxMessages.Status == J2534ERR.BUFFER_EMPTY) { MessageSieve.Sift(RxMessages.Messages); } else { throw new J2534Exception(RxMessages.Status, Device.Library.GetLastError()); } GetMoreMessages = (MessageSieve.ScreenMessageCount(ComparerHandle) < NumMsgs); } while (GetMoreMessages && (FunctionTimer.ElapsedMilliseconds < Timeout)); if (GetMoreMessages) { return(new GetMessageResults(MessageSieve.EmptyScreen(ComparerHandle, Remove), J2534ERR.TIMEOUT)); } else { return(new GetMessageResults(MessageSieve.EmptyScreen(ComparerHandle, Remove), J2534ERR.STATUS_NOERROR)); } }
/// <summary> /// Reads 'NumMsgs' messages from the input buffer and then the device. Will block /// until it gets 'NumMsgs' messages, or 'Timeout' expires. /// </summary> /// <param name="NumMsgs"></param> /// <param name="Timeout"></param> /// <returns>Returns 'false' if successful</returns> public GetMessageResults GetMessages(int NumMsgs, int Timeout) { GetMessageResults Results = new GetMessageResults(); lock (Device.Library.API_LOCK) { HeapMessageArray.Length = NumMsgs; Results.Status = (J2534ERR)Device.Library.API.ReadMsgs(ChannelID, HeapMessageArray, HeapMessageArray.Length, Timeout); Results.Messages = HeapMessageArray.ToList(); } return(Results); }
/// <summary> /// Attempts to read 'NumMsgs' messages from the J2534 Device within 'Timeout' time. /// </summary> /// <param name="NumMsgs">The desired number of J2534 messages. Due to timeouts, the number of messages returned may be less than the number requested. Number must be less than or equal to J2534.CONST.HEAPMESSAGEBUFFERSIZE (default is 200)</param> /// <param name="Timeout">Timeout (in milliseconds) for read completion. A value of zero reads buffered messages and returns immediately. A non-zero value blocks (does not return) until the specified number of messages have been read, or until the timeout expires.</param> /// <returns>Returns get message results</returns> public GetMessageResults GetMessages(int NumMsgs, int Timeout) { GetMessageResults Results = new GetMessageResults(); lock (Device.Library.API_LOCK) { HeapMessageArray.Length = NumMsgs; Results.Status.Code = Device.Library.API.ReadMsgs(ChannelID, HeapMessageArray.Ptr, HeapMessageArray.Length.Ptr, Timeout); if (Results.Status.IsNotOK) { Results.Status.Description = Device.Library.GetLastError(); } Results.Messages = HeapMessageArray.ToJ2534MessageList(); } return(Results); }
//Thread safety in this method assumes that each call will have unique comparers //An option is to lock on the ComparerHandle, but that seems unnecessary //There is no good reason I know of that multiple call would be made to this method //using the same ComparerHandle public GetMessageResults GetMessages(int NumMsgs, int Timeout, Predicate <J2534Message> ComparerHandle, bool Remove) { bool WantMoreMessages; Stopwatch FunctionTimer = new Stopwatch(); FunctionTimer.Start(); long actual_execution_time; do { //execution time is measured here to guarentee the API will actually get //TIMEOUT to export messages. This covers the case of this thread being preempted //and blocked for a significant time. actual_execution_time = FunctionTimer.ElapsedMilliseconds; GetMessageResults RxMessages = GetMessages(CONST.HEAPMESSAGEBUFFERSIZE, 0); if (RxMessages.Status.IsOK || RxMessages.Status.Code == J2534ERR.BUFFER_EMPTY) { MessageSieve.Sift(RxMessages.Messages); } else { throw new J2534Exception(RxMessages.Status); } WantMoreMessages = (MessageSieve.ScreenMessageCount(ComparerHandle) < NumMsgs); } while (WantMoreMessages && (actual_execution_time < Timeout)); if (WantMoreMessages) { return(new GetMessageResults(MessageSieve.EmptyScreen(ComparerHandle, Remove), new J2534Status(J2534ERR.TIMEOUT, "Timeout expired before all messages could be received in GetMessages"))); } else { return(new GetMessageResults(MessageSieve.EmptyScreen(ComparerHandle, Remove), new J2534Status(J2534ERR.STATUS_NOERROR))); } }