Add support for pipe input and file extension handling
- Added stdin pipe support for both encode and decode operations - Implemented file extension-based processing: * .dump files: hex dump format with arrow separators * .hex files: pure hex string data * .xml files: XML content for encoding - Added 'filename --encode' and 'filename --decode' syntax support - Enhanced command line parsing for flexible usage - Updated help text with pipe usage examples 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
7
Data/dump0.dump
Normal file
7
Data/dump0.dump
Normal file
@@ -0,0 +1,7 @@
|
||||
0000 10 22 33 44 55 66 80 34 28 2e 23 dd 86 dd 60 00 ."3DUf.4(.#...`.
|
||||
0010 00 00 00 33 06 ff fe 80 00 00 00 00 00 00 82 34 ...3...........4
|
||||
0020 28 ff fe 2e 23 dd fe 80 00 00 00 00 00 00 12 22 (...#.........."
|
||||
0030 33 ff fe 44 55 66 d1 21 c3 65 2c c5 61 f8 00 63 3..DUf.!.e,.a..c
|
||||
0040 ae c9 50 18 08 a8 72 51 00 00 01 fe 80 01 00 00 ..P...rQ........
|
||||
0050 00 17 80 98 02 10 50 90 8c 0c 0c 0e 0c 51 80 00 ......P......Q..
|
||||
0060 00 00 20 40 c4 08 a0 30 00 .. @...0.
|
||||
7
Data/dump1.dump
Normal file
7
Data/dump1.dump
Normal file
@@ -0,0 +1,7 @@
|
||||
0000 10 22 33 44 55 66 80 34 28 2e 23 dd 86 dd 60 00 ."3DUf.4(.#...`.
|
||||
0010 00 00 00 33 06 ff fe 80 00 00 00 00 00 00 82 34 ...3...........4
|
||||
0020 28 ff fe 2e 23 dd fe 80 00 00 00 00 00 00 12 22 (...#.........."
|
||||
0030 33 ff fe 44 55 66 d1 21 c3 65 2c c5 4a 3c 00 63 3..DUf.!.e,.J<.c
|
||||
0040 9b 49 50 18 0b 26 2f bd 00 00 01 fe 80 01 00 00 .IP..&/.........
|
||||
0050 00 17 80 98 02 10 50 90 8c 0c 0c 0e 0c 51 e0 20 ......P......Q.
|
||||
0060 25 69 68 c0 c0 c0 c0 c0 80 %ih......
|
||||
7
Data/dump2.dump
Normal file
7
Data/dump2.dump
Normal file
@@ -0,0 +1,7 @@
|
||||
0000 80 34 28 2e 23 dd 10 22 33 44 55 66 86 dd 60 00 .4(.#.."3DUf..`.
|
||||
0010 00 00 00 2c 06 ff fe 80 00 00 00 00 00 00 12 22 ...,..........."
|
||||
0020 33 ff fe 44 55 66 fe 80 00 00 00 00 00 00 82 34 3..DUf.........4
|
||||
0030 28 ff fe 2e 23 dd c3 65 d1 21 00 7d 20 74 2c e1 (...#..e.!.} t,.
|
||||
0040 d2 0a 50 18 11 1c 49 71 00 00 01 fe 80 01 00 00 ..P...Iq........
|
||||
0050 00 10 80 98 02 10 50 90 8c 0c 0c 0e 0c 52 11 00 ......P......R..
|
||||
0060 32 00 2.
|
||||
15
Data/encode0.xml
Normal file
15
Data/encode0.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ns1:V2G_Message xmlns:ns1="urn:iso:15118:2:2013:MsgDef" xmlns:ns2="urn:iso:15118:2:2013:MsgHeader" xmlns:ns3="urn:iso:15118:2:2013:MsgBody" xmlns:ns4="urn:iso:15118:2:2013:MsgDataTypes">
|
||||
<ns1:Header>
|
||||
<ns2:SessionID>4142423030303831</ns2:SessionID>
|
||||
</ns1:Header>
|
||||
<ns1:Body>
|
||||
<ns3:WeldingDetectionReq>
|
||||
<ns3:DC_EVStatus>
|
||||
<ns4:EVReady>true</ns4:EVReady>
|
||||
<ns4:EVErrorCode>NO_ERROR</ns4:EVErrorCode>
|
||||
<ns4:EVRESSSOC>100</ns4:EVRESSSOC>
|
||||
</ns3:DC_EVStatus>
|
||||
</ns3:WeldingDetectionReq>
|
||||
</ns1:Body>
|
||||
</ns1:V2G_Message>
|
||||
22
Data/encode1.xml
Normal file
22
Data/encode1.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ns1:V2G_Message xmlns:ns1="urn:iso:15118:2:2013:MsgDef" xmlns:ns2="urn:iso:15118:2:2013:MsgHeader" xmlns:ns3="urn:iso:15118:2:2013:MsgBody" xmlns:ns4="urn:iso:15118:2:2013:MsgDataTypes">
|
||||
<ns1:Header>
|
||||
<ns2:SessionID>4142423030303831</ns2:SessionID>
|
||||
</ns1:Header>
|
||||
<ns1:Body>
|
||||
<ns3:WeldingDetectionRes>
|
||||
<ns3:ResponseCode>OK</ns3:ResponseCode>
|
||||
<ns3:DC_EVSEStatus>
|
||||
<ns4:NotificationMaxDelay>0</ns4:NotificationMaxDelay>
|
||||
<ns4:EVSENotification>StopCharging</ns4:EVSENotification>
|
||||
<ns4:EVSEIsolationStatus>Invalid</ns4:EVSEIsolationStatus>
|
||||
<ns4:EVSEStatusCode>EVSE_Shutdown</ns4:EVSEStatusCode>
|
||||
</ns3:DC_EVSEStatus>
|
||||
<ns3:EVSEPresentVoltage>
|
||||
<ns4:Multiplier>0</ns4:Multiplier>
|
||||
<ns4:Unit>V</ns4:Unit>
|
||||
<ns4:Value>449</ns4:Value>
|
||||
</ns3:EVSEPresentVoltage>
|
||||
</ns3:WeldingDetectionRes>
|
||||
</ns1:Body>
|
||||
</ns1:V2G_Message>
|
||||
22
Data/encode2.xml
Normal file
22
Data/encode2.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ns1:V2G_Message xmlns:ns1="urn:iso:15118:2:2013:MsgDef" xmlns:ns2="urn:iso:15118:2:2013:MsgHeader" xmlns:ns3="urn:iso:15118:2:2013:MsgBody" xmlns:ns4="urn:iso:15118:2:2013:MsgDataTypes">
|
||||
<ns1:Header>
|
||||
<ns2:SessionID>41424230303038313</ns2:SessionID>
|
||||
</ns1:Header>
|
||||
<ns1:Body>
|
||||
<ns3:PreChargeRes>
|
||||
<ns3:ResponseCode>OK</ns3:ResponseCode>
|
||||
<ns3:DC_EVSEStatus>
|
||||
<ns4:NotificationMaxDelay>0</ns4:NotificationMaxDelay>
|
||||
<ns4:EVSENotification>None</ns4:EVSENotification>
|
||||
<ns4:EVSEIsolationStatus>Valid</ns4:EVSEIsolationStatus>
|
||||
<ns4:EVSEStatusCode>EVSE_Ready</ns4:EVSEStatusCode>
|
||||
</ns3:DC_EVSEStatus>
|
||||
<ns3:EVSEPresentVoltage>
|
||||
<ns4:Multiplier>0</ns4:Multiplier>
|
||||
<ns4:Unit>V</ns4:Unit>
|
||||
<ns4:Value>394</ns4:Value>
|
||||
</ns3:EVSEPresentVoltage>
|
||||
</ns3:PreChargeRes>
|
||||
</ns1:Body>
|
||||
</ns1:V2G_Message>
|
||||
1
Data/test_exi.hex
Normal file
1
Data/test_exi.hex
Normal file
@@ -0,0 +1 @@
|
||||
8098021050908C0C0C0E0C5211003200
|
||||
345
Program.cs
345
Program.cs
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace V2GProtocol
|
||||
{
|
||||
@@ -13,22 +14,333 @@ namespace V2GProtocol
|
||||
|
||||
try
|
||||
{
|
||||
// 기본 데이터 파일 경로
|
||||
string dataFilePath = @"data\632 raw data.txt";
|
||||
|
||||
if (args.Length > 0)
|
||||
if (args.Length == 0)
|
||||
{
|
||||
dataFilePath = args[0];
|
||||
}
|
||||
|
||||
if (!File.Exists(dataFilePath))
|
||||
{
|
||||
Console.WriteLine($"Error: Data file not found: {dataFilePath}");
|
||||
Console.WriteLine("Usage: V2GDecoder.exe [data_file_path]");
|
||||
ShowUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Loading data from: {dataFilePath}");
|
||||
var command = args[0].ToLower();
|
||||
|
||||
// 첫 번째 인자가 옵션인 경우 (--decode, --encode, --help)
|
||||
if (command.StartsWith("--") || command.StartsWith("-"))
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "--decode" or "-d":
|
||||
HandleDecodeCommand(args);
|
||||
break;
|
||||
case "--encode" or "-e":
|
||||
HandleEncodeCommand(args);
|
||||
break;
|
||||
case "--help" or "-h":
|
||||
ShowUsage();
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine($"Error: Unknown option: {args[0]}");
|
||||
ShowUsage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 두 번째 인자가 옵션인 경우 (filename --decode, filename --encode)
|
||||
else if (args.Length >= 2 && (args[1].ToLower() == "--decode" || args[1].ToLower() == "-d"))
|
||||
{
|
||||
// filename --decode 형태
|
||||
string[] newArgs = { args[1], args[0] }; // 순서를 바꿔서 --decode filename 형태로 만듦
|
||||
HandleDecodeCommand(newArgs);
|
||||
}
|
||||
else if (args.Length >= 2 && (args[1].ToLower() == "--encode" || args[1].ToLower() == "-e"))
|
||||
{
|
||||
// filename --encode 형태
|
||||
string[] newArgs = { args[1], args[0] }; // 순서를 바꿔서 --encode filename 형태로 만듦
|
||||
HandleEncodeCommand(newArgs);
|
||||
}
|
||||
// 파일명만 전달된 경우 (분석 모드)
|
||||
else if (File.Exists(args[0]))
|
||||
{
|
||||
AnalyzeFile(args[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Error: Unknown option or file not found: {args[0]}");
|
||||
ShowUsage();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
static void ShowUsage()
|
||||
{
|
||||
Console.WriteLine("Usage:");
|
||||
Console.WriteLine(" V2GDecoder.exe [file.txt] # Analyze hex dump file");
|
||||
Console.WriteLine(" V2GDecoder.exe --decode <exi_hex_or_file> # Decode EXI to XML");
|
||||
Console.WriteLine(" V2GDecoder.exe --encode <xml_file_or_string> # Encode XML to EXI");
|
||||
Console.WriteLine(" V2GDecoder.exe <file> --decode # Decode file content to XML");
|
||||
Console.WriteLine(" V2GDecoder.exe <file> --encode # Encode file content to EXI");
|
||||
Console.WriteLine(" V2GDecoder.exe --help # Show this help");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Pipe Usage:");
|
||||
Console.WriteLine(" type file.xml | V2GDecoder.exe --encode # Pipe XML file to encode");
|
||||
Console.WriteLine(" echo \"hex_string\" | V2GDecoder.exe --decode # Pipe hex string to decode");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Examples:");
|
||||
Console.WriteLine(" V2GDecoder.exe data/dump2.txt # Full analysis");
|
||||
Console.WriteLine(" V2GDecoder.exe -d \"8098021050908C0C0C0E0C5211003200\" # Decode hex string");
|
||||
Console.WriteLine(" V2GDecoder.exe -d data/dump2.txt # Extract & decode from file");
|
||||
Console.WriteLine(" V2GDecoder.exe -e \"<V2G_Message>...</V2G_Message>\" # Encode XML string");
|
||||
Console.WriteLine(" V2GDecoder.exe -e message.xml # Encode XML file");
|
||||
Console.WriteLine(" V2GDecoder.exe data/encode0.xml --encode # Encode XML file to EXI");
|
||||
Console.WriteLine(" V2GDecoder.exe data/dump2.txt --decode # Decode file to XML only");
|
||||
Console.WriteLine(" type data\\encode0.xml | V2GDecoder.exe --encode # Pipe file content to encode");
|
||||
Console.WriteLine(" echo \"8098021050908C0C0C0E0C5211003200\" | V2GDecoder.exe -d # Pipe hex to decode");
|
||||
}
|
||||
|
||||
static void HandleDecodeCommand(string[] args)
|
||||
{
|
||||
string input;
|
||||
byte[] exiBytes;
|
||||
|
||||
// Check if input is coming from stdin (pipe)
|
||||
if (args.Length < 2)
|
||||
{
|
||||
if (!Console.IsInputRedirected)
|
||||
{
|
||||
Console.WriteLine("Error: EXI hex string or file required for decode operation");
|
||||
Console.WriteLine("Usage: V2GDecoder.exe --decode <exi_hex_string_or_file>");
|
||||
Console.WriteLine(" or: echo \"hex_string\" | V2GDecoder.exe --decode");
|
||||
return;
|
||||
}
|
||||
|
||||
// Read from stdin
|
||||
Console.WriteLine("Reading EXI data from stdin (pipe input)...");
|
||||
input = Console.In.ReadToEnd().Trim();
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
Console.WriteLine("Error: No input data received from stdin");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
input = args[1];
|
||||
}
|
||||
|
||||
// Check if input is a file
|
||||
if (File.Exists(input))
|
||||
{
|
||||
Console.WriteLine($"Reading EXI data from file: {input}");
|
||||
|
||||
// Handle different file extensions
|
||||
string extension = Path.GetExtension(input).ToLower();
|
||||
|
||||
if (extension == ".dump")
|
||||
{
|
||||
// Hex dump file format with arrows (→)
|
||||
Console.WriteLine("Processing hex dump format file...");
|
||||
byte[] rawData = V2GDecoder.ParseHexFile(input);
|
||||
|
||||
// Find V2G message in the hex dump
|
||||
var v2gMessage = ExtractV2GMessageFromHexDump(rawData);
|
||||
if (v2gMessage != null)
|
||||
{
|
||||
exiBytes = v2gMessage;
|
||||
Console.WriteLine($"Extracted V2G EXI message from hex dump ({exiBytes.Length} bytes).");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Warning: No V2G message header (01 FE) found in hex dump. Attempting to decode raw data.");
|
||||
// Try to decode the raw data directly (might be pure EXI without V2G header)
|
||||
exiBytes = rawData;
|
||||
}
|
||||
}
|
||||
else if (extension == ".hex")
|
||||
{
|
||||
// Plain hex file (pure hex string)
|
||||
Console.WriteLine("Processing hex string file...");
|
||||
string fileContent = File.ReadAllText(input).Trim();
|
||||
fileContent = fileContent.Replace(" ", "").Replace("-", "").Replace("0x", "").Replace("\n", "").Replace("\r", "");
|
||||
exiBytes = Convert.FromHexString(fileContent);
|
||||
Console.WriteLine($"Parsed hex string from file ({exiBytes.Length} bytes).");
|
||||
}
|
||||
else if (extension == ".txt")
|
||||
{
|
||||
// Legacy support for .txt files - check content format
|
||||
string fileContent = File.ReadAllText(input).Trim();
|
||||
if (fileContent.Contains("→"))
|
||||
{
|
||||
// Hex dump format
|
||||
Console.WriteLine("Processing legacy hex dump format file...");
|
||||
byte[] rawData = V2GDecoder.ParseHexFile(input);
|
||||
var v2gMessage = ExtractV2GMessageFromHexDump(rawData);
|
||||
if (v2gMessage != null)
|
||||
{
|
||||
exiBytes = v2gMessage;
|
||||
Console.WriteLine($"Extracted V2G EXI message from hex dump ({exiBytes.Length} bytes).");
|
||||
}
|
||||
else
|
||||
{
|
||||
exiBytes = rawData;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Plain hex
|
||||
fileContent = fileContent.Replace(" ", "").Replace("-", "").Replace("0x", "").Replace("\n", "").Replace("\r", "");
|
||||
exiBytes = Convert.FromHexString(fileContent);
|
||||
Console.WriteLine($"Parsed hex string from file ({exiBytes.Length} bytes).");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown extension, try as plain hex
|
||||
Console.WriteLine($"Unknown file extension '{extension}', attempting to parse as hex string...");
|
||||
string fileContent = File.ReadAllText(input).Trim();
|
||||
fileContent = fileContent.Replace(" ", "").Replace("-", "").Replace("0x", "").Replace("\n", "").Replace("\r", "");
|
||||
exiBytes = Convert.FromHexString(fileContent);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Direct hex string input
|
||||
string exiHexString = input.Replace(" ", "").Replace("-", "").Replace("0x", "");
|
||||
|
||||
if (exiHexString.Length % 2 != 0)
|
||||
{
|
||||
Console.WriteLine("Error: Invalid hex string (odd number of characters)");
|
||||
return;
|
||||
}
|
||||
|
||||
exiBytes = Convert.FromHexString(exiHexString);
|
||||
Console.WriteLine("Processing direct hex string input.");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"Decoding EXI data ({exiBytes.Length} bytes):");
|
||||
Console.WriteLine($"Input: {Convert.ToHexString(exiBytes)}");
|
||||
Console.WriteLine();
|
||||
|
||||
// Decode EXI to XML
|
||||
var decodedXml = V2GDecoder.DecodeEXIToXML(exiBytes);
|
||||
Console.WriteLine(decodedXml);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error decoding EXI: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
static byte[]? ExtractV2GMessageFromHexDump(byte[] data)
|
||||
{
|
||||
// Find V2G Transfer Protocol signature (0x01FE)
|
||||
for (int i = 0; i < data.Length - 8; i++)
|
||||
{
|
||||
if (data[i] == 0x01 && data[i + 1] == 0xFE)
|
||||
{
|
||||
// Get payload length
|
||||
uint payloadLength = (uint)((data[i + 4] << 24) | (data[i + 5] << 16) | (data[i + 6] << 8) | data[i + 7]);
|
||||
|
||||
// Extract EXI payload
|
||||
if (i + 8 + payloadLength <= data.Length)
|
||||
{
|
||||
byte[] exiPayload = new byte[payloadLength];
|
||||
Array.Copy(data, i + 8, exiPayload, 0, (int)payloadLength);
|
||||
return exiPayload;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void HandleEncodeCommand(string[] args)
|
||||
{
|
||||
string xmlInput;
|
||||
string xmlContent;
|
||||
|
||||
// Check if input is coming from stdin (pipe)
|
||||
if (args.Length < 2)
|
||||
{
|
||||
if (!Console.IsInputRedirected)
|
||||
{
|
||||
Console.WriteLine("Error: XML string or file required for encode operation");
|
||||
Console.WriteLine("Usage: V2GDecoder.exe --encode <xml_file_or_string>");
|
||||
Console.WriteLine(" or: type file.xml | V2GDecoder.exe --encode");
|
||||
return;
|
||||
}
|
||||
|
||||
// Read from stdin
|
||||
Console.WriteLine("Reading XML data from stdin (pipe input)...");
|
||||
xmlContent = Console.In.ReadToEnd().Trim();
|
||||
if (string.IsNullOrEmpty(xmlContent))
|
||||
{
|
||||
Console.WriteLine("Error: No input data received from stdin");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xmlInput = args[1];
|
||||
|
||||
// Check if input is a file
|
||||
if (File.Exists(xmlInput))
|
||||
{
|
||||
string extension = Path.GetExtension(xmlInput).ToLower();
|
||||
|
||||
if (extension == ".xml")
|
||||
{
|
||||
Console.WriteLine($"Reading XML from file: {xmlInput}");
|
||||
xmlContent = File.ReadAllText(xmlInput);
|
||||
}
|
||||
else
|
||||
{
|
||||
// For non-XML extensions, still try to read as text file
|
||||
Console.WriteLine($"Reading content from file: {xmlInput} (extension: {extension})");
|
||||
xmlContent = File.ReadAllText(xmlInput);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Processing XML string:");
|
||||
xmlContent = xmlInput;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Input XML:");
|
||||
Console.WriteLine(xmlContent);
|
||||
Console.WriteLine();
|
||||
|
||||
// Encode XML to EXI
|
||||
var exiBytes = V2GDecoder.EncodeXMLToEXI(xmlContent);
|
||||
var exiHexString = Convert.ToHexString(exiBytes);
|
||||
|
||||
Console.WriteLine($"Encoded EXI data ({exiBytes.Length} bytes):");
|
||||
Console.WriteLine(exiHexString);
|
||||
|
||||
// Also show formatted hex
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Formatted hex:");
|
||||
Console.WriteLine(V2GDecoder.BytesToHex(exiBytes));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error encoding XML: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
static void AnalyzeFile(string dataFilePath)
|
||||
{
|
||||
if (!File.Exists(dataFilePath))
|
||||
{
|
||||
Console.WriteLine($"Error: Data file not found: {dataFilePath}");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Analyzing file: {dataFilePath}");
|
||||
|
||||
// 헥스 파일에서 바이너리 데이터 파싱
|
||||
byte[] rawData = V2GDecoder.ParseHexFile(dataFilePath);
|
||||
@@ -49,15 +361,6 @@ namespace V2GProtocol
|
||||
|
||||
// 네트워크 패킷 분석 (이더넷/IPv6/TCP 헤더 포함인 경우)
|
||||
AnalyzeNetworkPacket(rawData);
|
||||
|
||||
Console.WriteLine("\nPress any key to exit...");
|
||||
Console.ReadKey();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Error: {ex.Message}");
|
||||
Console.WriteLine(ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
static void AnalyzeV2GMessages(byte[] data)
|
||||
|
||||
965
V2GDecoder.cs
965
V2GDecoder.cs
File diff suppressed because it is too large
Load Diff
@@ -8,4 +8,31 @@
|
||||
<AssemblyName>V2GDecoder</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Data\2025-05-01_15-23-10_L460_AVM_AA8_3_DC_Charging_LGIT_32KW_T2_20to100_SOC.pcapng">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\dump0.dump">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\dump2.dump">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\dump1.dump">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\encode0.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\encode1.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\encode2.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Data\Xml.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user