Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can-j1939 - trying to emulate an entire truck #511

Open
mihai-demian opened this issue Mar 29, 2024 · 22 comments
Open

can-j1939 - trying to emulate an entire truck #511

mihai-demian opened this issue Mar 29, 2024 · 22 comments

Comments

@mihai-demian
Copy link

First of all, please allow me to thank you for the great work are doing.
I am trying to emulate a truck, meaning that I want to get the information from a game (namely ets2) and send it to a truck dashboard cluster. I managed to put together some parts on the application, where I can send 8byte packages at consistent time intervals, as stated in the j1939 standard (older, found for free online). The BAM message representing the engine configuration is sent correctly from testj1939, but it is not when sent from my application, although everything is the same. I have a BAM message every 5 seconds and some typical messages every 50ms, all happening at the same time. Can this be an issue?
How can I perform a read and write on the same socket without any issues? There is not much to read from the cluster, except for a BAM DM1 message (fault codes) and a reset message to the tachograph.
I have no filters set up. I did not understand how to use them yet, and also not found the reason to implement them since there is no message addressed the part of the application that I'm working on (engine at 0x00).
I attached the application part I wrote as far, but I have a lot more to do.
My plan to have a vcan interface for every controller involved (engine, transmission, retarder, main computer and tachograph), put all of them to the same can interface that is connected with the cluster. Is this approach worth implementing?

I am looking forward for any help.
Thank you.

engine.c.txt
engine.h.txt

@olerem
Copy link
Contributor

olerem commented Mar 30, 2024

Hi @mihai-demian,

First of all, please allow me to thank you for the great work are doing. I am trying to emulate a truck, meaning that I want to get the information from a game (namely ets2) and send it to a truck dashboard cluster.

it is good to hear that some one is using the J1939 kernel stack :) Interesting project!

I managed to put together some parts on the application, where I can send 8byte packages at consistent time intervals, as stated in the j1939 standard (older, found for free online). The BAM message representing the engine configuration is sent correctly from testj1939, but it is not when sent from my application, although everything is the same. I have a BAM message every 5 seconds and some typical messages every 50ms, all happening at the same time. Can this be an issue? How can I perform a read and write on the same socket without any issues? There is not much to read from the cluster, except for a BAM DM1 message (fault codes) and a reset message to the tachograph. I have no filters set up. I did not understand how to use them yet, and also not found the reason to implement them since there is no message addressed the part of the application that I'm working on (engine at 0x00). I attached the application part I wrote as far, but I have a lot more to do.

The kernel stack takes over some of management and filtering work, the only thing what user space need to do, is to use one socket per task/message type. It means, if you work with different message types like broadcast and "unicast"-ish, you need to use different sockets.
In case you need some examples, you can take a look to the ISOBUS File Server:
https://github.com/linux-can/can-utils/blob/master/isobusfs/isobusfs_srv.c#L249

It is a single threading application with multiple sockets and periodic tasks.

My plan to have a vcan interface for every controller involved (engine, transmission, retarder, main computer and tachograph), put all of them to the same can interface that is connected with the cluster. Is this approach worth implementing?

In general, if you wont to emulate different MCUs/Components of the truck, it will be best to have separate program per MCU. No need to create different VCAN interfaces per MCU. The sockets are already kind of software extension of CAN bus interfaces. Well, if you wont to do it the hard and secure way, you can put every MCU application isolated in the network name spaces with own V/CAN interfaces too:

https://medium.com/@fi.shajal27/introduction-to-network-namespace-and-the-process-of-connecting-two-network-namespaces-d1817e292deb

In case you need more examples, here is a server which receives HID events over CAN and injects it to kernel uinput devices. It was used for this demonstrator to play tetris over CAN:
https://pengutronix.de/de/blog/2020-02-26-embedded_world_2020.html#&gid=3&pid=1

I am looking forward for any help. Thank you.

In case you will make it more generic and reusable way (one application per MCU) it will be great to include your work to this repository.

@mihai-demian
Copy link
Author

