Receiving messages using a CAN adapter - c++

I'm using a CAN adapter API for Visual C++ Express. You can find out more about the API at their website. Click on the USB-CANmodul2 Hardware Manual for the correct PDF file I am using. This is useful for any program that uses CAN that needs a good API for it.
My code
Attached are some pictures to help describe what it is I am doing. I'm running a CAN bootloader on one compiler and my parsing program is on Visual Express. The parsing program should read from a text file and send parsed information to the CAN bootloader so it can program it to its memory. I am able to send messages fine. The problem is, when the CAN bootloader receives a message, it is supposed to reply to the other program that everything sent was correct, but I can't figure out how to receive messages in the parsing program with the API. I have done basically everything the their PDF file told me.
What am I doing wrong?
Pictures of the programs in debug mode:
The information from the parsing program sent, the bootloader is putting it into a buffer.
The bootloader is about to call functions to send a message back saying no error. The parsing program never gets past the polling loop, so it never receives the message. I know the bootloader sending functions worked, because I have tested them with the same CAN program the API comes in. Hopefully that is enough information for you guys to kind of understand what I am doing.
These are the lines I'm having trouble with:
do
274. retMessageF = UcanReadCanMsgEx(UcanHandle, &bChannel, &rxMessage, NULL);
275. while(retMessageF != USBCAN_SUCCESSFUL);

Related

Debugging a Win32 application c++

My application started life as a c++ Console application in VS2019. Code was provided as part of an SDK. Worked perfect. Great response from the manufacturer USB device. Later, I wanted to graduate is to a GUI application, much as I've been doing in VB and c#. Lo and behold, I managed to reconstruct the application in both Qt and Win32 but I'm running into a situation where the application becomes unresponsive and I have no way to tell what's going on.
In the Console application, I have to execute this code to interface with the device AFTER sending a "TakeMeasurement" command :
if (SDK_SUCCESSFUL(sdkError)) {
printf("\nWaiting for measurement to complete...\n");
while (!isMeasureWait) {
if (isDisConnect) break;
this_thread::sleep_for(chrono::milliseconds(1000));
}
}
This code works like a charm! Ater one or two iteration, the device has completed the measurement and I can get to the data easily.
On the Win32 side, I use the exact same code. Only, once control enters the loop, it never returns.
Any idea how I could diagnose the error? I have the impression that the "timing" is critical, between the exact moment where the Measurement command is initiated to the exact moment the instrument signals that it's done, and the data ready to be picked up.
My naive hypothesis is that, in debug mode on both 'platforms', I must be getting some timing differences? Sadly, I can't get more information from the manufacturer in this regard but I suspect I have a small window of time within which the instrument's response can be acted on? And I begin to suspect that, on Win32, that "time" is too long? Compared to on the Console side?
I was thinking of, perhaps, "measuring" that time, in milliseconds? First, on the Console side, to see what kind of delay "works", and then, to see how the delay compares with the Win32 side.
I may be wasting my time and I sure don't mean to waste yours.
How would I go about getting an idea of time elapsed in a c++ application? I'll take a look around VS2019, they have all kinds of "performance" things that popup at run time?
Any help is appreciated.
I am not sure I completely understand what is going on.
Execution of the thread wait loop was not not the culprit.
I'm not 100% sure but what happens is that, in my 'Export data to CSV TEXT file', if I tried to execute the call to :
SetWindowText(hEditMeasure, wMeasurements);
The application always hung. I placed breakpoints right before the call in the code, to trace execution, and it did not strike me at first but, in VS toolbar, there was a "thread" comboBox? With the value showing = DEVICE.DLL? and to its right, the name of my Export function as the Stackframe. In searching for additional information on the setWindowText function, I came accross the reference to use VM_SETTEXT to send to "different application"? Could it be unknowingly I was sending a message to "another thread", the DLL thread? And that's why it hung? I did not know enough to tell. So I started to move the setWindowText line around, ultimately inside the code that is called by the "Measure" button, and it worked!
I'm not out of the woods yet but I feel I'm making progress. Thank you all for your help and patience.

Grabbing printed statements from console C++

