MOST bus integration into SAAB 9-3 II

Also a heads up, but PiMost address changes only take affect after a reboot!

Hey Rhys,

I’m in the car right now and now understood how to log data. You need to use “BEGIN LOGGING” instead of “BEGIN DATA LOGGING” (which stays empty), what’s the later for?

You can check the most-dump from the get functions here:

most-dump get functions connection master
[
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x3",
		"instanceID": "0x1",
		"fktID": "0x0",
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x5",
		"data": [
			"0x0",
			"0x1c",
			"0x12",
			"0xc1",
			"0x40",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

In the meantime we found out more about the “GET REGISTRY”. If I don’t click on it in the first 10s it is possible to see the messages that come in, but if you miss that you won’t be able to register again (and see the registry list). If you register within the first 10s you stay in the ring and you can send/receive messages. Have you ever experienced something like this?

Good to know that you always have to restart the PiMost to change its address. I’m a bit scared of just removing power on the PiMOST, creating a ring break and probably ending up with a bunch of errors in the car? Until now I just switch ignition off and on, but this also restarts the whole MOST ring every time. There’s a blue button on the PiMOST where I assume it’s a reset button, but has no effect in pressing that one. Or do you need to press it very long?

I’ll try to map all the devices in the ring now as you proposed.

Thank you very much!

No I’ve never seen or heard something like that, the board “registers” automatically as soon as it powers on, the get registry request is just a message to the most master.

Probably worth logging the messages you receive in those first 10 seconds, I suspect the master is expecting a certain response.

If you have auto shutdown turned on, then also turning the car off long enough that all the leds on the board turn off will also cause the new address to take affect.

Hi Rhys,

Here are the first 10 seconds (or a bit more) after ignition on

most-dump first 10s
[
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x22",
		"instanceID": "0x1",
		"fktID": "0x112",
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",
		"fBlockID": "0x22",
		"instanceID": "0x1",
		"fktID": "0x111",
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x1",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x1",
		"instanceID": "0x7",
		"fktID": "0x0",
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x0",
		"data": [
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

The mapping follows later.

yeah that’s asking you for current fblocks, nothing sinister. Interesting to see the amplifier switch happening successfully, does audio stop after that?

Hi Rhys,

Well, I guess the next step would be to dive deeper into the messages to understand what I see. Although I read several times through several documents on how these messages are built up, atm the only thing I see there are numbers. I guess after some time you get used to it… that’s why I can’t see the amplifier switch right now, but no - the music does not stop. It starts playing almost immediately after ignition on.

The mapping corresponds with the very first picture in this thread (first post):

MOST mapping
0x100 - ICM
	0x1 - 82
	0x1 - 248
	0x2 - 252
	0x2 - 253
	0x1 - NetworkMaster
	0x47 - Diagnosis
	0x1 - DebugMessages
	0x1 - Sources
	0x1 - Vehicle

0x140 - CU/PU
	0x1 - 244
	0x57 - 247
	0x57 - Diagnosis
	0x1 - MicrophoneInput

0x122 - DVD
	0x56 - 247
	0x1 - 250
	0x56 - Diagnosis

0x112 - AMP2
	0x54 - 247
	0x54 - Diagnosis
	0x3 - Amplifier

0x111 - AMP1
	0x53 - 247
	0x53 - Diagnosis
	0x2 - Amplifier

0x110 - EHU
	0x1 - 32
	0x1 - 242
	0x1 - 243
	0x51 - 247
	0x51 - Diagnosis
	0x1 - Amplifier
	0x1 - AmFmTuner
	0x2 - Telephone
	0x1 - AuxIn
	0x1 - TMCTuner

0x120 - CDCF
	0x52 - 247
	0x52 - Diagnosis
	0x4 - AudioDiskPlayer

Today there’s a big summary on general and car specific topics.
In the meantime, I had a closer look at the most messages and I’m at a level where I can read the messages from a node which follows the book. And most likely I could also manage to send a specified message to achieve the correct outcome in most cases. However, for the unknown manufacturer specific messages it’s going to be much more complicated in my opinion.
For a beginner, all the addresses and numbers can be a bit confusing. All the information you see and the different opportunities how to address a device. Where do I find the DeviceID? Is it the same as the device address? There’s the logical address and then there’s the functional address… and what is the node address high and low actually? And which address represents the number in the node list in the most explorer? All these questions crossed my mind when I tried to get started. Although I still do have many question marks, I think I could try to summarize a few things for other beginners to facilitate getting started. It will be a mix between hopefully correct information and open questions, so please feel free to comment!

Initially, I thought if you want to send a message to a certain node in the ring or if you want to duplicate a node that you would need to know it’s DeviceID. Apparently, that’s not the case! Although I still don’t know where to find the DeviceID and how it should look like, the DeviceID is optional or often not used on application level. The node position (RxTxPos = 0x400+Pos) in the ring is used only for network management or debugging.
Instead you use the logical device address (RxTxLog), which according to the book, theoretically could be dynamically assigned (RxTxLog = 0x100+Pos). The book also mentions that the logical device address “can” be statically assigned by the system designer. At least in my car, and I think also in others, thats exactly what they did (which makes sense to me, as the system can be configured in many different ways, e.g. navigation unit present yes/no).
The book mentions in one single sentence that the logical address is stored in two registers (bNAH and bNAL), with no explanation of what that exactly means. It seems obvious that these represent the “node address high” respectively “node address low”, although I do not know what the “b” stands for (byte?).
When you click on “request registry” in the most explorer, I assume the PiMOST sends a CentralRegistry “get” command without any parameter to the NetworkMaster, which in turn responds with all registry entries. One entry consists of RxTxLog, FBlockID and InstID. The datatype of RxTxLog is an “unsigned word” which means that RxTxLog consists of 2 bytes. The first byte is the node address high, the second byte is the node address low. If you convert these hex numbers to decimal, they correlate with the numbers that you see when you click on the specific device in the registry list in the most explorer (which visualizes the received message for you and replaces predefined FBlockID’s from the book with the corresponding name e.g. 0x31 → (49) → AudioDiskPlayer).

The most explorer lists all entries in the registry list structered by “FBlockID”:

  • The car specific FBlockID’s are listed as the decimal number of the hex code.
  • The predefined FBlockID’s from the book are displayed with their corresponding name as mentioned above.
Syntax Registry List
FblockID(a)									// decimal number or if acc. to book: Name
	Addr: RxTxLog(1)	inst: InstID(1)		// RxTxLog(bNAH << 8 | bNAL); InstanceID(hex)
	Addr: RxTxLog(2)	inst: InstID(2)

FblockID(b)
	Addr: RxTxLog(3)	inst: InstID(3)
	Addr: RxTxLog(4)	inst: InstID(4)
	Addr: RxTxLog(5)	inst: InstID(5)

FBlockID(c)
	Addr: ...

The first value on the next level is “Addr” which is the logical device address RxTxLog, consisting of node address high and node address low. These two 8-bit numbers combined to a 16-bit number: First the node address high (e.g. 0x1) followed by the node address low (e.g. 0x20) which would result in 0x120 in the given example.
The second value on this level is “inst”, which represents the InstID (Instances of FBlocks) is a value to differentiate two FBlock’s of the same type (e.g. two CD players). Standard value is 0x01, in requests only the wildcards 0x00 (any instance - don’t care) and 0xFF (all instances - broadcast) can be used. Again, the InstID could be dynamically assigned, but at least in my car some InstID’s (e.g. Diagnosis) seem to be statically assigned, what according to the book the system designer “can” do.
FBlockID and InstID together are called the functional address of an FBlock and the combination must be unambiguous throughout the system. According to the book a device handles the InstID for its own FBlocks, whereas the NetworkMaster is responsible for the functional address being unambiguous throughout the system and in case of such a conflict, the NetworkMaster must reset an InstID. I did not find the opportunity to statically define the InstID in the MostExplorer, however I think for the PiMost we have to let the NetworkMaster do his job when we’re duplicating a node?

Besides network management “broadcasting” (a function which e.g. can be used to receive the corresponding function blocks from all nodes during initialization) the last relevant way to address a node seems to be the GroupAddress (GA). By using a group address several devices of a MOST system can be addressed simultaneously. The group address represents the allocation to a system class, such as amplifier, Audio CD Player or digital sound processor. The initial group address is derived from the […] FBlockID of the characteristic FBlock of the node, assuming this will be the most requested (GroupAddress = 0x300+FBlockID).
In my case, I assume the three physical amplifiers could be addressed by 0x322 for example, since 0x22 is defined as FBlockID for amplifiers by the book. However, for the MostExplorer you only have to write the decimal “34” (for hex 0x22) in the corresponding field in the settings. When playing around in my car, I had the impression that setting the correct group address (besides the correct node address high and low) seems to have an impact to successfully duplicate a node. Although it seems pretty clear which group to use for an amplifier, I couldn’t tell which group address I should set for the ICM e.g. if not anything else maybe 0x02 for NetworkMaster or 0x03 for ConnectionMaster? Or for the EHU, which incorporates an amplifier the 0x22, as well as an AmFmTuner 0x40, less likely the AuxIn 0x24 and more functions - is there a way to find out the correct group address or is it not that crucial to duplicate a node?

As for now, when I try to duplicate e.g. the ICM or the EHU the system crashes every 10sec - assumingely a result of the NetworkMaster trying to get the system to work. Once it managed to create a healty ring after a few restarts when the PiMost tried to duplicate the NetworkMaster (or the ConnectionMaster? I’m not 100% sure anymore) itself and a huge amount of information came through.
Since I had this crashes in the early days as well and you @rhys_m mentioned that

I was wondering if the standard PiMost address changed over the years (in this video you say it’s 0x01 and 0x10 → so 1 and 16 in the MostExplorer Settings), or if I unintentionally changed something before I saved it for reference as the PiMost’s standard address (1 and 110 in the MostExplorer Settings). If 0x01 and 0x10 still is the PiMost’s standard address, then it would be consistent to my current observations - since this is already the EHU’s logical address as you suspected!

On the car side, I realized that I made a big mistake in the system setup, since I power the PiMost from the cigarette lighter, which only receives power when the ignition is ON (+15). When I remove the PiMost from the ring, the MOST ring continues working when ignition is OFF, something I should have known in the first place. Auto shutdown on the PiMost for the Raspberry Pi only makes sense if the PiMost will be powered continuously (+30) and can be waked up by the ICM. Sorry for this mistake, but also here I think others can learn from my mistakes. Although I powered the PiMost initally with an external power supply (but at this point in time I had no clue what I’m doing), we quickly changed to the current setup on the cigarette lighter and all the investigations in the meantime should be taken with caution. I think I never managed to create a healthy ring from the beginning, I always had to try a few times and if I remember correctly always also changed the PiMost’s address. This means I turned ignition OFF several times and the whole system turned black, since I created a ring break.
Fun fact:

And I ended up doing this multiple times already :joy:
It could be a game changer, since when I turned ignition back on, I assume that the ring always just woke up from some of error state, probably never re-initializing the system as intended? Maybe the NetworkMaster would ask for different information if I did it correctly. In my opinion it could explain the inconsistent system behavior. Guess one of the next steps will be to re-open the dashboard and find a suitable +30 spot, which can support the PiMost, the Pi, the CarlinKit dongle and the screen without risking to overload a wire.
Since you mentioned

I realized, that in my current setup after ignition OFF and ON there actually is a short interruption in the music, but if the PiMOST is removed from the ring there is no interruption. The interruption is visible in the above log “most-dump first 10 sec”:

{
		"type": "0x0",				// 0x0 = Normal message
		"sourceAddrHigh": "0x1",		// 0x01
		"sourceAddrLow": "0x10",		// 0x10 -> 0x01 & 0x10 => 0x0110 = EHU
		"fBlockID": "0x22",			// 0x22 = AudioAmplifier
		"instanceID": "0x1",			// 0x01 (default)
		"fktID": "0x112",			// 0x112 = DisConnect: By use of the method DisConnect, channels for data streaming will be disconnected
		"opType": "0xc",			// 0x0C = Method Response "Result" (Parameter "SinkNr" (unsigned byte = 1 byte), 0x01 for the first sink
		"telID": "0x0",				// no multipart message
		"telLen": "0x1",			// 0x1 = 1 => length of message is 1 byte
		"data": [
			"0x1",				// 0x1 = 1 => sink no. 1 gets disconnected
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0"				// not to consider
		]
	},
	{
		"type": "0x0",				// 0x0 = Normal message
		"sourceAddrHigh": "0x1",		// 0x01
		"sourceAddrLow": "0x10",		// 0x10 -> 0x01 & 0x10 => 0x0110 = EHU
		"fBlockID": "0x22",			// 0x22 = AudioAmplifier
		"instanceID": "0x1",			// 0x01 (default)
		"fktID": "0x111",			// 0x111 = Connect: By use of the method Connect, channels for data streaming will be connected
		"opType": "0xc",			// 0x0C = Method Response "Result" (Parameter "SinkNr" (unsigned byte = 1 byte), 0x01 for the first sink
		"telID": "0x0",				// no multipart message
		"telLen": "0x1",			// 0x1 = 1 => length of message is 1 byte
		"data": [
			"0x1",				// 0x1 = 1 => sink no. 1 gets connected
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0",				// not to consider
			"0x0"				// not to consider
		]
	},

If I understand it correctly, the source which causes this interruption is the EHU and not the ICM which I would have suspected to do that in the function of the ConnectionMaster or maybe NetworkMaster (but this might be irrelevant once I manage to get a most-dump from a correct startup?). Since music gets interrupted completely by this command I suspect that AMP1 (0x111) and sink 1 could be the settings for the amplifier in standalone mode, if I’m lucky - or what do you think? To test the standalone on my mac, would I need to do more than changing the settings and press “ALLOCATE” in the MostExplorer and play music (e.g. selecting the PiMost in the audio settings)?

Hope you find time to read through this huge message and give me some hints - otherwise I’ll try to continue the next time I’ll find time to change the PiMost’s power setup.

Lots to cover!

I think the addressing is tripping you up, when in reality (Once the documentation makes sense, as it is written quite poorly! It is quite simple) The chip itself handles all receiving of the addresses, there are multiple ways to address a device

  • Logical address, this is the most common, and this is the value that is stored within the chip itself, in the case of the pimost this is the address that you set within the settings page in most-explorer. These start with 0x0140 to 0x02FF, .
  • node position, this is just 0x400 + the node position after the master. This makes it easy to message the master, since you know it is always going to be 0x0400.
  • the dynamic mode, I haven’t really seen this used, and you are correct in that the default address of the pimost is 0x110, in hindsight this should really be something in the 0x140 - 0x2ff range, however I don’t believe it affects anything it being within the 0x100 - 0x013f range. However perhaps Saab are an outlier and use the dynamic addressing rather than logical which is what all other systems so far seem to use.
  • group address, this can be sent to all slaves within a group.
  • broadcast, two types, blocking an unblocking. These are sent to every slave on the network, typically shutdown and start up messages etc.

Now when it comes to how this works in practice, think of most-explorer as a sub service to the chip itself. Most-explorer or socketmost for that matter doesn’t care about the address. The chip itself is what handles whether a message should be received. If the message deviceId (which can be any of the above messaging types) matches inside the chip, then the message is passed to the host (most-explorer).

For the next part you are talking about instanceID. This where things now get different. The addressing mentioned above is all to do with the chip itself, so that is at the lowest level. However Fblock and instanceID are more at the software level. The host itself implements these, they are not stored in the chip in anyway. So out of the box the pimost has no fblocks and in turn no instanceIDs. This is why you usually get spammed with messages from the master of “getFblocks” type. This is the master querying what fblocks are present. The idea is the software then handles these messages and responds appropriately with any fblocks present, along with their instanceIDs.

For group addresses, the first thing to mention is you can send a message to a slave requesting what the currrent set groupID of that device is. It is handy to to be able match the pimost to them. Group address is set as just a byte, the chip automatically appends 0x3 as the upper byte. I have found no use so far as to group addresses, and they don’t seem to be used in my experience.

The default address is only used out of the box, so if you have changed it, then it will no longer be used. The address is stored in persistent memory so does not get wiped etc.

For the power, yes apologies that is probably not clear, if using in auto shutdown mode it needs to be on permanent power. It does give the benefit of booting the pi when you unlock the doors too! I have also broken the ring multiple times, infact on my test bench I do it constantly, it has never caused and issue and seems to be very fault tolerant!

I realized, that in my current setup after ignition OFF and ON there actually is a short interruption in the music, but if the PiMOST is removed from the ring there is no interruption. The interruption is visible in the above log “most-dump first 10 sec”:

This is interesting! If the audio is just a blip, then I am guessing something else is overwriting the pimosts “forced switch” I call this a forced switch because it is really doing that. It is bypassing any kind of connection master and connecting an amplifier direct to the pimost. I suspect in your case the connection master is picking up on that and switching it back to where it wants to be.

If you can do a get functions to the connection master, we can look to create a proper connection master way of doing the auto switch. I would just need to see what fblocks are present in your connection master. I also suspect that where there are multiple amplifiers in your set up, perhaps one of the shadow devices are actually the ones the need the classic “forced switch”

Hey Rhys,

Thanks a lot for your addressing summary and your answers!
OK, so for the sniffing part I do not have to care about replying with present FBlocks and InstanceID’s, if I would use the PiMost in Standalone Mode and force switch the amplifiers to it I guess I won’t need to deal with this either. I think replying correctly will be relevant if I want to replicate an existing node or “create” a new node (e.g. an additional AudioDiskPlayer) - if that’s what you mean with the idea that the software responds appropriately.

Thanks for the hint for checking the group address. A “Get” in Netblock 0x01 FktID 0x004 should work for that.

The connection master only has three FktID’s: 0x0, 0xc12, 0xc13
I guess that correlates with the message in the most-dump, but I realized, that I don’t know how the RLE-coded BitField works:

most-dump getFunctions ConnectionMaster
{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",
		"fBlockID": "0x3",
		"instanceID": "0x1",
		"fktID": "0x0",
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x5",
		"data": [
			"0x0",
			"0x1c",
			"0x12",
			"0xc1",
			"0x40",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}

In my opinion, only 0x0 the “FktIDs” are specified in the GeneralFBlock. 0xc12 and 0xc13 seem to be manufacturer specific if I’m correct. It confuses me, since the book says 0x200 BuildSyncConnection and 0x201 RemoveSyncConnection should be mandatory. Probably they did something similar, just not according to the book?

I have not yet managed to change the power setup, but I guess (or I hope) it should not affect this result.

Today, only a small update of the mapping, including node position and group addresses. It’s in a slightly different format than my previous version:

RxTxLog - NodeName			// NodePosition 0x04xx, GroupAddress 0x03yy
	FBlockID(dec)	-	FBlockID(hex)	-	Description 	*	InstID
updated MOST mapping
0x100 - ICM					// NodePosition 0x0400, GroupAddress 0x03bf
	2	-	0x02	-	NetworkMaster		*	0x1
	3	-	0x03	-	ConnectionMaster	*	0x1
	5	-	0x05	-	Vehicle				*	0x1
	6	-	0x06	-	Diagnosis			*	0x47
	7	-	0x07	-	DebugMessages		*	0x1
	16	-	0x10	-	?Sources?			*	0x1
	82	-	0x52	-	?					*	0x1
	248	-	0xf8	-	?					* 	0x1
	252	-	0xfd	-	?					*	0x2
	253	-	0xfd	-	?					*	0x2

0x140 - CU/PU				// NodePosition 0x0401, GroupAddress 0x03f4
	6	-	0x06	-	Diagnosis			*	0x57
	38	-	0x26	-	MicrophoneInput		*	0x1
	244	-	0xf4	-	?					*	0x1
	247	-	0xf7	-	?					*	0x57


0x122 - DVD					// NodePosition 0x0402, GroupAddress 0x34f2
	6	-	0x06	-	Diagnosis			*	0x56
	247	-	0xf7	-	?					*	0x56
	250	-	0xfa	-	?					*	0x1

0x112 - AMP2				// NodePosition 0x0403, GroupAddress 0x0322
	6	-	0x06	-	Diagnosis			*	0x54
	34	-	0x22	-	AudioAmplifier		*	0x3
	247	-	0xf7	-	?					*	0x54

0x111 - AMP1				// NodePosition 0x0404, GroupAddress 0x0322
	6	-	0x06	-	Diagnosis			*	0x53
	34	-	0x22	-	AudioAmplifier		*	0x2
	247	-	0xf7	-	?					*	0x53

0x110 - EHU					// NodePosition 0x0405, GroupAddress 0x0110
	6	-	0x06	-	Diagnosis			*	0x51
	32	-	0x20	-	?					*	0x1
	34	-	0x22	-	AudioAmplifier		*	0x1
	36	-	0x24	-	AuxIn				*	0x1
	64	-	0x40	-	AmFmTuner			*	0x1
	65	-	0x41	-	TMCTuner			*	0x1
	80	-	0x50	-	Telephone			*	0x2
	242	-	0xf2	-	?					*	0x1
	243	-	0xf3	-	?					*	0x1
	247	-	0xf7	-	?					*	0x51

0x120 - CDCF				// NodePosition 0x0406, GroupAddress 0x0322
	6	-	0x06	-	Diagnosis			*	0x52
	49	-	0x31	-	AudioDiskPlayer		*	0x4
	247	-	0xf7	-	?					*	0x52

What is the reason for the mix between decimal and hexadecimal fields in the MostExplorer btw, I guess you had your reasons?

I was wondering, if the sniffing also could work via notification instead of duplicating a node (what did not work on some nodes until now), or do you miss certain traffic?

Today, I had a look at AMP2 when I switched from the AmFmTuner (EHU) to AudioDiskPlayer (CDCF) and back. The EHU incorporates a physical amplifier too - probably the master amplifier? The lowest level of sound system only has this physical amplifier from the EHU)

AmFmTuner > CD:

  1. The EHU sends a Mute “ON” for SinkNr “0x01”
  2. ICM sends a DisConnect of SinkNr 0x01
  3. ICM sends a Connect of SinkNr “0x01” with a SrcDelay of “0x04” and a ChannelList with “Channel 0-3”
  4. EHU unmutes by a Mute “OFF” for sink “0x01”
most-dump AmFmTuner > CD
[

	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x1",				// Status? Bit 0 = 1 => mute on
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x112",			// DisConnect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x1",			// 1 byte
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x111",			// Connect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x6",			// 6 bytes
		"data": [
			"0x1",				// SinkNr 0x01
			"0x4",				// SrcDelay 0x04
			"0x0",				// Channel 0
			"0x1",				// Channel 1
			"0x2",				// Channel 2
			"0x3",				// Channel 3
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x0",				// Status? Bit 0 = 0 => mute off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

CD > AmFmTuner:

  1. The EHU sends a Mute “ON” for SinkNr “0x01”
  2. ICM sends a DisConnect of SinkNr 0x01
  3. ICM sends a Connect of SinkNr “0x01” with a SrcDelay of “0x03” and a ChannelList with “Channel 0-3”
  4. EHU unmutes by a Mute “OFF” for sink “0x01”
most-dump CD > AmFmTuner
[
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x1",				// Status? Bit 0 = 1 => mute on
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x112",			// DisConnect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x1",			// 1 byte
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// 0x100 ICM
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x111",			// Connect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x6",			// 6 bytes
		"data": [
			"0x1",				// SinkNr 0x01
			"0x3",				// SrcDelay 0x03
			"0x0",				// Channel 0
			"0x1",				// Channel 1
			"0x2",				// Channel 2
			"0x3",				// Channel 3
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// 0x110 EHU
		"fBlockID": "0x22",
		"instanceID": "0x3",			// 0x112 AMP2
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set (not available anymore?, but maybe "SinkNr" & "Status"?)
		"telID": "0x0",
		"telLen": "0x2",			// 2 bytes
		"data": [
			"0x1",				// SinkNr? 0x01
			"0x0",				// Status? Bit 0 = 0 => mute off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

I’m not sure if my interpretation of SrcDelay is correct, since the book says “Delay of streaming data related to the TimingMaster.” The TimingMaster should be part of the ICM. We have:
ICM > CU/PU > DVD > AMP2 > AMP1 > EHU > CDCF (> PiMost) > ICM
The only way for a 0x04 for the CDCF and a 0x03 for the EHU seems to be if AMP2 and AMP1 are counted as sinks only, whereas the other nodes are counted as sources. Is that what the SrcDelay means? Somehow I doubt it… And I guess that’s not all information you need to create a sync connection between a source and a sink, or is it? The ConnectionMaster in the ICM should start a BuildSyncConnection I guess, but it doesn’t seem to be available…

At some point in time we will find out how it works :crossed_fingers:

This is good!

The src delay is just node position. The pimost handles this by itself. It is the delay of the amount of nodes between the device and the master. In reality I have had the srcDelay wrong many times and it seems to make no difference!

In theory if you just set AMP2 parameters as the amplifier settings in most-explorer you should be able to get the audio to switch. I remember you saying there was an audio blip before, perhaps the connection master knows of the forced switch and switches the amplifier back?

It would be great to get a log of messages if you can replicate the ICM when you do those audio switches.

You can’t really sniff all traffic via notifications. Notifications would be something like the cd player saying I am now playing track 5. The sniffing is more useful to see what message was sent to the cd player to begin playing track 5 (just using the cd audio player as an example here)

Hey Rhys,

It might not be important, but if SrcDelay would be node position, 0x03 would be AMP2, and 0x04 would be AMP1. I’m still confused here.

I tried the force switch with the AMP2 setting as you proposed. Two issues occured (and an old one):

  1. With most-explorer v3.0.0-beta.3 which I installed on my mac it’s not possible to change the “amplifier” and “microphone” settings in “Standalone” mode. I can only select a preset for “JLR/Land Rover” for example and “send to dongle”. But if I want to set my car specific settings, once I click on “send to dongle” all fields get replaced by a “0”, except for one. Seems to be a bug, at least in my setup. I can only change the settings with the older v.3.0.0-beta.2

  2. Unfortunately I never managed to duplicate the ICM until now. Complete system crash every 10sec.
    Did you ever use “spy mode” which is mentioned in the book? As a a analysis tool it should be possible to be invisible in the network, but listen into the entire bus communication. Would that might be an opportunity to “duplicate” the ICM?
    For the above mentioned reason, I cannot provide a log, but I duplicated the corresponding amp instead, without much information:

most-dump force switch 0x110 0x22 0x1
[
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x12",
		"fBlockID": "0x22",
		"instanceID": "0x3",
		"fktID": "0x112",			// DisConnect
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x12",
		"fBlockID": "0x22",
		"instanceID": "0x3",
		"fktID": "0x111",			// Connect
		"opType": "0xc",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]
  1. I tried all three amplifiers with a very comparable result: The audio does not stop or switch, but the affected amplifer stops working. So if I set AMP1 for example for standalone mode and then I press “force switch”, the door speakers stop working and it sounds really bad with the tweeters only from the dashboard and the bass from the trunk. The same applies if I just wait a few secs after startup. I guess thats what the standalone mode does: After a few secs (roughly 10sec or so?) it tries to force connect the amplifiers without any interaction. When I press on “force connect” an error occurs:

    I assume that the error is in decimal, which would be 0x103 in hex. In the GeneralFBlock this would be “Source Activity” which would be missing. Which functions do you call, when you perform a force switch? Do you use the ConnectTo 0x115?

Finally, I can provide a most-dump from AMP1 for the first seconds after startup until the force switch (audible loss of AMP1) happens:

most-dump AMP1 from startup to force switch
[
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x113",			// mute
		"opType": "0x1",			// get
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// SinkNr 0 (wildcard?)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// ICM
		"fBlockID": "0x6",			// diagnosis, no spec sheet available?
		"instanceID": "0x53",
		"fktID": "0x1",
		"opType": "0x0",
		"telID": "0x0",
		"telLen": "0x5",
		"data": [
			"0x1",
			"0x1",
			"0x0",
			"0xc",
			"0x33",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// ICM
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x111",			// Connect
		"opType": "0x2",			// StartResult
		"telID": "0x0",
		"telLen": "0x6",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x4",				// SrcDelay 0x04
			"0x0",				// Channel 0
			"0x1",				// Channel 1
			"0x2",				// Channel 2
			"0x3",				// Channel 3
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0xd02",			// saab specific?
		"opType": "0x0",			// set/start
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x7",				// ?
			"0x1",				// ?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x113",			// mute
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x0",				// SinkNr 0x0 (wildcard "any instance"?)
			"0x0",				// mute Off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x202",			// Bass
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0xff",				// Bass 0xff ? (Explicit values ranges are specified in the application)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x203",			// Treble
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// Treble 1 (?)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x200",			// Balance
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// Balance 0 = left-right equal
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x204",			// Fader
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// Fader 0 = front-back equal
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0xd05",			// saab specific?
		"opType": "0x0",
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x1",				// ?
			"0x12",				// ? -> eventually something with AMP2 0x112?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP2
		"fktID": "0x113",			// Mute
		"opType": "0x1",			// get
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x0",				// SinkNr 0x0 (wildcard "any instance"?)
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0xd02",			// saab specific? (used 2nd time)
		"opType": "0x1",
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// ?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x10",		// EHU
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x113",			// Mute
		"opType": "0x0",			// set
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",				// Mute Off
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x0",			// ICM
		"fBlockID": "0xf7",			// ? AMP1, 247 present in almost every node
		"instanceID": "0x53",			// InstID 0x53
		"fktID": "0xe50",			// ? saab specific
		"opType": "0x2",			// SetGet / StartResult
		"telID": "0x0",
		"telLen": "0x2",
		"data": [
			"0xbd",				// ?
			"0x44",				// ?
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x11",		// AMP1 ?! -> guess thats the PiMost?
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x112",			// DisConnect
		"opType": "0xc",			// Result
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	},
	{
		"type": "0x0",
		"sourceAddrHigh": "0x1",
		"sourceAddrLow": "0x11",		// AMP1 ?! -> guess thats the PiMost?
		"fBlockID": "0x22",
		"instanceID": "0x2",			// AMP1
		"fktID": "0x111",			// Connect
		"opType": "0xc",			// Result
		"telID": "0x0",
		"telLen": "0x1",
		"data": [
			"0x1",				// SinkNr 0x01
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0",
			"0x0"
		]
	}
]

There are a few saab specific functions involved, as far as I can see and FBlock 0xf7 (247) gets addressed once. This FBlock exists in every node, except for the ICM. I remember you saying, that every node usually has its shadow FBlock for the amplifier. I only have the 0x22 FBlock in every node with an AMP. What if the 0xf7 would be some kind of shadow FBlock to handle all three physical amplifiers at once? It’s only weird, that every amplifier would also have this shadow FBlock - but there might be a reason for that…

Btw, somehow I could not recreate the audio blip as described earlier, as I’m writing this now - maybe that only happend after the ignition off and on, I will need to try it again next time I’m in the car!

This is a frustrating bug, let me look back into it and resolve it

The spy mode I believe is extra hardware, there is an old MOST debugging unit that physically splits the MOST signal, it is on my list to investigate to see if it is possible to do something similar

The pimost uses this sequence

  • runs an internal allocate to get give 4 bytes to stream to
  • runs a sink disconnect to the specified amplifier (0x112)
  • runs a sink connect to the specified amplifer (0x111) message includes [sink number, node posistion, byte0, byte1, byte2, byte3] which are the bytes allocated to it from the first step

It does appear that the ICM sends standard requests to the amplifier which is great, and it also does sound like the auto switching is happening however just on one amplifier. If when that one amplifier disconnects and it stops playing audio, have you tried to play audio via the pimost? I would expect it to start playing out of the speakers that went silent. If not perhaps it needs an unmute sent to it, that would be fairly easy to do by sending a manual message, and if needed I can implement to the firmware. The error you saw on the force switch is for the microphone, I think BMW needs a source activity on for it to work. Receiving that error is not an issue, just that it is not implemented on that fblock. If an manual switch needs to be sent to all amplifiers I can also get that into the firmware, I guess we just need to check it. When the system allocates, I think there is a log in the command line of the bytes that shows which bytes get allocated, you could use these to send manual disconnect/connect messages to each amplifier.

Frustrating that the system won’t let you take the address of the ICM, however to get this streaming working I really don’t think we need it.

Hey Rhys,

Thanks for looking into this bug! Ok, I did not realize that spy mode requires an extra hardware, I did not search a lot, only whats written in the book and thats not much.

OK, so basically the PiMost performs a regular source switch, like the connection master would do I assume. So if I would run 3 connect commands with all 3 amplifiers in a row, eventually with a mute upfront and an unmute afterwards that should work as well if I understood it correctly.

Thats what I expected as well, but I guess I just tried it the wrong way: Although I wanted to check if I can select the PiMost as an audio device on my mac, I forgot to do that when I was in the car. I just let the music play on the mac and tried to force connect via most-explorer - I guess thats not enough :crazy_face:

Well, for the music only it might not be necessary to duplicate the ICM. As you probably remember I wanted to integrate it completely, as if it was original. I found the steering wheel controls like skip or volume which are sent to the CD player for example, respectively to the amplifiers. I never tried until now, but I think I could also change the audio settings (bass, balance,…) that I don’t have to set them blind once I remove the original screen (which is part of the ICM). What I didn’t find yet are other settings like brightness of the whole dashboard illumination (and screen brightness), as well as the “nightpanel” button (a nice saab feature to drive in the dark: The whole cockpit turns black except for a few things like speedometer). I know that both signals come from the I-Bus to the ICM and I was hoping that they’re also translated into a MOST signal (probably Saab specific in the 0x05 “vehicle” FBlock?), such that I don’t have to connect to the CAN network as well. I guess once the basic functionality works I could do a lot if I would want to (onboard error messages or displaying the cooling fluid temperature e.g.). But let’s focus on the sound part first!

Hey hey,

Almost two weeks ago Rhys helped us to do a manual switch of all three amplifiers! Streaming music over the PiMost for the first time was amazing :star_struck: Thanks again for your help Rhys!

I managed to replicate the same procedure several times since then and it works quite well:
First we did a “force switch” on the PiMost with the settings of one amplifier. Then we manually disconnected (FktID 0x112) both other amplifiers and then connected (TktID 0x111) with a guessed SrcDelay of 0x03 and the correct assumption that the PiMost switched to Channel 4 to 7 as the car already occupied Channel 0 to 3. The FktID 0x111 requires an OpType “StartResult” (0x02) but you cannot select that in the MostExplorer from the list - but you can select “SetGet” which is 0x02 as well. I think that might be good to know for others as well!

When I do switch the amplifiers from the active CD player to the PiMost, the CD player obviously continues to play its track and changes the CD once the last track has been played. I guess thats what you do with the force switch - you just steal the sound. Since my CD changer does not follow the book strictly I guess I will need to find out how to stop the CD at its current position if I would like to continue with the “force switch”. I tested the blinker sound when the PiMost was streaming music and that worked - the car sounds seem to be on different channels which is good :sunglasses:

What I did not manage yet to accomplish was a complete manual switch of the amplifiers (without the initial force switch of the PiMost). I tried to allocate (FktID 0x101) it myself: I just tried to reply with a “result” (SourceNr, SrcDelay, ChannelList), but I guess I inserted the wrong SourceNr. Is this basically the InstID, or the node position or again something else?

I also want to investigate the SrcDelay a little bit more: It might not be that important to set it to the correct value, but with 3 amplifiers instead of 1 in theory there should be a slight difference if you do it correctly. The question might be if you could actually hear that. Let’s see if I can find out more about that.

I will also need to investigate why we did not manage to get the microphone working, but I guess we will sort that out as well at some point :crossed_fingers:

This weekend I will investigate more on how to connect the PiMost to the permanent plus (+30) in a nice way. Additionally I want to check if I can power the new screen directly from the old electronics for the screen inside the ICM and maybe even control it’s backlight over it, but thats a different story :face_with_monocle:

I’ll let you know once I made more progress :v:

2 Likes