Hello,
Can anyone explain the difference between bind and connect on a SOCK_DGRAM, and how to use them?
I tried with bind and sendto and it works fine, but I cannot figure out how to use connect and send.
Thank you.

@olerem
Copy link
Contributor

olerem commented Apr 22, 2024

@mihai-demian
Copy link
Author

Hello,
and thank you again for your help and for your support.
I (poorly) made a video of my progress so far.
ETS 2 Telemetry MAN TGX instrument cluster
Now I am stuck in a TCP or UDP communication I need for switching the cluster on and off. Every textbook solution I tried failed... If you have any ideas, please share.
Thank you.

@olerem
Copy link
Contributor

olerem commented Apr 26, 2024

Can you please tell more about what you wont to make? Are you trying to implement TCP/UDP to J1939 bridge?

@mihai-demian
Copy link
Author

Hello,
No, i want to be able to turn on and off the cluster and to switch on and off the backlight. I want to do this using a Siemens s7-1200 plc. The TCP communication is pretty easy according to their manuals, the plc has integrated functions for TCP/UDP communication. The only problem is that i cannot do it.
I want plc to be the client and initiate a connection. The pc should listen and accept the connection. The plc program i know how to do (i am a plc programmer after all), the problem i encounter is the pc. I am not sure that i am using the socket/bind/listen/accept functions properly.
I want to bind the socket to the existing network, the same network that is used for internet connection, and for this the book says that i can use aton() to suggest an IP address. Yet, it doesn't work.
I will try using the ncat program to listen for a TCP connection and then, maybe, I will be able to understand what I l'm doing wrong.
Thank you.

@mihai-demian
Copy link
Author

Hello,
OK, funny enough, the connection seems to be working with both ncat and sockettest

now i have to make it work with my own code....

@mihai-demian
Copy link
Author

Hello,
@olerem , I need your help again.

I wrote some code that you can find in my repository. I will not make it public until it is ready.
If I use spn1214_from_spnno_v1 function to generate an error code, and the send it to the cluster, it works fine.
However, when i try converting the error codes sent from the cluster, i find no usable result.
What am i missing?
Thank you.

@olerem
Copy link
Contributor

olerem commented May 4, 2024

@mihai-demian , Sorry I do not have enough experience with this part of the protocol.
So, let's try to understand. You are sending DM1 PGN 65226 message with SPN 1214 - Suspect Parameter Number, which parameters (1208, 3, 10). Which is pointing to SPN 1208 (Pre-filter Oil Pressure). I didn't decoded 3 and 10 so far. Correct?
And you get as response?

@mihai-demian
Copy link
Author

@olerem , The meaning of the SPN is not important right now. I cannot decode whatever the cluster is sending.
In the SAE J1939-73 it is stated that 4 conversion versions exist, and that v4 must be used starting September 1996 (if memory serves). V1-3 set conversion method to 1 and V4 set CM to 0. Since I did 4 functions, CM is taken care of inside the function.
The parameters (1208, 3, 10) represent SPN number, FMI number and occurrence count, and when sent to the cluster, the diagnosis message 1208-3 is displayed.
My issue at the moment is converting from hex to decimal form. When I try converting the message from hex (received from the cluster) to decimal, none of the conversion methods yields a usable SPN (below 8500).
v1: 196683, v2: 19203, v3/v4: 199008
v1: 191143, v2: 172783, v3/v4: 480349
v1: 65913, v2: 96513, v3/v4: 77600
v1: 229564, v2: 48004, v3/v4: 268144
I am sure I am doing the conversion wrong, I just don't know how. I may be missing a byte swap, I don't know.
The message is received in intel byte order, so if I copy the message to an array of bytes, it should be in the correct order (I use the same technique for all other messages I send to the cluster and everything works fine).
May you check the functions declared in saej1939_73.c?
Thank you.

@olerem
Copy link
Contributor

olerem commented May 4, 2024

can you please use candump and send the output of messages you send and receive?

@mihai-demian
Copy link
Author

can you please use candump and send the output of messages you send and receive?

done

@olerem
Copy link
Contributor

olerem commented May 8, 2024

What do you mean?

@mihai-demian
Copy link
Author

