예제 #1
0
        public List <DataPoint> GetDataPoints(IPsnProtocolConfiguration protocol,
                                              IPsnProtocolCommandPartConfiguration commandPart, IPsnProtocolParameterConfiguration paramInfo,
                                              DateTime beginTime)
        {
            // Если конфигурация была изменена:
            if (_lastPsnProtocolId != null && _lastPsnProtocolId.IdentyString != protocol.Information.Id.IdentyString)
            {
                FreeResources();
            }

            if (_areResourcesFree)
            {
                FillResources(protocol, beginTime, protocol.CycleCommandParts, protocol.CommandParts);
            }

            var result = new List <DataPoint>();

            bool isWatchForRequestNeeded;
            Func <IPsnMapRecord, IPsnMapSubrecord> funcGetPart;

            if (commandPart.PartType == PsnProtocolCommandPartType.Request)
            {
                funcGetPart             = FuncGetPartRequest;
                isWatchForRequestNeeded = false;
            }
            else if (commandPart.PartType == PsnProtocolCommandPartType.Reply)
            {
                funcGetPart             = FuncGetPartReply;
                isWatchForRequestNeeded = false;
            }
            else /*if (commandPart.PartType == PsnProtocolCommandPartType.ReplyWithRequiredRequest)*/
            {
                funcGetPart             = FuncGetPartReply;
                isWatchForRequestNeeded = true;
            }

            // поток данных нужен для извлечения самих данных (т.к. изначально их нет в карте (есть только информация о местоположении и времени команд протокола ПСН)
            // можно разделить алгоритм на две части: выборку из карты инфомрации об интересующем сигнале, а затем - заполнение значений из потока данных
            for (int i = 0; i < _commandsMap.Count; ++i)
            {
                if (_commandsMap[i].CommandId.IdentyString == commandPart.CommandId.IdentyString)
                {
                    IPsnMapSubrecord needRec = funcGetPart.Invoke(_commandsMap[i]);

                    if (needRec != null)
                    {
                        if (isWatchForRequestNeeded && _commandsMap[i].RequestRecordInfo != null ||
                            !isWatchForRequestNeeded)
                        {
                            // CRC ok
                            int positionInGoodData = needRec.LocationInfo.Position;
                            result.Add(new DataPoint(paramInfo.GetValue(_goodPagesOnlyGoodBytes, positionInGoodData),
                                                     needRec.LocationInfo.Time, true, positionInGoodData));
                        }
                    }
                }
            }

            return(result);
        }
