예제 #1
0
        public bool GetComParameterValue(ParamName name, out int result)
        {
            ComParameter param = GetComParameterByName(name.ToString());

            if (param is null)
            {
                result = 0;
                return(false);
            }
            else
            {
                result = param.ComParamValue;
                return(true);
            }
        }
예제 #2
0
        public void CreateComParameters(BinaryReader reader, ECU parentEcu)
        {
            // this is unusual as it doesn't use the usual caesar-style bitflag reads
            // for reasons unknown the comparam is attached to the basevariant
            long comparamBaseAddress = BaseAddress + ComParamsOffset;

            // Console.WriteLine($"Comparam base: 0x{comparamBaseAddress:X} : number of comparams: {ComParamsCount} ");
            reader.BaseStream.Seek(comparamBaseAddress, SeekOrigin.Begin);
            List <long> comparameterOffsets = new List <long>();

            for (int comIndex = 0; comIndex < ComParamsCount; comIndex++)
            {
                comparameterOffsets.Add(reader.ReadInt32() + comparamBaseAddress);
            }

            if (parentEcu.ECUInterfaces.Count == 0)
            {
                throw new Exception("Invalid communication parameter : no parent interface");
            }

            foreach (long comparamOffset in comparameterOffsets)
            {
                ComParameter param = new ComParameter(reader, comparamOffset, parentEcu.ECUInterfaces, Language);

                // KW2C3PE uses a different parent addressing style
                int parentIndex = param.ParentInterfaceIndex > 0 ? param.ParentInterfaceIndex : param.SubinterfaceIndex;

                if (param.ParentInterfaceIndex >= parentEcu.ECUInterfaceSubtypes.Count)
                {
                    throw new Exception("ComParam: tried to assign to nonexistent interface");
                }
                else
                {
                    parentEcu.ECUInterfaceSubtypes[parentIndex].CommunicationParameters.Add(param);
                }
            }
        }