I have two loggers in my program. One that I made inside a gui, and one that is super complicated but very well designed and prints to the console. I am trying to get the output from the nice console logger to the rendered one. I have tried everything under the sun to get this to work but I can't seem to figure it out (due to my lack of understanding of the code from the other logger(spdlog).) My conclusion is that taking the logs directly from what is printed is the best way to do this but I can't find online anyone asking how to do this. I have seen a few questions but they just post code as an answer and don't really explain what is going on. My question: Is there a way to grab printed statements from the console and what are the performance issues/complications that come with doing something like this.
For example, if i do std::cout << "hello!" << std::endl; or some printf statement, I want to be able to further down in the code be able to grab "hello!"
My conclusion is that taking the logs directly from what is printed is the best way to do this but I can't find online anyone asking how to do this.
Consoles nowadays are terminal emulators. The original terminals' output went to printers and couldn't be (easily) read back.
Application's stdout and stderr (console) streams are write-only. Moreover, in Windows and Unix/Linux you can pipe your program's (console) output (either or both stderr and stdout) into another application with | (pipe) that creates a pipe IPC between stdout of your application and stdin of another one. That IPC pipe is write-only, your application cannot possibly read back from it.
You may be able to get access to the contents of the frame buffer of Windows cmd.exe that controls its Windows console window, but that won't be the verbatim byte-exact copy of data you wrote into stdout because of the escape sequences interpreted by Windows console.
If stdout is redirected into a file you can re-open that file for reading, but there is no portable way to re-open that file.
In other words, there is no portable way to read console output back.
I have tried everything under the sun to get this to work but I can't seem to figure it out (due to my lack of understanding of the code from the other logger(spdlog).
I bet you haven't tried reading spdlog documentation, in particular logger with multi sinks. A sink is an output abstraction, which implementation can write into a file, memory or both. What you need is attach your own sink to spdlog that prints into your UI.
Derive your sink from base_sink and implement abstract member functions:
virtual void sink_it_(const details::log_msg &msg) = 0; to print into the UI, and,
virtual void flush_() = 0; to do nothing.
Then attach one object of your sink class to that spdlog.

Possible to Interface with/use 3rd party Windows driver?

This touches on some already-answered questions, so feel free to duplicate away, but chances are I've already read them and am not satisfied.
There are 2 drivers on my system (located in C:\Windows\System32\drivers) called pefndis.sys and wfpcapture.sys. I am 100% sure pefndis.sys is a kernel driver and 99.9% sure wfpcature.sys is as well. These are 3rd party drivers installed by Mircosoft's Message Analyzer. I have discovered pefndis.sys is used to capture data on the wire and wfpcapture.sys is used to capture data above the network layer (ie, this will capture loopback traffic). I have no documentation, header files, etc, for these drivers as there was no intention of Microsoft for these drivers to be used for custom solutions as I would like to do. It just so happens I've identified wfpcapture.sys as performing the exact tasks I want, and I'd love to tap into what it can do; this seems so much more reasonable than spending the time and pain of implementing my own driver. However, my efforts have failed.
This is what I've done: I have some simple c++ code here:
void Provider::InitDriver()
{
HANDLE wfpHandle = NULL;
DWORD lastError = 0;
LPCTSTR wfpName = L"\\\\.\\wfpcapture";
LPCTSTR pefName = L"\\\\.\\pefndis";
wfpHandle = CreateFile(
wfpName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
lastError = GetLastError();
CloseHandle(wfpHandle);
}
When I run CreateFile with wfpName, I get an invalid handle and lastError==2 meaning the file cannot be found. When I run CreateFile with pefName, I get a valid handle and lastError==0. Upon further investigation, most of my randomly-picked .sys files from the drivers folder produce invalid handles with error codes of 2. Occasionally I'd get an error code of 5 (Access Denied, which also seems odd since I'm running everything as administrator). Does anyone have an explanation why I cannot get a handle to wfpcapture.sys? I brought up the pefndis.sys driver because it was installed by the same program as wfpcapture.sys, and I can clearly get a handle to that, so all my strings are formatted correctly, and both files are in the same directory. I came across this post yesterday which told me IoCreateSymbolicLink can be used in the driver code to give the driver another alias. If I'm using the wrong alias, does that explain why so many .sys files return FILE_NOT_FOUND errors when I try to get handles to them?
I've tried to do some more research on the file using IL DASM (no luck, this is native code), DUMPBIN, WinObj, and DependencyWalker.
DUMPBIN /EXPORTS [...]wfpcapture.sys returns no exports. I find this extremely odd. These answers suggest .DLLs without exports are simply resources or the code is obfuscated. I am almost certain wfpcapture.sys does not just contain resources. Is obfuscation the most reasonable explanation.. any other ideas why it doesn't have any exports?
I could not find wfpcapture in WinObj anywhere. I located pefndis in Device\. Where is wfpcapture? It doesn't actually talk to a device, so that makes sense, but it is still a driver, correct? Do drivers need to register with Windows in some way before CreateFile can find them?
DependencyWalker verified what DUMPBIN told me, I think .. no exports. I have no idea how Message Analyzer (or anything else down its dependency stack) is actually talking to it.
Just a bit more background for a complete picture... wfpcapture.sys is an ETW Provider that taps into Microsoft's WFP architecture (used for firewall and IDS applications) to sniff packets above the network layer. I want code that "activates" wfpcapture.sys and then sits back and collects the events (packet captures) that wfpcapture publishes. It's this activation part that I can't figure out. If I setup Message Analyzer to start capturing localhost traffic, then turn on the part of my code that captures the events (using StartTrace(...) and EnableTraceEx2(...)), that works just fine. I am just dying to know how Message Analyzer is talking to wfpcapture.sys and what it's saying in order to get it to cooperate and start publishing events. Another fun fact: When I start a trace in Message Analyzer and do sc query wfpcapture, it tells me the service (here it is identified as a kernel driver) is running. When I stop the trace, the query tells me the service is stopped. If I manually sc start wfpcapture and verify the service is running,, and then run my event capturing code, I get nothing. This tells me Message Analyzer must be sending something to wfpcapture.sys to get it activated and publishing. My plan that spawned this whole thing was to get a handle to driver and start sending it control codes via DeviceIoControl to glean some knowledge on how it worked. I have also seen some very strong evidence that Message Analyzer is passing filter masks to the driver.
Am I completely wasting my time here? That driver is not meant for my consumption, and poking and prodding it to learn about it may be a long shot, but I'm certain it does exactly what I need and I've never written a driver in my life; trying to do that seems foolish when this is sitting right here. Message Analyzer is free, I'm not trying to steal software. Could there possibly be some DRM associated with the driver that's boxing me out? I'd love to hear the thoughts of anyone out there who has Windows driver experience.
Ok, lot of questions there, hope this doesn't get flagged as too broad.

