#include "stdafx.h"
#include "stdlib.h"
using namespace System;
using namespace System::IO;
using namespace canlibCLSNET;
static int quiet = 0;
static bool logToFile = false;
static bool allowVirtual = false;
static long int msgCount = 0;
static long int overRuns = 0;
static __int64 timeOffset = 0;
static void DisplayHelp(void)
{
Console::Write("\nCANLIB Dump Program\n");
Console::Write("(Part of the CANLIB SDK from KVASER AB - http://www.kvaser.se)\n");
Console::Write("\n");
Console::Write("This is a sample program that just dumps all incoming messages to the screen\n");
Console::Write("or a file.\n");
Console::Write("\nUsage: candump [flags] [filename]\n");
Console::Write(" -X Listen to CAN channel number X.\n");
Console::Write(" -B<value> Set the bitrate. Value is any of 1000,500,250,125.\n");
Console::Write(" Default bitrate is 125 kbit/s.\n");
Console::Write(" -h Print this help text.\n");
Console::Write(" -q Be more quiet than usual.\n");
Console::Write(" -v Allow use of virtual channel.\n");
Console::Write("\nIf no filename is specified, standard output is used.\n\n");
Console::Write("The following keys can be used during logging:\n");
Console::Write(" ESC Stop logging.\n");
Console::Write(" Q Be more quiet.\n");
Console::Write(" q Be less quiet.\n");
Console::Write("\nExample:\n");
Console::Write("candump -B250 -0 logfile.log\n");
Console::Write(" would set CAN channel 0 to 250 kbit/s and log to logfile.log\n");
Environment::Exit(0);
}
{
IO::TextWriter^ errOutput = Console::Error;
String^ errString;
errOutput->WriteLine("{0}: failed, status = {1} ({2})", funcName, status, errString);
}
int PrepareChannel(int channel, int bitrate)
{
if (hnd < 0) {
ReportError("canOpenChannel", retStatus);
Environment::Exit(1);
}
ReportError("canSetBusParams", retStatus);
Environment::Exit(1);
}
ReportError("canBusOn", retStatus);
Environment::Exit(1);
}
return hnd;
}
void DisplayLeadIn(int handle)
{
if (quiet == 0) {
using namespace System::Globalization;
DateTime dt = DateTime::Now;
Console::WriteLine("; Logging started at {0}", dt.ToString("U", DateTimeFormatInfo::InvariantInfo));
Console::WriteLine("; (x = Extended Id, R = Remote Frame, o = Overrun, N = NERR)");
Console::WriteLine("; Ident xRoN DLC Data 0.....................7 Time");
}
}
void DisplaySummary(int handle)
{
if (quiet == 0) {
using namespace System::Globalization;
DateTime dt = DateTime::Now;
Console::WriteLine("; Logging ended at {0}", dt.ToString("U", DateTimeFormatInfo::InvariantInfo));
Console::WriteLine("; {0} messages received.", msgCount);
Console::WriteLine("; {0} overrun conditions detected.", overRuns);
}
}
void EmptyReceiveBuffer(int handle)
{
int id, dlc, flags;
array <unsigned char, 1> ^msg = gcnew array<unsigned char>(8);
__int64 time;
__int64 adjTime, timeFrac, timeInt;
int i;
if (quiet <= 1) {
Console::Write("{0:X8} {1}{2}{3}{4} {5:G2} ",
id,
dlc);
if (dlc > 8) dlc = 8;
if ((flags & Canlib::canMSG_RTR) == 0) {
for (i = 0; i < dlc; i++) Console::Write("{0:X2} ", msg[i]);
for (; i < 8; i++) Console::Write(" ");
}
else {
Console::Write(" ");
}
msgCount++;
}
else {
Console::Write(" Error Frames ");
}
adjTime = time - timeOffset;
if (adjTime < 0) {
timeFrac = (-adjTime) % 1000;
timeInt = (-adjTime) / 1000;
Console::WriteLine(" -{0,5}.{1:D3}", timeInt, timeFrac);
}
else {
timeFrac = adjTime % 1000;
timeInt = adjTime / 1000;
Console::WriteLine(" {0,6}.{1:D3}", timeInt, timeFrac);
}
}
}
ReportError("canRead", status);
}
}
void RecordMessages(int handle)
{
bool finished = false;
IO::TextWriter^ errOutput = Console::Error;
while (!finished) {
while (!Console::KeyAvailable) {
EmptyReceiveBuffer(handle);
Threading::Thread::Sleep(50);
}
ConsoleKeyInfo cki;
cki = Console::ReadKey(true);
switch (cki.Key) {
case ConsoleKey::Escape:
finished = true;
break;
case ConsoleKey::Q:
if ((int)(cki.Modifiers & ConsoleModifiers::Shift)) {
if (quiet < 5) quiet++;
}
else {
if (quiet > 0) quiet--;
}
errOutput->WriteLine("New quiet level = {0}", quiet);
break;
}
}
}
int main(array<System::String ^> ^args)
{
int channel = 0;
String^ logFileName = "";
IO::StreamWriter^ filePtr = nullptr;
IO::TextWriter^ stdOutput = Console::Out;
IO::TextWriter^ errOutput = Console::Error;
for (int i = 0; i < args->Length; i++) {
if (args[i][0] != '-') {
logFileName = String::Copy(args[i]);
try
{
filePtr = File::CreateText(logFileName);
}
catch (IO::IOException^ e)
{
errOutput->WriteLine(e->Message);
DisplayHelp();
}
logToFile = true;
}
else if (args[i][1] == 'h') {
DisplayHelp();
}
else if (args[i][1] == 'q') {
quiet++;
}
else if (args[i][1] == 'v') {
allowVirtual = true;
}
else if (args[i][1] == 'B') {
int tmp = Convert::ToInt32(args[i]->Substring(2));
switch (tmp) {
default : DisplayHelp(); break;
}
}
else {
channel = Convert::ToInt32(args[i]->Substring(1));
}
}
int handle = PrepareChannel(channel, bitrate);
if (logToFile) Console::SetOut(filePtr);
DisplayLeadIn(handle);
RecordMessages(handle);
DisplaySummary(handle);
if (logToFile) filePtr->Close();
}
return 0;
}