Sponsored
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
This would break us into new territory... To get around this, we would have to get into the LIN bus. I have read up on this a bit, and it sounds like LIN bus are simpler than CAN bus, and it's truely just a simple serial data bus that we just need a receiver chip breakout to work with. This would be how we could directly interact with the aux switches, and also with the windows.
I've been hoping that we didn't have to go there, but the signs are starting to stack up, aren't they? If my latest AUX switch experimentation goes south, I'd be really interested in how to get started. (The only other workround I can figure would be to shoot an ECU reset code somewhere that could reset the AUX power settings as a side-effect?)

Also, wanted to say again, nice job on the radio module reset!
Sponsored

 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
I was playing around with the Raspberry Pi being dual-powered by AUX3 and AUX4. (The Raspberry Pi remains powered if either or both circuits have power, which is the ideal case.) I set AUX3 to latched/ignition/last-state-on and did not alter it. I did the bulk of my experimentation with AUX4.

If you started with AUX4 powered on and in a state of latched/ignition/last-state-on, you could successfully convert it into a state of latched/battery/last-state-on while the ignition was still running. No problem! Sending these commands do the trick:

cansend can0 314#5a.03.04 ; sleep 0.05 ; cansend can0 314#00.00.00 ; sleep 0.05 ; cansend can0 314#00.00.00 ; sleep 0.05​
cansend can0 314#5a.03.02 ; sleep 0.05 ; cansend can0 314#00.00.00 ; sleep 0.05 ; cansend can0 314#00.00.00 ; sleep 0.05​

Then, let's say you've turned the vehicle off and you've exited. AUX4 continues to run, which actually is what you'd want. The RGB halos have power and the Raspberry Pi is still running and in control.

So from here, it would be possible for the Raspberry Pi to sense that it's been running for an awfully long time (30 minutes) with the ignition off. So perhaps we'd be looking at a feature which automatically turns off AUX4 if it had been running for an extended time on battery power, right?

Great! We can actually power down AUX4 by sending TWO changes to AUX4's configuration. First we set AUX4 to last-state-on, and then we set AUX4 to IGNITION. And then it immediately loses power (and we lose the Raspberry Pi with it). But that's good.

The problem happens the next time the key is cycled in the ignition. AUX3 (which we never altered and had been set to power on with ignition) turns on automatically and powers up the Raspberry Pi. But it isn't restoring power back to AUX4. The settings for AUX4 show that it is set to latched/ignition but it isn't showing a checkbox for Last State On and the switch has no power indicator.

The problem seems to be that once you shut down AUX4, there's no CAN configuration command (that we know of) that can tell it to power AUX4 back up again. It requires a physical press of the AUX4 button to restore power. We're able to manipulate AUX4 into powering down when we want, but we can't get it to power back up automatically (with ignition) or manually (upon request).

You don't recall any way from JScan to be able to manually flip an AUX switch off or on, do you?
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
Here's what I pulled up in JScan for AUX4 under the Body Control Module:

Jeep Wrangler JL JEEP HACKING CAN-C / CAN-IHS / UDS ! (Reverse Engineering) 1648235870120


The first variable tracks with actual voltage on the circuit (and the indicator LED on the button itself). The last two are the variables we already know how to set via the uConnect radio and with direct CAN bus commands.