C++ IBM i Access API Running remote commands and getting output

IBM i Access API for C++ lets you run server commands for example (DSPSYSSTS Displaying system status):
cwbSV_ErrHandle msgHandle; //Error Handle
cwbSV_CreateErrHandle(&msgHandle); //Create Error Handle
int code = cwbRC_RunCmd(SystemData::hxSystem, "DSPSYSSTS", msgHandle); //Run command
//Command ran successfully
if(code == CBW_OK){
int code = cwbSV_GetErrText(msgHandle, returnTxt, 1024, NULL);
//code value is CWBSV_NO_ERROR_MESSAGES
}
I can retrieve error messages thrown by the server after command run. But how can I retrieve the command output? If I run a "DSP" (Display) command, I'm obviously wanting to get the output display.
DSP type commands by definition send their output to the 5250 data stream which is then interpreted by a 5250 emulator in order to properly paint a display. It's not at all like stdout, which means that intercepting output meant for a display will require a fair amount of work.
The traditional answer is to use an API which returns the information in a form intended to be read by a program. In the case of system status, that's probably the Retrieve System Status (QWCRSSTS) API. One way to make this easy on yourself is to write a stored procedure and call that instead of directly invoking the API from the client.
Another alternative is to DSPSYSSTS OUTPUT(*PRINT), then read the spooled file. It'll be easier to parse than the raw 5250 output but it can and does change between releases so the API is a more consistent interface.
If you really want to screen scrape the output from DSPSYSSTS, you'll need to learn about the 5250 protocol, which is complex enough that I don't think it can be explained in a forum like this. On the other hand, Albert York has written a program called TNAPI which might fit your needs.
Use Scott Klement explaning to translate Retrieve System Status (QWCRSSTS) API into C++ code. This way you dont need rpg at all.

System stop responding and throws yami i/o error

I need suggestion about YAMI library . I have a system which receives Json string from external interface and parse that received string and send that message to internal ip address for the required action.
The exchange of messages within the internal ip address has been taken care by Yami library. everything works fine but occasionally it displays yam i/o error and system doesn't response unless it is restarted.
The whole software is written in C++ and C and development os is fedora 11.
I have tried to investigate the problem but I am bit clueless as I have not found much help on internet and my testing method doesn't work.
its strange that system works for few hours and then crash . For example If I leave system idle for half an hour and then try to send message via external interface it crashes producing yami i/o error or even while sending continuos command it crashes.
Any help or suggestion will be of great help.
Thanks and regards,
Sam
It looks like this exception is from a core::io_error result which is translated to a runtime exception by details::translate_result_to_exception(). Most of this error originates from the source code in yami/posix in your case.
What you have to do now is figure out where the error originates and ultimately the source of the issue. You should be able to get a rough idea from what happens in your code when the error occurs (are you creating a new connection, sending data, receiving data, etc...).
If that doesn't yield any obvious results I would probably create a test project using the yami source code instead of the library file so I would be able to trace into the yami code to where the error originates from.