예제 #2
0
        private BigList <IPsnMapRecord> BuildCommandsMap(IPsnProtocolCommandPartConfiguration[] cmdParts,
                                                         IEnumerable <IPsnProtocolCommandPartConfigurationCycle> cycleCmdPartInfos, byte[] dataBytes,
                                                         DateTime psnLogBeginTime, List <IPsnPageIndexRecord> pagesIndex)
        {
            // Структура записи будет:
            // Запись:
            //     Запрос:
            //         - позиция
            //         - кусок команды
            //     Ответ:
            //         - позиция
            //         - кусок команды
            var result = new BigList <IPsnMapRecord>();
            var time   = psnLogBeginTime;
            var cycleCmdPartInfoArray = cycleCmdPartInfos as IPsnProtocolCommandPartConfigurationCycle[] ??
                                        cycleCmdPartInfos.ToArray();
            IPsnMapSubrecord prevRequestSubrec = null; // Запрос из предыдущей итерации (изначально его нет)

            RunThroughDataAndExectueCustomActionOnCommandPartsFound(
                cmdParts,
                dataBytes,
                partsPosition =>
            {
                try
                {
                    IPsnCommandPartsPosition currPtLocInfo =
                        new PsnCommandPartsAndPosition(partsPosition.DataPosition,
                                                       partsPosition.CrcOkPartLocationInfo);
                    var pageIndex = currPtLocInfo.DataPosition /
                                    (_extractor.PsnPageSize - _extractor.PsnPageHeaderLength);

                    var pageWhereCmdPartLocated = pagesIndex[pageIndex];
                    // Подгонка времени до страничного, если время теущей страницы больше времени
                    if (pageWhereCmdPartLocated.PageTime.HasValue)
                    {
                        if (pageWhereCmdPartLocated.PageTime.Value > time)
                        {
                            time = pageWhereCmdPartLocated.PageTime.Value;
                        }
                    }

                    // -1. Если среди текущих найденных кусков команд есть циклическай кусок с правильной контрольной суммой, то время инкрементируется:
                    for (int j = 0; j < cycleCmdPartInfoArray.Length; ++j)
                    {
                        if (currPtLocInfo.CrcOkPartLocationInfo.Id.IdentyString ==
                            cycleCmdPartInfoArray[j].Id.IdentyString)
                        {
                            time = time.Add(cycleCmdPartInfoArray[j].CyclePeriod);
                            break;
                        }
                    }


                    // 0. К этой точке есть готовое время для текущей части команды - переменная time

                    var currentTruelyFoundCommandPart = currPtLocInfo.CrcOkPartLocationInfo;

                    bool isCurrentTruelyFoundCommandPartRepliedOnPrevRequest =
                        false;     // является ли точно найденная команда ответом на предыдущий запрос
                    // Если предыдущий запрос есть, то вероятно надо искать ответ на него:
                    if (prevRequestSubrec != null)
                    {
                        if (currentTruelyFoundCommandPart.PartType == PsnProtocolCommandPartType.Reply ||
                            currentTruelyFoundCommandPart.PartType ==
                            PsnProtocolCommandPartType.ReplyWithRequiredRequest)
                        {
                            if (prevRequestSubrec.CommandPart.CommandId.IdentyString ==
                                currentTruelyFoundCommandPart.CommandId.IdentyString)
                            {
                                isCurrentTruelyFoundCommandPartRepliedOnPrevRequest = true;
                            }
                        }
                    }

                    if (currentTruelyFoundCommandPart.PartType == PsnProtocolCommandPartType.Request)
                    {
                        // Если до этого уже был запрос, то он сохраняется в карту как безответная запись:
                        if (prevRequestSubrec != null)
                        {
                            result.Add(new PsnMapRecord(
                                           prevRequestSubrec.CommandPart.CommandId,
                                           prevRequestSubrec,
                                           null));
                        }

                        // Текущий запрос сохраняется, для дальнейшего поиска ответа на него:
                        prevRequestSubrec = new PsnMapSubrecord(
                            new PsnCommandPartLocation(
                                currPtLocInfo.DataPosition,
                                time),
                            currentTruelyFoundCommandPart);
                    }
                    else
                    {
                        // Если найден ответ - проверить, является ли ответ ответом на пердыдущий запрос, или это какой-то другой ответ:
                        if (isCurrentTruelyFoundCommandPartRepliedOnPrevRequest)
                        {
                            // Является, нужно сделать одну целую запись:
                            result.Add(new PsnMapRecord(
                                           prevRequestSubrec.CommandPart.CommandId,
                                           prevRequestSubrec,
                                           new PsnMapSubrecord(
                                               new PsnCommandPartLocation(
                                                   currPtLocInfo.DataPosition,
                                                   time),
                                               currentTruelyFoundCommandPart)));
                            prevRequestSubrec = null;
                        }
                        else
                        {
                            // Не является, нужно сделать две записи:
                            // (1) запрос
                            if (prevRequestSubrec != null)
                            {
                                result.Add(new PsnMapRecord(
                                               prevRequestSubrec.CommandPart.CommandId,
                                               prevRequestSubrec,
                                               null));
                                prevRequestSubrec = null;     // Обнуляем запрос после добавления в карту
                            }

                            // (2) ответ
                            result.Add(
                                new PsnMapRecord(
                                    currentTruelyFoundCommandPart.CommandId,
                                    null,
                                    new PsnMapSubrecord(
                                        new PsnCommandPartLocation(
                                            currPtLocInfo.DataPosition,
                                            time),
                                        currentTruelyFoundCommandPart)
                                    ));
                        }
                    }

                    return(partsPosition.CrcOkPartLocationInfo
                           .Length); // Следующий поиск будем проводить с позиции конца хорошей части команды
                }
                catch (OutOfMemoryException ex)
                {
                    throw new Exception("В системе не достаточно памяти для построения командной карты лога", ex);
                }
                catch (Exception ex)
                {
                    throw new Exception(
                        "Ошибка алгоритма постоения командной карты лога, обратитесь к разработчикам программы",
                        ex);
                }
            });
            return(result);
        }
예제 #3
0
 public PsnMapRecord(IIdentifier commandId, IPsnMapSubrecord requestRecordInfo, IPsnMapSubrecord replyRecordInfo)
 {
     CommandId         = commandId;
     RequestRecordInfo = requestRecordInfo;
     ReplyRecordInfo   = replyRecordInfo;
 }