If we can do a bit of CAN bus sniffing to find the IDs for the first piece of data (ASBM_AUX4_On), and then we find the ID for a second piece that we know like CBC AUX 4 Power Mode, then we've at least got a chance at being able to directly alter a switch's power setting by crafting our own custom UDS command. (Or we could stumble across something else we'd recognize.)
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
If we can do a bit of CAN bus sniffing to find the IDs for the first piece of data (ASBM_AUX4_On), and then we find the ID for a second piece that we know like CBC AUX 4 Power Mode, then we've at least got a chance at being able to directly alter a switch's power setting by crafting our own custom UDS command. (Or we could stumble across something else we'd recognize.)
The power status of all the AUX buttons can be read from the BCM with UDS function 0x22 on ID 0xA0C3. The configuration status of all the AUX buttons can be read from the BCM with UDS function 0x22 on ID 0xA051. But that leaves us stuck in the same situation we keep finding ourselves in where we can figure out what ID has information, how to read it, but never how to write back to it.

Writing values to an ID involves command 0x2E (WriteDataByIdentifier) and at some place here we need to find something that we can write data back to the vehicle and figure out how that process actually works. Until we make that leap, a lot of stuff just kind of get stuck as information-only.

I'm trying to think of the best way to accomplish this. Maybe there's some data in JScan that we're reading and updating and we just need the follow the process through to see how it happens from beginning to end. The 0x2E command seems to be the key to making long-term configuration changes. (That's as opposed to something like UDS command 0x2F "I/O By Id" that we can use for digital I/O tasks like honking the horn.)
 

redracer

Well-Known Member
First Name
Robert
Joined
Aug 22, 2017
Threads
20
Messages
576
Reaction score
650
Location
Manteca, CA
Vehicle(s)
2023 4xe Rubicon
Oh interesting... I just stumbled upon this site...
https://copperhilltech.com/

I ordered one of their isolated LIN bus breakout boards. But, they also have a bunch of dual can bus options for the PI and for the Teensy boards. The Teensy is a lot like an arduino but with much more power and options. When we do get to moving away from the Pi for a more finalized install, their boards might just fit the bill.
 

Sponsored

OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
I ordered one of their isolated LIN bus breakout boards. But, they also have a bunch of dual can bus options for the PI and for the Teensy boards.
Truth be told, I'm a little frustrated that the situation has brought us to this point of wanting LIN access.

I mean, my understanding is that the LIN bus by itself doesn't actually control anything. A button status (or status change) might be communicated over the LIN bus, but any actual real-world voltage changes would still have to be done by a module (the BCM in this case.... which also listens on the LIN bus).

There should be a solution for everything with UDS, but without a list of UDS identifiers, we're limited to repeating a limited number of commands from a limited number of tools... and it's too dangerous to try to make guesses and see what a random number in any random place might do if we want to find something new. It's a little frustrating.

All that said though, if we get LIN access, it's more likely than not to help out (even on our current path) in a number of ways. I can't knock it, you're doing the right thing here! I'm just kicking myself trying to come up with another way to get lists of usable items like UDS Data Identifiers, I/O Identifiers, Service Routines.... those kinds of things.

Here's the avenue I'm considering:
Buying a high-end automotive service tablet, harvesting anything and everything I can get from it, and then selling it off as soon as I'm able to limit my cost. I've seen tablets at $1000 and $2000 which seem to foot the bill. I don't know exactly what I'm looking for, but some include FCA Secure Gateway authentication, bi-directional controls (which is what we're after), and diagnostic routines which would be nice to have, too.

I have no idea how to really compare the number of items they offer control over or which brand might be best suited to this purpose. Maybe someone else reading this knows more on the subject, but I think that's going to be the one solid way of making a lot of progress in one shot. Of course, it could end up that what you get with JScan is the best that's out there in the world today.
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
I'm seeing a need for a new challenge which moves the ball forward.

Perhaps we need to update a parameter from the Raspberry Pi. A vehicle configuration setting? A month or two ago, I remember that we we made an interesting connection between some UDS data and a regularly broadcasted CAN message. Maybe that's worth exploring some more?

It had to deal with a piece of vehicle configuration data on the Body Control Module (labeled by JScan as "CSM1"). It appears to control access to a list of optional configuration items in the uConnect radio. Like Forward Collision warning... I don't get those menu options because it's not a part of my build.

On the Body Control Module, when we performed a Read By Id operation with an identifier of 0x0146, the data we received from the BCM was nearly identical to what is being broadcast every second on the CAN-C and the CAN-IHS bus with a message Id of 0x3B3.

What's helpful is that we have collected message ID 0x3B3 across three vehicles, so even if we don't know what bits of data enables what, we could apply a configuration that we know does not create any invalid state.

Wrangler 1: $01307641E4A3C710​
Wrangler 2: $01307201FCA10710​
Wrangler 3: $01107501E4A30710​

Perhaps of interest, Wrangler 2 is different because it does not have AUX switches.

So potentially, we could do a Write_Data_By_Identifier operation to store the Wrangler 2 configuration to my current vehicle, followed by a read-back to make sure it took. We could then verify that message ID 0x3B3 has the new configuration. (If not, hit the BCM with a Reset.) After that, we could follow up with the Module Reset command that you recently discovered for the uConnect radio to (hopefully) make it pull a configuration refresh from the BCM. Then (with luck) go into the uConnect Settings and see if we've lost the AUX switch settings.

I seem to remember that some people are using JScan to do the very same thing (but in reverse... adding AUX switches). Should the update not work, this gives us another (and more direct) method of seeing how such an update is actually done.

Now, telling my vehicle it does not have AUX switch settings in the uConnect Radio configuration screen is not very helpful. But what is helpful is having a single working example where we could backup, update, and restore any chosen data identifier from any chosen Module (up to a certain length).

I mention length because I'm clearly running into some data identifiers that want to return more data than you can read without using sessions, which is another challenge we need to address. Now that I'm hashing this out, I'm wondering if our first step should be mastery of the ISO-TP session protocol. It's going to be awkward if we've got a piece of data that's 20 bytes long and we only manage to edit the first 4 bytes.

If I'm looking to reduce risk, I think we've got two layers of (partial) protection for a bad update. First would be the (forgetting the official name) "undo function" of Jscan which backs out your configuration changes (step-by-step or all-at-once). The other would be the unmarry function of the Tazer, but I'll have to go back and confirm that this was one of the BCM configuration IDs that they maintain a copy of.

So I guess we've got two things to shoot for? If we can establish that means of reading, backing up (to the Raspberry Pi), and updating variables in the modules, we're going to be able to move on to more substantial things. Like directly updating the entire configuration of the AUX buttons (all at once) to set everything all at once. I'm hoping the BCM will treat it's own data as the primary source for switch behavior.

The destination doesn't sound very fun, but it seems like the journey may be pretty useful here?

PS: We may need to discovery a third party tool which helps us get a handle ISO-TP sessions.
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
So to begin with, I have three windows open and collecting live data. They're each running one of these three commands:
isotprecv -s 504 -d 620 can1 -l <-- SHOWS COMMANDS TO THE BCM
isotprecv -s 620 -d 504 can1 -l <-- SHOWS DATA FROM THE BCM
candump can1,620:7ff,504:7ff <-- SHOWS RAW TRAFFIC TO/FROM BCM

When I'm using JScan to read the CSM1 variable from the BCM, it regularly issues this command:
22 01 46​
And using isotprecv, I'm able to decode fully decode the response that's spread across multiple messages:
62 01 46 00 30 76 41 E4 A3 C7 10​

Of course, when I myself try to manually send the 22 01 46 command like this:
echo "22 01 46" | isotpsend -s 620 -d 504 -p 00: -P a can1​
It looks like isotprecv makes an attempt at decoding but fails. Right now I'm *guessing* it's because there's no code on our side that detects when a multipart message has been received and then messages back with a "give me the next piece" to the BCM. So the decode eventually times out and fails. So we're missing something there.

I went to diagnose this further, but when I've got a number of CAN processes open and collecting live data, it looks like I'm hitting a kernel and/or device driver bug. The can1 device is actually shutting down on me, as seen in /var/log/messages:

Mar 29 17:48:19 raspberrypi kernel: [ 72.302856] mcp251x spi0.1 can1: bus-off​
Mar 29 17:56:41 raspberrypi kernel: [ 573.481766] mcp251x spi0.1 can1: bus-off​

I can do an "ifconfig can1 up" once and get back online, but after that, it looks like it's taking a reboot to restore CAN connectivity. I've googled with the phrase "raspberrypi kernel: mcp251x spi0.1 can1: bus-off" and while a number of people have been running into it, none of them seem to have found a cure.

This new problem is going to limit what and how much I can reverse engineer here. But the next step in the puzzle seems to be figuring out the dance we need to do to identify that a multi-part message has arrived and then to do whatever is needed to acknowledge and request the next part of the message. Or maybe that's what iotprecv is mistakenly doing for us? I'm not sure. Saw this in my candumps:

can1 620 [8] 03 22 01 46 00 00 00 00 <--- REQUESTING CSM1​
can1 504 [8] 10 0B 62 01 46 00 30 76 <---- FIRST PART OF CSM1 DATA​
can1 620 [8] 30 00 01 00 00 00 00 00 <---- I DIDN'T MANUALLY SEND THAT​
can1 620 [3] 30 00 00 <---- I DIDN'T MANUALLY SEND THAT​

Maybe it's an iotprecv option. Or maybe it doesn't like two processes running at the same time with the sender and receiver ports reversed.
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
Good news!

I've managed to gain access to a high end scan tool. Unfortunately, this isn't a situation where I'm going to be able to work with it on a regular basis. But I will be able to dump the device and try my hand at extracting any JL specific tables and definitions that I can sift out of it.

It's no slam dunk, but another possible door to get where we'd want to be.
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
SESSION EXPLAINED: UPDATING BCM DATA (BY IDENTIFIER)

Some time ago, I captured and notated an BCM parameter update by JScan. The parameter itself is inconsequential (attempting to enable wheel alignment menu), but the order of events and the individual operations give us a blueprint for how persistent changes are made. BCM = Body Control Module.

Message IDs with 620 are being sent TO the BCM.
Message IDs with 504 are being received FROM the BCM.

BCM: WHEEL ALIGNMENT MENU OPTION ON/OFF DISABLED -> ENABLED
=============================================================


The following session was created by the JScan application. It begins by telling the BCM that test equipment (itself) has been connected. It requests an extended rights diagnostic session, and then reads data from the BCM with an identifier of $0147. ($0147 corresponds to what Jscan calls CSM2 - Vehicle Customer Settings Menu 2). CSM2 stores data which ultimately controls what configuration options are visible (or hidden) in the uConnect radio's settings menu.

(If you are interested in following exactly what is being changed, I have colored the affected BYTE red.)

. RAW PACKETS (LEFT SIDE).......EXPLANATION (RIGHT SIDE)
can1 620 [8] 02 3E 00 00 00 00 00 00---------A VEHICLE TESTER IS PRESENT
can1 504 [8] 02 7E 00 A0 3B 52 01 00--------------> accepted
can1 620 [8] 02 10 03 00 00 00 00 00---------REQUESTING AN EXTENDED RIGHTS DIAGNOSTIC SESSION
can1 504 [8] 06 50 03 00 14 00 C8 00--------------> accepted (within provided timing restrictions)
can1 620 [8] 03 22 01 47 00 00 00 00---------READ DATA BY IDENTIFIER: $0147
can1 504 [8] 10 0B 62 01 47 34 80 00--------------> 11 byte payload, initial frame (first 6 bytes)
can1 620 [8] 30 00 01 00 00 00 00 00.--------CONTINUE SENDING THE NEXT FRAME THEN WAIT FOR ACK
can1 504 [8] 21 00 00 00 04 00 80 00.--------------> consecutive and final frame (last 5 bytes)


................... . . . . . .............MULTI-FRAME MESSAGE
-. . . . . . . --------- " IDENTIFIER $0147: 34 80 00 00 00 00 04 00 "

We've got the data. But it's still an entirely different world to figure out which bits correspond to
what configuration options. CSM2 bits might be used to allow the user to see and make choices dealing with optional features such as active blind spot monitoring, auxillary switches, hill start assist, and so much more. We don't know which bits do what, but some people have built tools that do (like JScan, AlphaOBD, or the Tazer JL Mini).

Inside the JScan app, we've told it that we want to enable the steering wheel alignment options in the uConnect settings menu. It does so by reading identifier $0147, and then it writes the data back to identifier $0147 with the requested change. So once again, we perform a read...

. RAW PACKETS (LEFT SIDE).......EXPLANATION (RIGHT SIDE)
can1 620 [8] 02 3E 00 00 00 00 00 00---------A VEHICLE TESTER IS PRESENT
can1 504 [8] 02 7E 00 00 04 00 80 00--------------> accepted
can1 620 [8] 02 10 03 00 00 00 00 00---------REQUESTING AN EXTENDED RIGHTS DIAGNOSTIC SESSION
can1 504 [8] 06 50 03 00 14 00 C8 00--------------> accepted (within provided timing restrictions)
can1 620 [8] 03 22 01 47 00 00 00 00---------READ DATA BY IDENTIFIER: $0147
can1 504 [8] 10 0B 62 01 47 34 80 00--------------> 11 byte payload, initial frame (first 6 bytes)
can1 620 [8] 30 00 01 00 00 00 00 00---------CONTINUE SENDING THE NEXT FRAME THEN WAIT FOR ACK
can1 504 [8] 21 00 00 00 04 00 80 00--------------> consecutive and final frame (last 5 bytes)


................................MULTI-FRAME MESSAGE
- - - - - - - " IDENTIFIER $0147: 34 80 00 00 00 00 04 00 "

But before performing the update, JScan requests an extended rights diagnostic session. This is likely to be an actual requirement before the BCM will accept any identifier to be updated.

. RAW PACKETS (LEFT SIDE).......EXPLANATION (RIGHT SIDE)
can1 620 [8] 02 10 03 00 00 00 00 00---------REQUESTING AN EXTENDED RIGHTS DIAGNOSTIC SESSION
can1 504 [8] 06 50 03 00 14 00 C8 00--------------> accepted (within provided timing restrictions)
can1 620 [8] 02 10 03 00 00 00 00 00---------REQUESTING AN EXTENDED RIGHTS DIAGNOSTIC SESSION
can1 504 [8] 06 50 03 00 14 00 C8 00--------------> accepted (within provided timing restrictions)
can1 620 [8] 10 0B 2E 01 47 34 A0 00---------MULTIPLE FRAMES: FIRST FRAME OF WRITE DATA BY ID $0147
can1 504 [8] 30 08 14 00 14 00 C8 00--------------> accepted (allowing 8 more frames without delay)
can1 620 [8] 21 00 00 00 04 00 00 00---------MULTIPLE FRAMES: CONSECUTIVE FRAME #1 WITH REMAINING DATA


................................MULTI-FRAME MESSAGE
------
" WRITE TO IDENTIFIER $0147: 34 A0 00 00 00 00 04 00 "

After sending the full and complete command to write to $0147, here's how the BCM responds:

. RAW PACKETS (LEFT SIDE).......EXPLANATION (RIGHT SIDE)
can1 504 [8] 03 7F 2E 78 14 00 C8 00--------------> PENDING: STANDBY FOR A RESPONSE FROM THE BCM.
can1 504 [8] 03 6E 01 47 14 00 C8 00--------------> SUCCESSFUL: WRITE TO IDENTIFIER $0147


The BCM indicated that it needed a moment, followed by an acknowledgement that the update was successful. We then request the contents of identifier $0147 so that we can see for ourselves that the change was made successfully.

. RAW PACKETS (LEFT SIDE).......EXPLANATION (RIGHT SIDE)
can1 620 [8] 03 22 01 47 00 00 00 00---------READ DATA BY IDENTIFIER: $0147
can1 504 [8] 10 0B 62 01 47 34 A0 00--------------> MULTIPLE FRAMES: INITIAL RESPONSE (11 BYTES TOTAL)
can1 620 [8] 30 00 01 00 00 00 00 00---------CONTINUE SENDING THE NEXT FRAME THEN WAIT FOR ACK
can1 504 [8] 21 00 00 00 04 00 A0 00--------------> MULTIPLE FRAMES: CONSECUTIVE FRAME WITH REMAINING DATA


................................MULTI-FRAME MESSAGE
----------" IDENTIFIER $0147: 34 A0 00 00 00 00 40 00 "

Looks like we have a permanent change! To update an identifier, all within a short window, we should:

1. Tell the BCM that a tester is present​
2. Read the identifier (and store the original in our own persistent storage)​
3. Request an extended rights diagnostic session​
4. Send the update (using CAN-TP when the entire message exceeds 8 bytes)​
5. Wait for BCM responses and a success or failure message​
6. (Optional best practice.) Re-read the identifier to validate a successful change​

As of now I believe that "isotpsend" and "isotprecv" will be capable of sending and receiving multi-frame messages, but the exact command line options still need to be figured out (as seen two messages ago). I've got a number of other challenges going on at the moment, so I don't have the time to spend on this as I'd like!

I found the following CAN-TP reference to be useful in deciphering both the message frames and their flow control commands: https://www.linkedin.com/pulse/can-tp-iso-15765-2-vivek-maurya

EDIT: Text reformatted to a better fit for the message board. Added some more verbage.
 
Last edited:

Sponsored

OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
WORKING EXAMPLE: HOW TO READ ANY BCM DATA BY IDENTIFIER

This is a working example of how to perform a complete Read Data by Identifier $0146 (CSM1) operation against the BCM (sending on 620 and listening on 504) with a 2021 Jeep Wrangler, using a Raspberry Pi using the Waveshare 2-Channel CAN adapter. It uses the isotprecv and isotpsend utilities that are included in the can-utils package.

You should begin by opening by opening two terminal windows. In the first window, you will issue a command that tells isotprecv to process (and then display) the next incoming message:

isotprecv -s 620 -d 504 -p 00:00 -P l can1
That session will block until an incoming message has been processed.

In the second window, you will issue a command (via isotpsend) which requests data from your BCM with the identifier of $0146:

echo "22 01 46" | isotpsend -s 620 -d 504 -p 00:00 -P l can1

After issuing the command, you should see the resulting data in your first window. If no data has been seen, it is possible that the vehicle's CAN bus was asleep due to inactivity. If that is the case, your first message should have already woken the CAN bus back up, and you'll just need to repeat the command a second time.

Back in the first window, we received the following response:

62 01 46 00 30 76 41 E4 A3 C7 10

"62 01 46" is a direct reply to our "22 01 46" command, except $40 has been added to the first byte in order to tell us that our command was successful. What follows after that is the actual content of identifier $0146, which is "00 30 76 41 E4 A3 C7 10". That's what we've been after. SUCCESS!!

OBSERVATIONS


Up until now, we've been able to multi-thread whatever sections of code to own own liking. Anything and everything can run at the same time. And when we're sending individual CAN messages (like button presses) and interpreting the regular CAN messages, this approach continues to work. But any direct interaction with a module will need to be structured in a way that avoids overlapping commands that have the potential to compromise one another.

NEW POSSIBILITIES

1.
Code a single-threaded gateway for all direct module interaction. Designed to keep the right responses tied to their associated commands. Prevents overlapping (potentially corrupting) messages from reaching a module.

2. Obtain a list of all valid BCM identifier numbers. Use this method against every address from $0000 to $FFFF to see which identifiers are used by the BCM and which are not. A valid identifier should yield a response starting with 62 (as seen earlier). My earlier attempt at this (using a utility called "udsoncan") seems to suggest that a module may decide to stop cooperating in the face of excessive attempts.

3. Perform a complete dump (your vehicle's baseline) of all BCM identifiers to persistent storage on your Raspberry Pi. That's your backup copy in case something goes wrong. I believe Tazer does something similar with it's marry operation.

4. Work up the nerve to perform my first Write By Identifier command that makes changes seen in the real world. Scary to do to one's own vehicle for the first time. But it's got to happen eventually.
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
Today I've been doing some light investigation into the BCM.

I've taken the time to write my own script ("rid" - read identifier) which I used to detect if any particular identifier (65536 combinations from $0000 to $FFFF) is a valid BCM identifier or not. With exceptions, this was a duplicate of the work I did earlier with CaringCaribou. I'm not using that tool today because there's the potential for it to engage in unwanted behavior (see the post where the vehicle decided it was in a crash and had SiriusGuardian call fire/ambulance). I also failed to guarantee it single-user access at the time.

Here's a list of all valid BCM identifiers on a 2021 Jeep Wrangler Unlimited Rubicon. This should be a full list of identifiers to backup before making any modificaitons. It also works as a list of places to look when you're hunting down changes:

211 Valid BCM Identifiers:
0100 0103 0104 0107 010A 010B 010D 010E 0120 0121 0122 0123 0124 0125 0126 0127 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 013A 013B 013C 013D 013E 013F 0140 0141 0142 0143 0144 0145 0146 0147 0148 0149 014A 014B 014C 014D 014E 014F 0200 0201 0202 0203 0204 0205 0206 0207 A003 A009 A010 A011 A012 A013 A015 A01A A020 A021 A023 A024 A025 A026 A027 A028 A029 A02A A02B A02C A02D A02E A02F A030 A033 A034 A035 A036 A037 A039 A03B A040 A049 A050 A051 A052 A053 A054 A056 A057 A058 A059 A060 A061 A070 A071 A072 A074 A0A0 A0B0 A0B1 A0B3 A0B4 A0B5 A0B6 A0B7 A0B9 A0C0 A0C2 A0C3 A0C4 A0DD A0DE A0DF D001 D010 D011 D014 D015 D019 D039 D03A D050 D051 D052 D060 D0A0 D0A1 D0A2 D0A3 D0A4 D0A5 D0A8 D0A9 D0AA D0AB D0AC D0AD D0AE D0AF D0B1 D0B5 D0B9 D0C0 D0C6 D0CE D1A4 D1A5 D1A6 D1A7 D1A8 D1A9 D1AA D1AB D1AC D1AD D1B1 D1B2 D1B3 D1B4 D1B5 D1B8 D1B9 D1BC D1BD D1BE D1BF D1C1 D1C2 D1C5 D1C6 F010 F011 F012 F013 F014 F100 F10B F10D F112 F122 F132 F150 F151 F153 F154 F155 F158 F15B F160 F161 F170 F171 F172 F173 F18C F190 F1A0 F1A3 F1A4 F1A5 F1F0 F1F8 F1F9

We can sometimes use a tool like JScan to help us identify and name the function performed by these identifiers (at a broad level).

From here I'm updating the script so it stores a permanent copy of any data it retreives. Then I've got one particular change I'm trying to hunt down here. That may be more difficult, since any of these locations might change for any reason. But I think I'll be able to sift out a pattern.
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
At the risk of oversharing today, here's a small piece of personal treasure.
(Please don't make me regret this.)


'0100/00 00 03 E8 '
'0103/FF '
'0104/00 '
'0107/01 '
'010A/55 AA '
'010B/00 '
'010D/00 '
'010E/00 '
'0120/01 02 '
'0121/03 3C 01 4D 16 2B 16 0F 02 0E 1D 02 02 13 2A 31 03 11 02 02 02 08 02 02 25 1E 02 02 02 14 02 0D 02 02 10 08 3B 0B 02 14 02 02 06 02 08 '
'0122/54 31 A2 5B 4C 0E 51 B8 '
'0123/00 58 66 00 25 25 00 00 '
'0124/40 57 2C 08 B5 34 43 E4 '
'0125/03 E8 10 04 0F A0 09 C4 '
'0126/00 00 00 00 00 00 00 30 '
'0127/7C 00 00 00 00 00 FF FF '
'0129/00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '
'0130/7C CD 05 61 4F E8 00 9F '
'0131/8C A9 6F CD FF 07 6F C0 '
'0132/5C 02 B6 29 09 20 10 04 '
'0133/80 00 20 00 00 00 00 00 '
'0134/10 00 F0 '
'0135/20 02 00 '
'0136/00 84 '
'0137/00 00 '
'0138/00 08 '
'0139/0C 00 '
'013A/10 10 '
'013B/00 A9 82 CC 88 88 88 44 '
'013C/FC 2E 83 3C A1 88 58 00 '
'013D/FC 00 64 FA 18 23 '
'013E/68 30 00 00 36 11 85 00 '
'013F/00 00 '
'0140/00 00 00 00 00 00 00 00 '
'0141/70 60 20 40 00 00 00 80 '
'0142/1C 13 0A 03 FF DA 0F 0F '
'0143/48 94 3F 03 E3 DA '
'0144/0C 00 '
'0145/88 8D 00 08 08 04 00 00 '
'0146/00 30 76 41 E4 A3 C7 10 '
'0147/34 80 00 00 00 00 04 00 '
'0148/00 EE EE 1C 05 00 00 00 '
'0149/00 '
'014A/40 '
'014B/23 06 '
'014C/23 00 00 00 '
'014D/04 00 40 00 00 10 40 01 '
'014E/00 00 00 00 00 01 80 00 '
'014F/80 08 00 00 00 00 00 00 '
'0200/00 04 04 04 28 00 00 04 00 00 00 00 00 '
'0201/01 01 00 00 00 00 00 00 00 00 DD 03 00 00 00 00 00 00 00 00 00 00 00 00 '
'0202/02 05 9B FF 00 00 00 00 00 00 00 00 00 00 00 00 '
'0203/05 00 AB 00 00 00 00 00 00 00 '
'0204/00 00 00 FF 00 FF 00 00 00 00 '
'0205/00 00 00 00 00 00 00 00 00 00 '
'0206/06 00 AB 00 00 00 00 00 00 00 '
'0207/00 00 00 00 00 00 00 00 00 00 '
'A003/00 00 00 00 00 00 00 00 '
'A009/03 '
'A010/7E 82 BF BF 00 00 00 '
'A011/03 B1 08 00 3C 01 ED 00 '
'A012/06 00 04 00 00 00 '
'A013/65 00 44 03 62 F0 '
'A015/8D 00 8E 00 8F 00 8F 00 '
'A01A/05 01 00 0B 01 9A '
'A020/09 30 00 '
'A021/02 '
'A023/04 02 0C F1 2F 00 '
'A024/00 00 00 00 00 00 '
'A025/00 00 00 00 00 00 '
'A026/00 00 00 00 00 00 '
'A027/00 00 00 00 00 00 00 00 '
'A028/00 00 00 00 00 00 00 00 '
'A029/00 00 00 00 00 00 00 00 '
'A02A/00 00 00 00 00 00 00 00 '
'A02B/00 00 00 00 00 '
'A02C/00 00 00 00 00 '
'A02D/00 00 00 00 00 '
'A02E/00 00 00 00 00 '
'A02F/00 01 C0 03 00 00 '
'A030/00 00 00 00 '
'A033/00 00 00 00 00 '
'A034/00 00 00 00 00 '
'A035/00 00 00 00 00 '
'A036/00 00 00 00 00 '
'A037/00 00 00 '
'A039/3F '
'A03B/83 01 00 0C 00 C0 '
'A040/00 00 00 00 00 00 '
'A049/00 00 '
'A050/3F 00 00 00 2D 01 02 02 '
'A051/80 0D 83 '
'A052/1E 46 20 01 F4 03 01 '
'A053/00 00 00 00 00 00 00 00 00 08 '
'A054/00 '
'A056/00 '
'A057/00 00 00 '
'A058/03 50 '
'A059/00 00 '
'A060/00 00 '
'A061/00 00 '
'A070/20 19 57 20 19 57 '
'A071/00 '
'A072/00 07 01 D1 93 00 20 02 05 9B 00 00 FF FF FF 00 20 02 05 9B '
'A074/00 00 00 C0 00 '
'A0A0/00 00 A6 00 00 00 '
'A0B0/00 00 '
'A0B1/00 00 00 00 00 00 00 00 '
'A0B3/01 1D C2 B2 3B 0A 46 '
'A0B4/3F 1E B8 2C 01 '
'A0B5/46 CE 43 A7 03 FF 02 '
'A0B6/26 21 52 F3 00 81 '
'A0B7/90 06 E4 CC 01 FF FF 6D '
'A0B9/04 '
'A0C0/42 35 32 31 46 35 30 31 20 31 30 2F 30 37 2F 32 30 '
'A0C2/0F 0F 00 00 00 00 '
'A0C3/FF FF FF 3F 19 3F '
'A0C4/00 '
'A0DD/8F 04 8F 04 8F 04 8C 04 8E 04 8E 0F '
'A0DE/00 '
'A0DF/00 '
'D001/00 '
'D010/00 '
'D011/00 '
'D014/00 '
'D015/00 '
'D019/00 '
'D039/00 '
'D03A/00 '
'D050/00 '
'D051/00 '
'D052/00 '
'D060/00 '
'D0A0/00 '
'D0A1/00 '
'D0A2/00 '
'D0A3/00 '
'D0A4/00 '
'D0A5/00 '
'D0A8/00 '
'D0A9/00 '
'D0AA/00 '
'D0AB/00 '
'D0AC/00 '
'D0AD/00 '
'D0AE/00 '
'D0AF/00 '
'D0B1/00 '
'D0B5/00 '
'D0B9/00 '
'D0C0/00 '
'D0C6/00 '
'D0CE/00 '
'D1A4/00 '
'D1A5/00 '
'D1A6/00 '
'D1A7/00 '
'D1A8/00 '
'D1A9/00 '
'D1AA/00 '
'D1AB/00 '
'D1AC/00 '
'D1AD/00 '
'D1B1/00 '
'D1B2/00 '
'D1B3/00 '
'D1B4/00 '
'D1B5/00 '
'D1B8/00 '
'D1B9/00 '
'D1BC/00 '
'D1BD/00 '
'D1BE/00 '
'D1BF/00 '
'D1C1/00 '
'D1C2/00 '
'D1C5/00 '
'D1C6/00 '
'F010/30 04 12 09 00 00 00 00 '
'F011/80 DF 88 46 0E 00 00 00 '
'F012/00 00 00 '
'F013/00 00 00 '
'F014/36 38 31 39 33 37 33 36 41 46 '
'F100/02 46 25 01 '
'F10B/8D 13 00 38 4E 03 2C C7 00 00 '
'F10D/08 67 B9 D1 '
'F112/36 38 34 39 36 31 36 37 41 45 '
'F122/36 38 34 39 36 31 36 39 41 45 '
'F132/36 38 34 39 36 31 36 37 41 45 '
'F150/0D 11 00 '
'F151/14 2F 50 '
'F153/11 0E 00 '
'F154/00 C6 '
'F155/00 C6 '
'F158/15 31 05 02 '
'F15B/FF FF FF FF FF FF FF FF FF FF '
'F160/02 1E 01 00 26 20 19 03 02 35 00 03 64 16 06 11 01 03 07 02 '
'F161/01 1E 01 00 26 20 19 05 02 35 00 03 64 16 06 11 01 03 07 02 '
'F170/02 00 00 00 00 00 03 00 BA 3E 80 01 01 7B 0E 00 00 00 00 00 '
'F171/01 00 00 00 00 00 03 00 BA 3E 80 01 01 7B 0E 00 00 00 00 00 '
'F172/00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '
'F173/00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '
'F18C/54 31 43 31 37 39 31 32 35 35 30 37 '
'F190/31 43 34 48 4A 58 46 4E 36 4D 57 37 35 36 35 33 30 '
'F1A0/31 43 34 48 4A 58 46 4E 36 4D 57 37 35 36 35 33 30 '
'F1A3/00 '
'F1A4/00 '
'F1A5/00 '
'F1F0/3D 64 06 0E '
'F1F8/00 00 00 00 00 00 00 00 00 00 '
'F1F9/00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
These BCM identifiers changed over the course of one ACCESSORY ON and one ENGINE RUN so they may contain engine or vehicle statistics or status information:

0129 A010 A013 A015 A01A A021 A023 A02F A037 A039 A03B A0A0 A0B1 A0B3 A0B4 A0B5 A0B6 A0B7 A0C2 A0DD D019 D060 D0B1 D0B5 D0B9 D1B1 D1BF D1C2 D1C5 F1F0

So if you're trying to hunt down where a configuration change might be permanently stored in the BCM, even though the data in these identifiers may change, they should be low on your list of suspects because they're more likely to change for unrelated reasons.

As it turns out, I didn't find the change I was looking for. I'm going to repeat this process with the EVIC Module and the Steering Wheel Module. But I've got to re-tool first. Feels good to start moving things forward again.

@redracer -- if you'd like to take the rid script for a spin, here it is. It creates a directory tree under /home/pi/modules/bcm/rid where it stores the data. You use the script by saying "rid <Identifier>" such as "rid F1F0". If your BCM is asleep, it'll be up to you to repeat your command, but it'll show the results on-screen (in addition to populating them in that directory) so you'll know what happens each time.

WARNING: I hope to make serious changes to how this script works. Don't lean on it to too hard. Let's not put it in the repository (unless a better version never appears). Please excuse the incorrect code comments. This is recycled code.

Bash:
#!/bin/bash

error() {
  echo "N/A"
  # Exit with a failure result code
  exit 1
}

initialize () {
  # 1/10th of a second from now, send the UDS query for Cabin Temperature
  # to the HVAC module, read the response, and store just the hexadecimal
  # digits we need into the $RESPONSE variable.
  #
  # NOTE: It currently replies back with cabin temperature in Fahrenheit. It
  #       is not known if there is a switch which might also make it output
  #       Celsius or not.
  ( sleep 0.1 ; \
    echo "22 $ID" | /usr/bin/isotpsend -s 620 -d 504 -p 00:00 -P l can1 ) &

  # Collect all responses fro mthe BCM.
  # After 1.5 seconds, stop collecting.
  COMMAND="timeout -s 1 2.5 /usr/bin/isotprecv -s 620 -d 504 -p 00:00 -P l can1"

  # Only look for messages which report a *successful response* to our
  # query. If we received more than one response, only use the latest
  # response. Finally, we'll isolate only the byte that we're looking for.
  RESPONSE="$( $COMMAND )"
  RID="${RESPONSE:0:2}"
  SID="22"
  SUCCESS="$( printf "%X" $(( 0x$SID + 0x40 )) )"
  OK=99

#  echo COMMAND: 22 $ID

  # [ "$RID" == "$SUCCESS" ] && OK=1 && echo "SUCCESS: ${RESPONSE:9}"
  # [ "$RID" == "7F" ]       && echo "NEGATIVE RESPONSE: ${RESPONSE}"

  if [ "$RID" == "$SUCCESS" ] ; then
    OK=0
    echo "SUCCESS"
    echo "${RESPONSE:9}"
    # DIRECTORY CHECK: /home/pi/modules/$MODULE/$OPERATION/${ID:0:2}${ID:3:2}
    if [ ! -d /home/pi/modules/$MODULE/$OPERATION/${ID:0:2}${ID:3:2} ] ; then
      mkdir /home/pi/modules/$MODULE/$OPERATION/${ID:0:2}${ID:3:2}
    fi
    touch /home/pi/modules/$MODULE/$OPERATION/${ID:0:2}${ID:3:2}/"${RESPONSE:9}"
  fi

  if [ "$RID" == "7F" ] ; then
    OK=1
    echo "NEGATIVE RESPONSE"
    echo "$RESPONSE"
  fi

  if [ "$OK" == "99" ]
    then
      echo "UNKNOWN RESPONSE"
      echo ${RESPONSE}
    fi

exit $OK

}

# MAIN CODE BEGINS HERE

MODULE=bcm
OPERATION=rid
INPUT=$( printf "%04X" 0x$@ 2>/dev/null )
if [ $? -ne 0 ]
  then
     echo "INPUT ERROR: $@"
     exit 1
  fi

ID="${INPUT:0:2} ${INPUT:2:2}"
# echo "INPUT: $INPUT   ID: $ID"

# Send our UDS request and store the response.
initialize
 
OP
OP
jmccorm

jmccorm

Well-Known Member
First Name
Josh
Joined
Sep 15, 2021
Threads
55
Messages
1,170
Reaction score
1,322
Location
Tulsa, OK
Vehicle(s)
2021 JLUR
Build Thread
Link
Occupation
Systems Engineering
It may be a stretch, but I just wanted to say HELLO! to the Jeep Hillbilly who worked on the Jeep Wrangler JL's IPC Module. I'm assuming 68492256AE is an internal-use part number (like I ran into on the BCM).

EDITING TO ASK: Might Fisi be a reference to a race car driver, by chance? Giancarlo Fisichella? Or is it the Federazione Italiana Sport Invernali?

IPCM Read by Identifier $F151:
68492256AEJEEPHLBLAEJEEPHLBLAE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE68492256AE

UPDATE: Willing to NDA for module documentation / configuration specifications / software manuals!
Sponsored

 
Last edited:
 







Top