Method of listening to UDS message on CAN 1 and outputting control code on CAN2 in CAPL - capl

I'm a complete amateur in programming but have some experience with operating Vector tools and long time familiarity with automotive CAN networks and UDS. I can send a control message to operate the relay on a RAD I/O interface on bus 2 manually (ON KEY) so I know the command works (clickety click) but I need it to do so on receipt of a diagnostic CAN frame (on diagrequest). The problem is, the diagRequest is on CAN bus 1 and I need to send the command on CAN bus 2. Any CAPL keyboard warriors able to suggest a solution please?
includes
{
}
variables
{
message 0x600 radio={dlc=8};
}
ON key 'p'
{radio.byte(0)=0x04;
output (radio);
}
ON key 'o'
{radio.byte(0)=0x00;
output (radio);
}
on diagRequest RequestTransferExit
{radio.byte(0)=0x04;
output (radio);
}

You should configure your Simulation node to gateway (in its Configuration... Buses Tab) add the other CAN also, so it can access simultaneously.
In order to output the ID on a different channel, you have to define the radio message with the Channel selector also, like this:
variables
{
message CAN1.0x600 radio={dlc=8};
}

Related

X11/Xlib: Grab key events and then pass them to sub-windows

I'm tinkering with X11 using Go and Xlib (using cgo) and I'm trying to program basic window management functionalities, but I'm having problems with input management (keyboard in this case).
So far I've created a basic reparenting window manager where client windows (i.e. windows managed by this program) are wrapped within container windows created by this program. Container windows are direct children of root window and client windows are direct children of their container windows.
I'm trying to grab the entire keyboard and check if a key event is directed towards the window manager in order to process certain things. In case this key event is not something related to the window manager I would like to pass it along to client windows. I know that there is the option to select only specific keys or modifiers (using XGrabKey) for this matter (I was able to do it), but I would like to be able to grab the entire keyboard in this case.
So far I have the following code which doesn't work and keys are not passed to client windows.
...
C.XGrabKeyboard(
display,
rootWindow,
0,
C.GrabModeAsync,
C.GrabModeAsync,
C.CurrentTime,
)
...
for {
var event C.XEvent
C.XNextEvent(display, &event)
eventType := (*C.int)(unsafe.Pointer(&event[0]))
switch *eventType {
...
case C.KeyPress:
eventPayload := (*C.XKeyEvent)(unsafe.Pointer(&event[0]))
// Value of eventPayload.root here equals rootWindow.
// Value of eventPayload.window here equals rootWindow.
// Value of eventPayload.subwindow here equals a ContainerWindow.
if SOME_CONDITIONS_ARE_MET {
// Key event is directed towards the window manager. Process this key event.
...
continue
}
// Window manager has nothing to do with this key event. Pass it along.
C.XAllowEvents(display, C.ReplayKeyboard, C.CurrentTime)
...
}
}
It is worth mentioning that in this case I've used C.XSynchronize(display, 1) so calling XSync is no longer required. Also calling XFlush after XAllowEvents did not solve the problem either.
By the way I originally saw the XAllowEvents solution in this Stack Overflow question and this website.

How-to Stop sending out PDU in FlexRay with capl