What do you mean?

there are 2 candump files here

@olerem
Copy link
Contributor

olerem commented May 9, 2024

Ok, for protocol.
You are sending following message 18FECA00#55FFB804030AFFFF and cluster interprate it properly:

  • 0xFECA - PGN for DM1
  • 0x00 - source address
  • 0x55 - activate some notification LEDs
  • 0xFF - do not blink this LEDs
  • 0xB80403 - 0x004B8 - SPN 1208
  • 0x03 - Error 3.

And, if I see it correctly, you are trying to interpret following message from cluster 18ECFF17#200E0002FFCAFE00. Correct?
This message can't be interpreted standalone, it is part of transport protocol BAM message.
All messages should be combined together, which should be done by the kernel. Here is complete messasge:
(1715022788.968544) can0 18ECFF17#20120003FFCAFE00
TP PGN (0xec00), from 0x17 to broadcast. TP command BAM, Destination PGN 0xFECA (DM1)
And here is actual payload:
(1715022789.018926) can0 18EBFF17#01C0FF53F784FE44
(1715022789.069680) can0 18EBFF17#0201248143F5C4FE
(1715022789.118177) can0 18EBFF17#0343F86481FFFFFF

After kernel processing, you should get following payload in user space:
C0FF53F784FE44, 01248143F5C4FE, 43F86481

0xc0 - leds to be activated
0xff - do not blink
0x53F784 - unknown SPN interpretation
0xFE - bit 8 set to 1, convert SPNs per Version 1, 2 or 3 specified below:
1. SPN assumed to be sent most significant bit first (53F784 >> 5 = 0x29FBC, 171964)
2. SPN represented as Intel format for most significant 16 bits, with 3 least significant bits of 19 bits in with FMI value. (F75384 >> 5 = 0x7BA9C, 506524)
3. SPN represented as Intel format for all 19 bits (least significant sent first) (84 >> 5 = 0x4, 0x4F753 = 325459)
4. SPN represented as Intel format for all 19 bits with the SPN Conversion Method set to 0.

Hm, currently I can't extract plausible values of this message.

@olerem
Copy link
Contributor

olerem commented May 9, 2024

What if you feed this message back to the cluster? Will it be able to decode it? You will need to replace source address from 0x17 to something different. The BAM message probably combines multiple SPNs. So, you can try to send only one of them. For example:
8FECA00#C0FF53F784FEFFFF

@mihai-demian
Copy link
Author

Hm, currently I can't extract plausible values of this message.

Hello,
Thank you, now we finally agree on something!
This was my problem all along. Every function I tried failed to properly decode the message, which is why I was sure that I screwed up the function.
I fed then messages back to the cluster and nothing was displayed. Then I realized that the payload my function spns1214_from_spnno_v1 () was generating a payload that differed in the first byte, but only half a byte. So I tried masking the first byte and interpreting the payload with spnno_from_spns1214_v1() and the output was something that I could find in the MAN data compendium.
As soon as I get back home I will post a sample output.
Thank you.

@mihai-demian
Copy link
Author

What do you mean?

there are 2 candump files here

I placed the output of a "program" for reading dm1 messages, together with some comments. Most of the SPN codes have a meaning, although not all of them display a message on the cluster's display.
Thank you.

@olerem
Copy link
Contributor

olerem commented May 10, 2024

If I understand you comments correctly, this cluster is using SPN v1 message format. Correct?
Is it MAN TGX, TGS, TGM, TGL compatible cluster?

@mihai-demian
Copy link
Author

Yes, that is correct. The cluster seems to be using the SPN v1 message format. The seller said that it is a TGX cluster, but i think it is for TGA.

@olerem
Copy link
Contributor

olerem commented May 16, 2024

@mihai-demian , if you need some extra parts for your track emulation project, here is one: olerem@188b83e

@mihai-demian
Copy link
Author

hello,
i am sorry for my late updates.
here is my entire work on the MAN TGA dashbord project.
https://github.com/mihai-demian/truck.git
i still have to figure out how to send diagnostic messages and how to use the k-line, but more on this later
thank you very much for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants