Send ethernet/udp packet via CAPL - can-bus

How to send ethernet packets or UDP packets via CAPL? I know there is an ethernet IG block but I wanted to know if we can send it via capl script just like a CAN messagee is sent via CaPL

Function ethernetPacket <packet var>; can be used to create an Ethernet send object. The object data can be manipulated by selectors associated with this object. More information about these selectors can be found in Help at the following path:
CAPL Functions » Ethernet » ethernetPacket
Here an example on how to send a Ethernet Packet via CAPL
ethernetPacket txPacket;
int i;
txPacket.msgChannel = 1;
txPacket.hwChannel = 2;
txPacket.source = EthGetMacAddressAsNumber( "20:00:00:00:00:01" );
txPacket.destination = EthGetMacAddressAsNumber( "FF:FF:FF:FF:FF:FF" );
txPacket.Length = 100;
txPacket.type = 0xF123;
for( i = 0; i < txPacket.Length; i++ )
{
txPacket.Byte(i) = i & 0xFF;
}
output( txPacket );

You may indeed send ethernet packets through CAPL.
With option .Ethernet several APIs are provided for receiving and transmitting Ethernet frames.
The CAPL Function guide.
For instance, the function ethernetPacket is used to create an Ethernet send object. Unfortunately, I've never done it myself, so I don't have a snippet to demostrate this, yet I urge you to refer to the CANoe/CANalyzer guide under section CAPL Functions > Ethernet CAPL Functions. Interrupt-like procedures are also provided for Ethernet communication, e.g. on ethernetPacket. In addition, you might want to put some more effort in the research, next time...
I know nothing of UDP, yet for sake of completeness CAPL provides APIs for TCP/IP, FlexRay, RS232 (serial), and standards like J1939, K-Line.

Related

is there a way to modify the CANoe Rx Messages before Receiving on the Bus?

I'm Receiving CAN Message from my Controller(Suppose Message ID= 0x100 signals S1,S2),
But I want to change the signals of Canoe Rx message before Receiving it on the Bus.
basically if you want to change something in a CAN frame you can do something like this in capl.
Example:
Framename: TEMP
Signal you want to change: S1, S2
on message TEMP /* or "on message 0x100" in your case */
{
/* if you have a dbc or arxml assigned to the canoe project you can directly
* use frame names and signal names to manipulate the data.
* if not you need to use it's ID and write over the bytes on it.
*/
this.S1 = whatever_value;
this.S2 = whatever_value;
output(this);
}
If you don't have a DBC/ARXML file added to the project, but i highly recommend to do so. The only thing you need to change in the above code that you have to specify which bytes you overwrite.
You change this:
this.S1 = whatever_value;
this.S2 = whatever_value;
To this:
this.byte(0) = whatever_value;
this.byte(1) = whatever_value;
But you need to know which bytes you need to overwrite.
If you cannot modify the message before being sent by the Controller, your only option to modify your message is a HIL (Hardware In the Loop), which you position between the sender (Controller) and CANoe VNs on the bus.
They are called CANStress modules for instance, if you wish to stick to Vector products.
They will sniff the messages on your bus, and at the defined trigger (by you) will overwrite the Physical Layer with whatever you wish, successfully altering or fault-injecting the bus.
Be aware, that modifying the signals means you have to know their mapping, also how to recalculate the CRC tag and modify that also, otherwise the CANoe VN will not accept your message, and will report Rx_Err CRC Check.

Trying to connect to Ticket Printer using VB6 Winsock

I am trying to send data from a VB6 program to a ticket printer Via TCP/IP. The only VB6 way I have found to try and do this is using the WinSock Control.
I use the following code to connect
WinSock.Protocol = sckTCPProtocol
WinSock.RemoteHost = txtIPAddress.Text
WinSock.RemotePort = txtPort.Text
WinSock.Connect
And then try and send the data as follows
WinSock.SendData ("<F8>" & txtPrint.Text & "<p>")
Everytime I try and do this, it fails because the Winsock.State is 6 (Connecting). This just stays at connecting and never connects or fails. I am able to connect to the printer using this IP/Port combo outside of VB6. Is there anything I may be doing wrong? Can the WinSock control do this?
In a .net program provided, this seems to be accomplished by doing the following:
CONNECT
client = new TcpClient(ip_address, 9100);
s = client.GetStream(); //s is System.Net.Sockets.NetworkStream
s.ReadTimeout = 500; //attempt to read for up to 0.5 seconds
sr = new StreamReader(s); //create read stream
sw = new StreamWriter(s); //create write stream
sb = new BinaryWriter(s); //create binary stream
sw.AutoFlush = true; //set write stream to flush data when < full buffer
SEND:
sw.WriteLine(command);
Thank you.
You are missing up concepts. I remember this from 15 years ago.
Winsock is for work with a protocol. You must know the printer protocol. Is not just sample text.