I have a FlexRay PDU called TEMP in our case, which is getting filled in every cycle, and i would like to simulate a timeout on this PDU, but it has no updatebit.
I have a panel where i check the enable button to decide if it should be sent out or not.
frPdu FR::TEMP_Pdu;
on preStart {
if (#FR_namespace::TEMP_Enablebutton)
{
FRSetSendPDU(TEMP_Pdu);
}
}
on frStartCycle * {
if (#FR_namespace::TEMP_Enablebutton)
FrUpdatePDU(TEMP_Pdu, 1, 1));
}
Whatever I set my button to, the PDU gets transmitted every loop.
FRUpdatePDU() is not sending another instance of PDU, it is just updating the next iteration with data from the frPDU object, since we are talking about PDU of a static frame, once the VN starts sending it, you cannot stop it individually by PDU control.
Frame vs. PDU
A frame is physical Flexray Frame on the network. a PDU, is a virtualization of a part (or of the entire) of the frame payload.
Analogy: The postal truck is the FlexRay Frame, and the boxes in it are PDUs. For the Postal service (Flexray Protocol - OSI layer 1) the important unit is the truck itself, and for you (the client), the boxes in it. You will never be interested in what kind of truck delivered your goodies in a box, you are interested only in the content itself.
When you call the FrUpdatePDU(), you not only start sending the PDU, but you activate (send non-null frames) its slot also.
By setting the frame underneath to non-null frame, you ensured (in a case of static frame) that it will be sent cyclically from that point, automatically, regardless what you want to do with the PDU (the trucks are going anyway, even if you don't want to send boxes in them).
Solution:
I presume you do not have IL DLLs to aid you, therefore you are limited to the functions CANoe environment provides as General FlexRay IL functions.
You need to identify the frame carrying the PDU.
You need to manipulate the frame also with frUpdateStatFrame().
frframe FramefromDBCofTEMPPDU InstanceofFrameTemp;
on frStartCycle *
{
if (#FR_namespace::TEMP_Enablebutton==1)
{
mframe.fr_flags=0x0;
frUpdateStatFrame(mframe);
TEMP_Pdu.byte(0xAA);
FrUpdatePDU(TEMP_Pdu, 1, 1));
}
else
{
mframe.fr_flags=0x80;
frUpdateStatFrame(mframe);
}
}
So, in fact you need to modify the frame also. About the frame flags, check out the definition of the frframe in Help.
I don't use Vector CANoe or CANalyzer myself and there is almost no public documentation, so I can only offer some general debugging hints:
Have you checked that #FR_namespace::TEMP_Enablebutton has the expected value, i.e. that it is really false when you turn the button off? You could add a write() before the if() inside "on frStartCycle" to check this.
This question looks similar: Sending Periodic CAN signals on button press using CAPL and CANalyzer - they use "on sysvar" to react to the button press, maybe you have to do something similar. Namely: React to the button press, set an environment variable, check that variable in "on frStartCycle"
Since there is not a lot of public documentation, you can also try asking around inside your company, there might be some people around you who can help you.

Broadcasting of Messages in Veins example

I noticed that in the Veins demo scenario a node broadcasts the data message it creates to each and every other node in the simulation.
I tried to modify that a bit. I modified the sendMessage() function in TraCIDemo11p.cc file by initializing the address of the recipient in the WSMusing the setRecipientAddress() function. But while running the simulation in Veins 3.0, I find that this message is still being broadcast to all the nodes apart from the target node.
How do I implement this p2p connection?
How do I generalize by adding an RSU to the scenario to implement a heterogeneous communication framework?
In its basis the 802.11p standard, which is the main communication standard for Vehicular Communication (and also the one used in Veins), does broadcast.
So basically, whatever you send via a 802.11p network interface, it will always be broadcasted, however you can make-up some type of p2p by doing "source-destination checking" from the frames.
You can extend the WaveShortMessage to contain Source and Destination fields specific for your application, and then perform checks if the destination is receiving from the intended sender.
Lets say we have two nodes nodeSender and nodeReceiver who want to communicate.
nodeSender would need to include its own identifier (name, ID etc) in the message:
msgToSend->setSourceAddress("nodeSender")
nodeReceiver would need to check if the message it "hears" is from the intended sender. Because in reality it will be hearing from multiple senders due to the broadcast nature of 80211p
if(receivedMsg->getSourceAddress() == 'nodeSender')
{
/* this is the message which I need */
else
{
/* do nothing with the message from other senders */
}
You can use vehicles SUMO id as their unique identifier for the addresses. You can obtain that by querying the TraCIMobility module:
cModule *tmpMobility = getParentModule()->getSubmodule("veinsmobility");
mobility = dynamic_cast<Veins::TraCIMobility*>(tmpMobility);
ASSERT(mobility);
mySumoID = mobility->getExternalId();

OSX Cocoa input source detect change

Does anyone know how to detect when the user changes the current input source in OSX?
I can call TISCopyCurrentKeyboardInputSource() to find out which input source ID is being used like this:
TISInputSourceRef isource = TISCopyCurrentKeyboardInputSource();
if ( isource == NULL )
{
cerr << "Couldn't get the current input source\n.";
return -1;
}
CFStringRef id = (CFStringRef)TISGetInputSourceProperty(
isource,
kTISPropertyInputSourceID);
CFRelease(isource);
If my input source is "German", then id ends up being "com.apple.keylayout.German", which is mostly what I want. Except:
The results of TISCopyCurrentKeyboardInputSource() doesn't change once my process starts? In particular, I can call TISCopyCurrentKeyboardInputSource() in a loop and switch my input source, but TISCopyCurrentKeyboardInputSource() keeps returning the input source that my process started with.
I'd really like to be notified when the input source changes. Is there any way of doing this? To get a notification or an event of some kind telling me that the input source has been changed?
You can observe the NSTextInputContextKeyboardSelectionDidChangeNotification notification posted by NSTextInputContext to the default Cocoa notification center. Alternatively, you can observe the kTISNotifySelectedKeyboardInputSourceChanged notification delivered via the Core Foundation distributed notification center.
However, any such change starts in a system process external to your app. The system then notifies the frameworks in each app process. The frameworks can only receive such notifications when it is allowed to run its event loop. Likewise, if you're observing the distributed notification yourself, that can only happen when the event loop (or at least the main thread's run loop) is allowed to run.
So, that explains why running a loop which repeatedly checks the result of TISCopyCurrentKeyboardInputSource() doesn't work. You're not allowing the frameworks to monitor the channel over which it would be informed of the change. If, rather than a loop, you were to use a repeating timer with a low enough frequency that other stuff has a chance to run, and you returned control to the app's event loop, you would see the result of TISCopyCurrentKeyboardInputSource() changing.

GSM SM5100B C M E E R R O R : 4 error

I am using Arduino to control an SM5100B GSM device, everything works except when I want to send an SMS after receiving another. I get this,
Error code:
O K > + C M G S : 2 5 O K + C M E E R R O R : 4
My code for handling the aforementioned received SMS:
#include <SoftwareSerial.h> //Include the NewSoftSerial library to send serial commands to the cellular module.
char inchar; //Will hold the incoming character from the Serial Port.
SoftwareSerial cell(2,3);
char mobilenumber[] = "0597010129";
void setup() {
//GSM
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
Serial.println("Initialize GSM module serial port for communication.");
cell.begin(9600);
delay(35000); // give time for GSM module to register on network etc.
Serial.println("delay off");
cell.println("AT+CMGF=1"); // set SMS mode to text
delay(200);
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to serial out upon receipt
delay(200);
}
void loop() {
if(cell.available() >0)//If a character comes in, from the cellular module
{
inchar=cell.read();
Serial.println(inchar);
if (inchar=='#'){ // OK - the start of our command
delay(10);
inchar=cell.read();
Serial.println(inchar);
if (inchar=='a'){
delay(10);
Serial.println("The folowing SMS : \n");
inchar=cell.read();
Serial.println(inchar);
if (inchar=='0'){ //sequance = #a0
Serial.println("#a0 was received");
}
else if (inchar=='1'){//sequance = #a1
Serial.println("#a1 was received ");
sendSms();
}
}
cell.println("AT+CMGD=1,4");// AT command to delete all msgs
Serial.println(" delete all SMS");
}
}//end of if(cell.available() >0) {...}
}
void sendSms(){
//cell.println("AT+CMGF=1"); // set SMS mode to text
cell.print("AT+CMGS="); // now send message...
cell.print((char)34); // ASCII equivalent of "
cell.print(mobilenumber);
cell.println((char)34); // ASCII equivalent of "
delay(500); // give the module some thinking time
cell.print(":D hello m3alleg :D"); // our message to send
cell.println((char)26); // ASCII equivalent of Ctrl-Z
delay(20000);
}
General note about your handling of AT commands.
No, no, no! This way of doing it will never work reliably. You MUST
wait for the > character to be received before sending "text
to send". Or actually it is not just the > character, it is four
characters. Quote from 3GPP specification 27.005:
the TA shall send a four character sequence
<CR><LF><greater_than><space> (IRA 13, 10, 62, 32) after command line
is terminated with <CR>; after that text can be entered from TE to
ME/TA.
(TA (terminal adapter) here means modem and TE (terminal equipment) the sender of AT commands)
For any abortable AT command (and 27.005 clearly states for AT+CMGS
This command should be abortable.) the sending of any character will
abort the operation of the command. To quote ITU V.250:
5.6.1 Aborting commands
...
Aborting
of commands is accomplished by the
transmission from the DTE to the DCE
of any character.
(DCE (data communication equipment) here means modem and DTE (data terminal equipment) the sender of AT commands)
This means that when you send "text to send" before "\r\n> " is sent
by the modem the command will be aborted. There is no way to wait "long
enough" for expecting the response be send. You MUST read and parse
the response text you get back from the modem.
The same applies for the final result code after each command (e.g. OK,
ERROR, CME ERROR and a few more). For instance sending "AT+CMGF=1"
and then sending the next command without first waiting for OK is begging
for problems. So always when sending AT commands, you MUST wait
for the final result code before sending the next command.
Please never, never use delay to wait for any AT command response. It's
as useful as kicking dogs that stand in your way in order to get them
to move. Yes it might actually work some times, but at some point you
will be sorry for taking that approach...
Answer to your question.
Based on the response you get, I can see that your problem is not command
abortion (although your parsing have serious problems as described above
that you should fix), and the CME ERROR is your best clue. From section
"9.2.1 General errors" in 27.007 it gives operation not supported as
description for value 4.
27.005 states that:
If sending fails in a network or an ME error, final result code +CMS ERROR: is returned.
Notice that this is +CMS ERROR and not +CME ERROR, but it is applicable, see below.
I guess that sequence of actions is as following:
The AT command handling part of the SM100B GSM modem accepts the sms data
and formats it in an appropriate format and sends it of to the part of the
modem that communicates with the GSM network. It successfully send the
sms data to the network and reports this back to the AT command handling
part which then prints +CMGS: 25 and final result code OK. However
after a short time the network sends back a rejection message for the sms,
which is then given as the +CME ERROR response.
If my guess above is correct, should the response have been delivered
as +CMS ERROR instead? No, because the final response
has for the AT+CMGS command has already been given (OK), and
returning multiple final result codes for a command should never be done
(except by mistake (note 1)).
And while +CME ERROR can replace the ERROR final result code,
it is not only a final result code. From the AT+CMEE command description:
Set command disables or enables the use of result code +CME ERROR: as an indication of an error relating to
the functionality of the MT. When enabled, MT related errors cause +CME ERROR: final result code instead
of the regular ERROR final result code. ERROR is returned normally when error is related to syntax, invalid parameters,
or TA functionality.
Thus +CME ERROR can both be an final result code as well as an unsolicited
result code (possibly also an intermediate result code).
But could not the AT+CMGS command have waited to receive the network
rejection and returned +CMS ERROR? Probably not. Without knowing too
much about the network details of sms sending, it might be the case
that rejection today might occur at a much later time than before. Such
changes are sometimes a problem with GSM related AT commands which have
an old heritage that was originally tightly tied to GSM behaviour which
some times becomes less and less true as the technology moves to GPRS,
UMTS, LTE, etc.
Note 1:
One of my former colleagues used to complain about the way the standard
have specified voice call handling, because after a ATD1234; command
you first get the final result code OK, and then later when the call is
ended you get a new final result code NO CARRIER. This just horribly
bad design, the call end indication should have been a specific unsolicited
response and not a final response.
So to summarise
Your sms seems to be rejected by the network. Try to find out why.
You also have some serious problems with your AT command handling
that you should fix; there is no way to handle AT commands without
reading and parsing the response text from the modem.
cell.println("AT+CNMI=3,3,0,0"); // set module to send SMS data to
serial out upon receipt
For anyone who is looking for answer to the same problem I had:
I was trying to wake up gsm module from sleep mode by sending sms and it didn't work right away. Phone call goes straight to UART, but for sms you have to use this command to set module to send SMS data to serial port upon receipt .
AT+CNMI=3,3,0,0

Resources