Hello everyone and thanks in advance for the help,
I am using the WriteFile function (fileapi.h) to send frames to the NDIS driver at Ethernet Layer 2 level, directly between MAC addresses.
The frames are sent correctly, but in any of the tests I did, the frames are sent duplicated. I detected this by capturing the output with WireShark, where the following is represented:
Within the frame I send, I increment a counter on each send. This counter is repeated in two consecutive frames, which have different frame numbers assigned by WireShark.
This is not something that happens randomly due to the loss of messages in the network, and the forwarding of messages by another device in the network. It happens on every frame that is sent, they are exactly the same, including the counter which is incremented every two frames.
Questions:
Is there a parameter in the NDIS driver that sets this duplicate output.
Am I misinterpreting the WireShark capture.
I saw this post, and did as recommended by uninstalling and installing Ncap and WinCap, but it made no difference.
Thank you very much. Best regards.
bSuccess = (BOOLEAN)WriteFile(
Handle,
pWriteBuf,
PacketLength,
&BytesWritten,
NULL);
DWORD err = GetLastError();
printf("ERROR: %i", err);
if (!bSuccess)
{
PRINTF(("DoWriteProc: WriteFile failed on Handle %p\n", Handle));
break;
}
Solved, I answer to my question.
The compilation of the NDIS driver that I am using, comes prepared with the NDIS_SEND_FLAGS_CHECK_FOR_LOOPBACK flag in the send.c file.
For this reason, and following the explanations of this page, it is possible to cancel the duplicated messages in the computer of origin, since in the computer of destiny, finally these did not arrive to be an internal loop.
Best regards.
Related
I am using a CANCase VN1640A between 2 ECUs in order to falsify a CAN message. Below the bridge simulation setup:
In my CAPL Code, the received messages from channel 1 will be redirected to channel 3 and vice-versa. (So far I am not falsifying any message)
variables{
message can1. msgCAN1;
message can3. msgCAN3;
}
on message can1.{
msgCAN3=this;
if(this.dir == rx)
output(msgCAN3);
}
on message can3.{
msgCAN1 = this;
if(this.dir == rx)
output(msgCAN1);
}
But when I start CANoe I get this Error message:
This error means that CANoe tries to send more as it could. The transmit buffer is overflowed. I have changed the hardware configuration of Transmit Queue size to the max 32768 messages, also the Receive Latency to very fast but unfortunately the error occur again.
Does anyone have any hints that could help to solve this problem and thanks in advance.
The error message can mean, that CANoe tries to send more as it could. The transmit buffer is overflowed. This can have several causes:
the bus is full of high prior messages and therefore CAN hardware cannot send
You have a program which writes messages very quick to the buffer, so that the card can´t send (while loops for).
Error frames occur when sending and thus the card cannot send.
Vector tool provides a loop test:
Send messages from CH1 to CH3. If this is working fine, it looks like the problem is caused by your CANoe configuration.
The necessary test programs are part of the Vector Driver Setup Files and located in the folder Common. You can download the Driver Setup File from www.vector.com/driver-setup.
CAN Highspeed Looptest: http://kb.vector.com/entry/589/
CAN Low-speed Looptest: http://kb.vector.com/entry/590/
If the loop test works fine, you can see the time, the busload etc. If not, you will get a failed message.
Note:
Reduce the number of channels used in CANoe/CANalyzer under:
Configuration | Options | Measurement | General | Channel usage.
Are there more selected channels in the CANoe configuration than assigned CANcabs in the Vector Hardware Config?
(Start | Control Panel | Hardware and Sound | Vector Hardware)
Please check the channel and application assignment in the Vector Hardware Config.
Kindly check the hardware mapping in CANoe. This error mostly arises when the mapping is not correct or disturbed.
Go to Hardware-> Network Hardware configuration -> Driver -> Select proper channel for the vector hardware
I hope this helps !
So this error does NOT mean that CANoe tries to send more as it could.
It means instead:
We have (many) error frames on the CAN bus. CANoe tries to send messages which does not work (for whatever reason) -> error frames are the result. The CAN controller will retry to send the frame which might again lead to an error frame. Now over time the Send Requests accumulate and lead to further error frames. At some point the buffer for the error frames does overflow which leads to the message you see in the write window.
Solution:
We have to check the Trace Window and check what kind of error frames we get there (and then take suitable measures to prevent them).
I'm trying to send packets over CoAP between two TI 2650 sensortags. I used the logic from the "er-rest-example" provided by contiki 3.0, that is:
coap_init_message(request, COAP_TYPE_CON, COAP_POST, 0);
coap_set_header_uri_path(request, url);
coap_set_payload(request, (uint8_t*)msg, sizeof(msg) - 1);
COAP_BLOCKING_REQUEST(&server_ip, REMOTE_PORT, request, client_chunk_handler);
When I started the program, it works as expected until the first time COAP_BLOCKING_REQUEST is called, at which point the program seems to freeze (doesn't react to button presses anymore).
So I assume COAP_BLOCKING_REQUEST blocks until it receives a response, which is not suitable for my project. Can anyone confirm that?
UPDATE:
Going forward from that assumption, my question now is, what steps to I have to take to send out a packet?
Do I use the coap_send_message function from er-coap.c or the coap_send_transaction function from er-coap-transaction.c?
I want to figure out what functions I have to call in which order to configure the packet correctly and then send it out with the correct function (which I guess would be one of the above).
Maybe there is some documentation out there that I haven't found yet and someone could point me to it?
Cheers
Does anyone know if there is an API to get the current monitor state (on or off) in Windows (XP/Vista/2000/2003)?
All of my searches seem to indicate there is no real way of doing this.
This thread tries to use GetDevicePowerState which according to Microsoft's docs does not work for display devices.
In Vista I can listen to GUID_MONITOR_POWER_ON but I do not seem to get events when the monitor is turned off manually.
In XP I can hook into WM_SYSCOMMAND SC_MONITORPOWER, looking for status 2. This only works for situations where the system triggers the power off.
The WMI Win32_DesktopMonitor class does not seem to help out as well.
Edit: Here is a discussion on comp.os.ms-windows.programmer.win32 indicating there is no reliable way of doing this.
Anyone else have any other ideas?
GetDevicePowerState sometimes works for monitors. If it's present, you can open the \\.\LCD device. Close it immediately after you've finished with it.
Essentially, you're out of luck—there is no reliable way to detect the monitor power state, short of writing a device driver and filtering all of the power IRPs up and down the display driver chain. And that's not very reliable either.
You could hook up a webcam, point it at your screen and do some analysis on the images you receive ;)
Before doing anything based on the monitor state, just remember that users can use a machine with remote desktop of other systems that don't require a monitor connected to the machine - so don't turn off any visualization based on the monitor state.
You can't.
Look like all monitor power capabilities connected to the "power safe mode"
After searching i found here code that connecting between SC_MONITORPOWER message and system values (post number 2)
I use the code to testing if the system values is changing when i am manually switch off the monitor.
int main()
{
for(;monitorOff()!=1;)
Sleep(500);
return 0;
}//main
And the code is never stopped, no matter how long i am switch off my monitor.
There the code of monitorOff function:
int monitorOff()
{
const GUID MonitorClassGuid =
{0x4d36e96e, 0xe325, 0x11ce,
{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
list<DevData> monitors;
ListDeviceClassData(&MonitorClassGuid, monitors);
list<DevData>::iterator it = monitors.begin(),
it_end = monitors.end();
for (; it != it_end; ++it)
{
const char *off_msg = "";
//it->PowerData.PD_PowerStateMapping
if (it->PowerData.PD_MostRecentPowerState != PowerDeviceD0)
{
return 1;
}
}//for
return 0;
}//monitorOff
Conclusion : when you manually switch of the the monitor, you cant catch it by windows (if there is no unusual driver interface for this), because all windows capabilities is connected to "power safe mode".
In Windows XP or later you can use the IMSVidDevice Interface.
See
http://msdn.microsoft.com/en-us/library/dd376775(VS.85).aspx
(not sure if this works in Sever 2003)
With Delphi code, you can detect invalid monitor geomerty while standby in progress:
i := 0
('Monitor'+IntToStr(i)+': '+IntToStr(Screen.Monitors[i].BoundsRect.Left)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Top)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Right)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Bottom))
Results:
Monitor geometry before standby:
Monitor0: 0, 0, 1600, 900
Monitor geometry while standby in Deplhi7:
Monitor0: 1637792, 4210405, 31266576, 1637696
Monitor geometry while standby in DeplhiXE:
Monitor0: 4211194, 40, 1637668, 1637693
This is a really old post but if it can help someone, I have found a solution to detect a screen being available or not : the Connecting and Configuring Displays (CCD) API of Windows.
It's part of User32.ddl and the interesting functions are GetDisplayConfigBufferSizes and QueryDisplayConfig. It give us all informations that can be viewed in the Configuration Panel of windows.
In particular the PathInfo contains a TargetInfo property that have a targetAvailable flag. This flag seems to be correctly updated on all the configurations I have tried so far.
This allow you to know the state of every screens connected to the PC and set their configurations.
Here a CCD wrapper for .Net
If your monitor has some sort of built-in USB hub, you could try and use that to detect if the monitor is off/on.
This will of course only work if the USB hub doesn't stay connected when the monitor is consider "off".
I have a problem because I don't know how _pulse receiving works. If I have my data struct
typedef struct _my_data {
msg_header_t hdr;
int data;
} my_data_t;
and I am receiving only my msg I cant tell if it is a pulse
my_data_t msg;
...
rcvid = MsgReceive(g_Attach->chid, &msg, sizeof(msg), NULL);
when rcvid = 0 BUT how a program knows that it need to send _pulse in a form of msg (struct that I defined) or else how does it work. In addition is _IO_CONNECT a pulse? If yes why doesn't it have rcvid==0? - according to http://www.qnx.com/developers/docs/6.3.2/neutrino/lib_ref/n/name_attach.html
1 - _IO_CONNECT is not used for pulse. Its used for connect system call to resource managers. Example system calls are open(), close(), etc.
2 - You need to know whether the server or client is waiting on pulse message or not. For pulse message the blocking function in the resource manager will be MsgReceivePulse() and the client will use MsgSendPulse().
MsgSend() is used for normal message and MsgSendPulse() is for sending pulse message.
Similarly MsgReceive() is used for receiving normal message and MsgReceivePulse() is used for receiving pulse messages. Please refer to the QNX documents for more detailed description.
Both variants have different parameters like the functions for pulse messages do not have any parameter for return data because pulses are non blocking small messages which do not block for any reply but functions for normal messages have parameters for receive data.
You need to create channel and connection, for example
chid=ChannelCreate(0);
int pid=getpid();
coid=ConnectAttach(0, pid, chid, 0, 0);
and attach channel to connection.............
Then if you have two threads...............from one thread you can to call MsgSend function, for example MsgSend(coid, &(message), sizeof(message), &rmsg, sizeof(rmsg)); and in the other thread rcvid=MsgReceive(chid, (void*)&message, sizeof(message),NULL);
I want to know how can I get a keyboard input in contiki os.
I already tried getchar(),getch(),scanf(),gets() and none worked, so I want to know if somebody can help me.
getchar,getch,scanf,gets are sort of POSIX things that read from files (e.g. stdin) --- these don't exist in Contiki (all though you could probably use them with the native platform).
So the first question to ask is what platform are you using and what do you mean by "keyboard". If keyboard means typing characters that are sent via a serial port from a computer then you have to know where they are received on the thing running Contiki. A typical arrangement is to receive characters on a uart, say, uart1.
In this case, contiki uses a callback such as uart1_input_handler that will be defined by the application. Platform main loops will check if there are characters to send to the input_handler and then check that an input_handler is defined. If so, will call something like uart1_input_handler(c).
You can see this code for the various platforms by grepping for uart1_input_handler:
platform/redbee-econotag/contiki-mc1322x-main.c: uart1_input_handler(uart1_getc());
cpu/msp430/dev/uart1x.c: if(uart1_input_handler(c)) {
cpu/stm32w108/dev/uart1.c: uart1_input_handler(c);
etc...
Some examples that register an input handler and process the characters:
example/shell:
/* set up the shell */
uart1_set_input(serial_line_input_byte);
serial_line_init();
serial_shell_init();
slip, in examples/ipv6/rpl-border-router/slip-bridge.c
slip_set_input_callback(slip_input_callback);
My guess for what you want to do would be to start with the shell examples and try to get those working.
The example cited below is from the Wiki pages of contiki on github. It demonstrates how the contiki specific mechanism for serial input works. Like mariano mentioned above that a callback has to be defined for the serial drivers specific to the platform you are using. I have used for ex. "rs232_set_input(RS232_PORT_0, serial_line_input_byte) ; " for my atmega128 MCU. The serial i/o drivers use this callback mechanism to post input characters to the "serial_line_process" defined in serial-line.c file. This process then broadcasts the serial_line_event_message to all processes along with the data read on the serial line. A process like the eg. stated below, can catch this event and process the input as per the requirements.
The callback mentioned above is defined in $(CONTIKI)/core/dev/serial-line.c. Check that out.
Once you initialise it using serial_line_init(), you are good to go.
#include "contiki.h"
#include "dev/serial-line.h"
#include <stdio.h>
PROCESS(test_serial, "Serial line test process");
AUTOSTART_PROCESSES(&test_serial);
PROCESS_THREAD(test_serial, ev, data)
{
PROCESS_BEGIN();
for(;;) {
PROCESS_YIELD();
if(ev == serial_line_event_message) {
printf("received line: %s\n", (char *)data);
}
}
PROCESS_END();
}
I assume you use COOJA (or maybe you connected a keyboard to your device so my answer will not be correct).
COOJA is an emulator, not a simulator.
If you want a responsive design, use the sensor button (on sky platform for example)
SENSORS_ACTIVATE(button_sensor);
/* Wait until we get a sensor event with the button sensor as data. */
PROCESS_WAIT_EVENT_UNTIL(ev == sensors_event &&
data == &button_sensor);
Hope it helped.