예제 #3
0
        public DiagService(BinaryReader reader, CTFLanguage language, long baseAddress, int poolIndex, ECU parentEcu)
        {
            ParentECU   = parentEcu;
            PoolIndex   = poolIndex;
            BaseAddress = baseAddress;
            reader.BaseStream.Seek(baseAddress, SeekOrigin.Begin);

            ulong bitflags        = reader.ReadUInt32();
            ulong bitflagExtended = reader.ReadUInt32();

            Qualifier = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            Name_CTF        = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);
            Description_CTF = CaesarReader.ReadBitflagInt32(ref bitflags, reader, -1);

            DataClass_ServiceType        = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);
            DataClass_ServiceTypeShifted = 1 << (DataClass_ServiceType - 1);

            IsExecutable        = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);;
            ClientAccessLevel   = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);;
            SecurityAccessLevel = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);;

            T_ComParam_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            T_ComParam_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Q_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Q_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            R_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            R_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            InputRefNameMaybe = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            U_prep_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            U_prep_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            // array of DWORDs, probably reference to elsewhere
            V_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            V_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            RequestBytes_Count  = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            RequestBytes_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            W_OutPres_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            W_OutPres_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            field50 = CaesarReader.ReadBitflagUInt16(ref bitflags, reader);

            NegativeResponseName = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress); // negative response name
            UnkStr3 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);
            UnkStr4 = CaesarReader.ReadBitflagStringWithReader(ref bitflags, reader, baseAddress);

            P_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            P_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            DiagServiceCodeCount  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            DiagServiceCodeOffset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            S_Count  = CaesarReader.ReadBitflagInt16(ref bitflags, reader);
            S_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            bitflags = bitflagExtended;

            X_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            X_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Y_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Y_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            Z_Count  = CaesarReader.ReadBitflagInt32(ref bitflags, reader);
            Z_Offset = CaesarReader.ReadBitflagInt32(ref bitflags, reader);

            if (RequestBytes_Count > 0)
            {
                reader.BaseStream.Seek(baseAddress + RequestBytes_Offset, SeekOrigin.Begin);
                RequestBytes = reader.ReadBytes(RequestBytes_Count);
            }
            else
            {
                RequestBytes = new byte[] { };
            }

            // u_table to u_entries
            InputPreparations = new List <DiagPreparation>();
            for (int prepIndex = 0; prepIndex < U_prep_Count; prepIndex++)
            {
                long presentationTableOffset = baseAddress + U_prep_Offset;
                reader.BaseStream.Seek(presentationTableOffset + (prepIndex * 10), SeekOrigin.Begin);

                // DIOpenDiagService (reads 4, 4, 2 then calls DiagServiceReadPresentation) to build a presentation
                int    prepEntryOffset = reader.ReadInt32();  // file: 0 (DW)
                int    prepEntryBitPos = reader.ReadInt32();  // file: 4 (DW)
                ushort prepEntryMode   = reader.ReadUInt16(); // file: 8 (W)

                DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);
                //preparation.PrintDebug();
                InputPreparations.Add(preparation);
            }


            OutputPreparations = new List <List <DiagPreparation> >();
            long outPresBaseAddress = BaseAddress + W_OutPres_Offset;

            for (int presIndex = 0; presIndex < W_OutPres_Count; presIndex++)
            {
                reader.BaseStream.Seek(outPresBaseAddress + (presIndex * 8), SeekOrigin.Begin);
                int resultPresentationCount  = reader.ReadInt32();
                int resultPresentationOffset = reader.ReadInt32();

                List <DiagPreparation> ResultPresentationSet = new List <DiagPreparation>();
                for (int presInnerIndex = 0; presInnerIndex < resultPresentationCount; presInnerIndex++)
                {
                    long presentationTableOffset = outPresBaseAddress + resultPresentationOffset;
                    reader.BaseStream.Seek(presentationTableOffset + (presIndex * 10), SeekOrigin.Begin);

                    int    prepEntryOffset = reader.ReadInt32();  // file: 0 (DW)
                    int    prepEntryBitPos = reader.ReadInt32();  // file: 4 (DW)
                    ushort prepEntryMode   = reader.ReadUInt16(); // file: 8 (W)

                    DiagPreparation preparation = new DiagPreparation(reader, language, presentationTableOffset + prepEntryOffset, prepEntryBitPos, prepEntryMode, parentEcu, this);
                    ResultPresentationSet.Add(preparation);
                }
                OutputPreparations.Add(ResultPresentationSet);
            }

            DiagComParameters = new List <ComParameter>();
            long comParamTableBaseAddress = BaseAddress + T_ComParam_Offset;

            for (int cpIndex = 0; cpIndex < T_ComParam_Count; cpIndex++)
            {
                reader.BaseStream.Seek(comParamTableBaseAddress + (cpIndex * 4), SeekOrigin.Begin);
                int          resultCpOffset     = reader.ReadInt32();
                long         cpEntryBaseAddress = comParamTableBaseAddress + resultCpOffset;
                ComParameter cp = new ComParameter(reader, cpEntryBaseAddress, parentEcu.ECUInterfaces);
                DiagComParameters.Add(cp);
            }

            // DJ_Zugriffsberechtigung_Abgleich
            // DJ_Zugriffsberechtigung
            // DT_Abgasklappe_kontinuierlich
            // FN_HardReset
            // WVC_Implizite_Variantenkodierung_Write

            // NR_Disable_Resp_required noexec
            // DT_Laufzeiten_Resetzaehler_nicht_implementiert exec

            /*
             * if (false && qualifierName.Contains("RVC_SCN_Variantencodierung_VGS_73_Lesen"))
             * {
             *
             *  Console.WriteLine($"{nameof(field50)} : {field50}");
             *  Console.WriteLine($"{nameof(IsExecutable)} : {IsExecutable} {IsExecutable != 0}");
             *  Console.WriteLine($"{nameof(AccessLevel)} : {AccessLevel}");
             *  Console.WriteLine($"{nameof(SecurityAccessLevel)} : {SecurityAccessLevel}");
             *  Console.WriteLine($"{nameof(DataClass)} : {DataClass}");
             *
             *
             *
             *  Console.WriteLine($"{qualifierName} - ReqBytes: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, Preparation: {U_prep_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}");
             *  Console.WriteLine($"at 0x{baseAddress:X}, W @ 0x{W_Offset:X}, DSC @ 0x{DiagServiceCodeOffset:X}");
             *  Console.WriteLine($"ReqBytes: {BitUtility.BytesToHex(RequestBytes)}");
             * }
             */
            //Console.WriteLine($"{qualifierName} - O: {RequestBytes_Count}, P: {P_Count}, Q: {Q_Count}, R: {R_Count}, S: {S_Count}, T: {T_Count}, U: {U_Count}, V: {V_Count}, W: {W_Count}, X: {X_Count}, Y: {Y_Count}, Z: {Z_Count}, DSC {DiagServiceCodeCount}");


            byte[] dscPool             = parentEcu.ParentContainer.CaesarCFFHeader.DSCPool;
            long   dscTableBaseAddress = BaseAddress + DiagServiceCodeOffset;

            using (BinaryReader dscPoolReader = new BinaryReader(new MemoryStream(dscPool)))
            {
                for (int dscIndex = 0; dscIndex < DiagServiceCodeCount; dscIndex++)
                {
                    reader.BaseStream.Seek(dscTableBaseAddress + (4 * dscIndex), SeekOrigin.Begin);
                    long dscEntryBaseAddress = reader.ReadInt32() + dscTableBaseAddress;
                    reader.BaseStream.Seek(dscEntryBaseAddress, SeekOrigin.Begin);

                    ulong  dscEntryBitflags = reader.ReadUInt16();
                    uint   idk1             = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);
                    uint   idk2             = CaesarReader.ReadBitflagUInt8(ref dscEntryBitflags, reader);
                    int    dscPoolOffset    = CaesarReader.ReadBitflagInt32(ref dscEntryBitflags, reader);
                    string dscQualifier     = CaesarReader.ReadBitflagStringWithReader(ref dscEntryBitflags, reader, dscEntryBaseAddress);

                    dscPoolReader.BaseStream.Seek(dscPoolOffset * 8, SeekOrigin.Begin);
                    long dscRecordOffset = dscPoolReader.ReadInt32() + parentEcu.ParentContainer.CaesarCFFHeader.DscBlockOffset;
                    int  dscRecordSize   = dscPoolReader.ReadInt32();

                    reader.BaseStream.Seek(dscRecordOffset, SeekOrigin.Begin);

                    // Console.WriteLine($"DSC {qualifierName} @ 0x{dscTableBaseAddress:X8} {idk1}/{idk2} pool @ 0x{dscPoolOffset:X}, name: {dscQualifier}");
                    byte[] dscBytes = reader.ReadBytes(dscRecordSize);
#if DEBUG
                    //string dscName = $"{parentEcu.Qualifier}_{Qualifier}_{dscIndex}.pal";
                    //Console.WriteLine($"Exporting DSC: {dscName}");
                    //File.WriteAllBytes(dscName, dscBytes);
#endif
                    // at this point, the DSC binary is available in dscBytes, intended for use in DSCContext (but is currently unimplemented)
                    // Console.WriteLine($"DSC actual at 0x{dscRecordOffset:X}, size=0x{dscRecordSize:X}\n");
                }
            }
        }