send xml data via socket with message (VLI) Ruby

Ruby novice. First time post so excuse any communication protocol inadequacies :)
This site has been a great help and a "HUGE!!!" shoutout of thanks to all.
I need to connect my rails app to an electricity providers api so I can vend electricity to my web customers. I'm needing some help to simply get an initial request sent to the API
IP: 41.204.194.188
Port: 8945
First block: What is a message variable length indicator (VLI)?
"2 bytes precede every message sent to/from BizSwitch. The 2 bytes are referred to as a variable length indicator. Bytes 1-2 indicate the number of bytes in the message (excluding the first 2 bytes). The 2 bytes represent a 16bit unsigned integer in network byte order. Note that if a compressed message is being sent, the message will have to first be compressed, in order to determine its length, before being sent."
Ignore compression.
link to api doc: https://dl.dropboxusercontent.com/u/3815995/Ipay-prepaidElecTransactionSpec.pdf
Simple Vend Request example:
<ipayMsg client="ipay" term="1" seqNum="0" time="2002-05-16 10:55:30 +0200">
<elecMsg ver="2.37">
<vendReq>
<ref>136105500001</ref>
<amt cur="ZAR">11400</amt>
<numTokens>1</numTokens>
<meter>A12C3456789</meter>
<payType>cash</payType>
</vendReq >
</elecMsg>
</ipayMsg>
Simple Vend Response example
<ipayMsg client="ipay" term="1" seqNum="0" time="2002-05-16 10:55:35 +0200">
<elecMsg ver="2.37"
<vendRes> <ref>136105500001</ref>
<res code="elec000">OK</res>
<util addr="Megawatt Park, Contact Centre tel 086-003-7566" taxRef="4740101508" distId="6004708001509">Eskom Online</util>
<stdToken units="346.34" rctNum="12345678" amt="10000" tax="1400">12345678901234567890</stdToken>
<rtlrMsg>060000 Warning: This meter is not configured for FBE.</rtlrMsg>
<customerMsg>Meter not registered for Free Basic Electricity. Please apply at your local office.</customerMsg>
</vendRes>
</elecMsg>
</ipayMsg>
I've got this far and I seem connected but how do I actually send and receive responses? I've tried googling for help but yet to find how to send the XML packet and then receive the response.
#!/usr/bin/env ruby
require 'socket'
begin
socket = TCPSocket.new('41.204.194.188', 8945)
rescue => e
puts "error: #{e}"
else
puts "connected"
end
socket.close
Would appreciate any assistance or a nudge in the right direction.
Kind regards,
Jamie
Great I figured it out. Main issue regarding communication to the socket was sending a message variable length indicator. This stackoverflow question put me on the write path "Ruby - How to represent message length as 2 binary bytes"
Step 1: determine the length of my xml message length = message.size
The first field in the header must be the message length which is defined as a 2 binary byte message length in network byte order.
Step 2: message_variable_length_indicator = [length].pack("n")
Step 3: Connect to socket streamSock = TCPSocket::new('41.204.194.188', 8945)
Step 4: streamSock.write(message_variable_length_indicator)
Step 5: streamSock.write(message)
Step 6: get a response str = streamSock.recvfrom(1000)
Now to deal with timeout but at least I'm connecting :)
I have done this in PHP may be you will get idea from below code its working fine for my request.
function sendSocketRequest($XmlString, $Socket_Request) {
if (!($sock = socket_create(AF_INET, SOCK_STREAM, 0))) {
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("Couldn't create socket: [$errorcode] $errormsg \n");
}
if (!socket_connect($sock, $Socket_Request['HostName'], $Socket_Request['Port'])) {
$errorcode = socket_last_error();
$errormsg = socket_strerror($errorcode);
die("Could not connect: [$errorcode] $errormsg \n");
}
$status = socket_write($sock, pack_int32be(strlen($XmlString)), 4);
$status = socket_write($sock, $XmlString, strlen($XmlString));
$response = socket_read($sock, $this->_socketReadLength);
socket_close($sock);
return substr($response, 2);
}
function pack_int32be($i) {
if ($i < -2147483648 || $i > 2147483647) {
die("Out of bounds");
}
return pack('C4', ($i >> 24) & 0xFF, ($i >> 16) & 0xFF, ($i >> 8) & 0xFF, ($i >> 0) & 0xFF
);
}
$socketResponse = sendSocketRequest($yourXMLString, array('HostName'=>'<HostName>','Port'=>'<Port>');

How to receive UDP data in Vala?

another Vala problem occured: I try to send and receive data via UDP. The sending works and via Wireshark I can see that the server sends the expected result. Problem is: My program doesn't get the data.
I checked and I can see that, when a socket has been created to send the UDP data, the specific port stays open, which is confirmed by Wireshark because my PC doesn't send any of those ICMP messages back to the server.
What I got so far:
try
{
SocketClient mySocket = new SocketClient();
mySocket.protocol = SocketProtocol.UDP;
mySocket.type = SocketType.DATAGRAM;
var conn = mySocket.connect (new InetSocketAddress(addr,targetPort));
conn.output_stream.write(themessage_in_a_uint8_array);
DataInputStream response = new DataInputStream (conn.input_stream);
string resp ="";
char myChar;
try
{
do
{
myChar = (char)response.read_byte();
print ("Response" + myChar.to_string());
}while(true);
}
catch(Error e)
{
print(e.message);
}
}
catch(Error e)
{print(e.message);}
What currently happens: The message is send, the string 'Response' is printed once into the console and after that it just loops.
If I check response.get_available() it returns 0.
I can check with lsof | grep used_portnumber and sure enough, the used socket stays open. What am I doing wrong?
I am not sure but this is what I suspect:
UDP is a datagram protocol (data is explicitly chopped into data). Server have sent one datagram to client. Now in BSD Sockets (and after it everywhere) if the underlaying socket have datagram type then read reads the full packet. If the buffer have insufficient length the message is truncated.
The solution is read in one byte. For example
uint8[] buffer = new uint8[1 << 16]; // Maximum UDP length - we don't loose anything
unowned string locale;
bool need_convert = GLib.get_charset (out locale);
do {
ssize_t len = response.read (buffer);
string text;
if (need_convert) {
text = GLib.convert ((string)buffer, len, locale, "UTF-8");
} else {
text = (string)buffer;
}
stdout.print("Response " + text);
} while (true);
Edit I have change the code to print UTF-8 text - without assuming current locale is "UTF-8"-based.
PS 1 This is my guess as it is one gotcha of BSD Sockets (also Winsockets and everything that builds on this) that come to my mind. Please be graceful if the question will be more specific (i.e. it is not the answer to question).
PS 2 In general I would recommend against mixing bytes and chars. While in ASCII-compatible encodings (ISO, UTF-8) sending ASCII subset of chars is safe it will bite when attempt on CJK encodings or if sender will send 'ą' by UTF-8 and sender will treat it as ISO-8859-2 (where this character have different encoding). I assume it is for the toy-examples only. If not you may want to read What Every Programmer Absolutely, Positively Needs To Know About Encodings And Character Sets To Work With Text.

Wireshark Lua Dissector - How to set source and destination

I'm working on a Wireshark Dissector in Lua.
I try to provide wireshark as much information about my custom protocol as possible to make use of the available analysis tools. Therefore I'm trying to set the correct source and destination address for my protocol.
My protocol can be on top of different other protocols such as UDP or IEEE 802.15.4. So it might even be that the package source/destination is already set (UDP).
However I want wireshark to show my addresses, so I tried the following:
myproto = Proto("myproto"), "My Protocol")
myproto_source = ProtoField.uint16("myproto.src", "Source Address", base.HEX)
myproto.fields = { myproto_source }
function myproto.dissector(buffer, pinfo, tree)
local subtree = tree:add(myproto, buffer(), "My Proto")
subtree:add(myproto_source, buffer(0,2)
-- does not work with error:
-- bad argument #1 to '?' (Address expected, got userdata)
pinfo.src = myproto_source
-- does work, but only adds text, wireshark tools rely on pinfo.src
pinfo.cols.src = tostring(buffer(0,2):uint())
end
udp_table = DissectorTable.get("udp.port")
udp_table:add( 12345, myproto )
wtap_encap_table = DissectorTable.get("wtap_encap")
wtap_encap_table:add(wtap["IEEE802_15_4"], myproto)
So is there maybe a datatype/class "address" that is necessary to set pinfo.src? Or is there a totally different way to set the packet information?
Thanks in advance!
pinfo.src takes an Address object (which is an IP address; not a 16-bit integer). Example usage:
pinfo.src = Address.ip('1.2.3.4')
Note that this only sets the text of the "Source" column shown in Wireshark. The underlying packet info cannot be modified, and the IP packet details will continue to show the actual IP address.
Just a suggestion - I'm not an LUA wiz:
pinfo:col.src = buffer(0,2):uint()
maybe??

Resources