Vehicle Stream Framing And Dispatch#
The companion’s VehicleMessenger initiates a TCP connection to configured role
gateway:57032. It is not a companion listener on that port. The connection
carries publications in both directions, independently of which side initiated
TCP. The separate collector uses gateway:57042 and its own catalogue; the
sixteen-byte SOME/IP RPC stack is a different protocol.
This contract belongs to Y317 / v15.3.3-r1, build
2018-03-16T21:23:48Z. It does not establish the bearer, port or compatible
catalogue of MCU image A. Earlier MCU addresses in the function table are scoped
separately and are not a version-matched companion peer.
Complete function catalogue: 420 records, 417 channel/ID keys.
Payload schemas: 135 XML models plus 12 nested models.
Subscriptions: local topic associations and semantic limits.
Connector And Lifecycle#
pubsub.broker.d.h owns VehicleMessenger; pubsub.broker.d.f is the connector
and pubsub.broker.d.g the model/codec manager. h.a(Context) loads
VehicleMessages.xml and reads vehicleConnector. The code fallback is
localhost:12345, not the configured gateway endpoint. The collector instead
reads dataCollectorConnector, fallback localhost:54321, and loads
DataCollectorMessages.xml through pubsub.broker.d.a.
f$a splits the endpoint at its first colon and parses the suffix as an integer;
this is not a general URI or bracketed-IPv6 parser. f$a.run() opens a plain
java.net.Socket, with a 10-second connect timeout and no explicit local bind,
TLS, credential exchange or application handshake. No frame-read timeout is set.
Failed connects close the socket and retry after 10 seconds until interrupted.
After a successful stream handoff the connector thread returns; it is not a
heartbeat monitor. Connector-open exceptions have a separate 10-second delayed
retry. Shutdown joins connector and I/O threads for up to 30 seconds each.
h$1 follows PowerManager.VEHICLE_SYSTEM: resume opens the connector; pause
closes it. Local handler h$b cases 1…7 represent ingress dispatch, open,
close/reopen, close, stream availability, unavailability and power recovery,
respectively. These are local handler numbers, not wire IDs. Availability for
Vehicle/#, Logging/#, Diagnostics/# and GatewaySystem/# is a local broker
notification, not a network subscription or ACL.
Frame Layout#
Offset |
Bytes |
Encoding |
Meaning |
|---|---|---|---|
0 |
2 |
u16BE |
Channel |
2 |
2 |
u16BE |
Message ID within channel |
4 |
2 |
u16BE |
Payload byte count N |
6 |
N |
Model-specific |
Payload, at most 250 bytes |
Full extent is 6+N, at most 256 bytes. There is no service, instance, client/session, type, return code, sender identity, generic sequence, nonce, authentication tag or CRC in the header. State/get/request distinctions belong to topics/models, not header flags. There is no generic continuation bit, subscribe/unsubscribe, ACK/NACK, ping, discovery or method-invocation mechanism. Named models may implement application-level exchanges.
h$c.run() allocates a big-endian 256-byte buffer and reads exactly six header
bytes followed by exactly N body bytes. Short reads accumulate; multiple frames
in a TCP segment remain separate. TCP packet boundaries are irrelevant. EOF,
including a partial header/body, raises an I/O error. A zero-byte read retries
without backoff or a deadline. Outer N=0 is syntactically accepted but is not
valid for every model, notably the one-byte Null model.
An in-range false length can consume subsequent frame bytes. No delimiter or magic/version scan restores alignment. Oversize N>250 exits before draining its body. Partial frames have no general read deadline in this path.
Lookup And Duplicate IDs#
Channel.fromId recognizes 13 enum channels, but the numeric vehicle catalogue
populates only Vehicle=0, Logging=2, Diagnostics=3, GatewaySystem=10 and
BasebandSystem=12. Other recognized enum channels do not imply vehicle-catalogue
membership or permitted cloud ingress.
The reader converts the ID to a decimal string and calls
pubsub.a.a.c(channel,id). g.b(channel,name) resolves an explicit binder or
derives binders.someip.*Binder from a registered models.* class. Serializer
lookup g.a(channel,name) is analogous. Reflection failures are cached as null.
The peer supplies integers and model bytes, not a reflection class name.
pubsub.a.a.h(String,String) loads records in document order.
pubsub.a.a$c.a(pubsub.a.a$a) inserts an ID only when absent: first-wins.
The full-topic index independently retains both distinct topics. Its separate
schema-to-name map is last-wins and does not change inbound ID lookup.
Vehicle ID |
Retained Inbound Name / Model |
Later Inbound-Shadowed Topic / Model |
|---|---|---|
6014 / 0x177E |
OnlineUpdateConfirmSuccess / UpdateId |
OnlineUpdateVehicleState / UInt8 |
6015 / 0x177F |
OnlineUpdateConfirmError / UpdateId |
OnlineUpdateClusterRequest / UInt8 |
6016 / 0x1780 |
OnlineUpdateConfirmWithdrawal / UpdateId |
OnlineUpdateCarWakeupRequest / Bool |
Reverse lookup g.d(channel,name) -> pubsub.a.a.n(fullTopic) preserves both
names’ shared ID. There is no payload-type fallback to the later topic. All
420 records, including the three shadowed records, remain in the
catalogue; inbound lookup has 417 keys. This is the behavior of this core
loading this catalogue order, not proof of native-peer interpretation or a
deployed OTA failure.
Publication And Gates#
h$c reader -> channel/ID lookup -> model binder -> queued ingress
-> h.b(String,String,Object) -> ordered receive interceptors
-> MessageBrokerService$1.b(String,Object,Bundle)
-> exact-topic subscribers -> application/state listener
Messenger.publish -> broker Topic.matches messenger routing -> h$2.a(...)
-> outbound interceptors -> active/wakeup gate -> synchronized FIFO
-> h$d writer -> reverse ID and serializer -> six-byte header -> write/flush
An interceptor returning false consumes a publication and short-circuits the chain, potentially after publishing a transformed or assembled model. Receive decoding alone does not establish an application subscription or authorization. Some interceptors compare names without checking the channel; enum recognition is not an ACL.
Inactive non-wakeup output reports local failure. Wakeup-marked output requests
power activation and queues. The FIFO has no explicit capacity bound in these
methods; teardown does not explicitly clear its contents, codec caches or all
interceptor state. A Java-null object becomes a default one-byte Null model.
Successful write/flush removes the FIFO head and can report local result 0, not peer receipt or execution. Interceptor consumption can also report result 0 without a frame. Invalid channel output has a log/drop branch reaching a common result-0 callback. Invalid IDs, serializer errors and oversize serialized models normally remove the record and report failure. Serialization precedes the size check, so backing-array exceptions may occur first.
Write I/O failure terminates the writer without removing its current FIFO head. Later resumption can leave delivery ambiguous if bytes already reached the peer; there is no generic exactly-once guarantee.
Errors And Recovery#
Condition |
Behavior |
|---|---|
N>250 or header/body I/O error |
Terminate reader and post local handler case 7 |
Unknown channel or ID |
Consume body, discard frame, continue |
Missing binder, null model or caught BinderException |
Discard frame, continue |
Ordinary reader-loop termination |
Publish local Vehicle OperationState(0,0), not a wire ACK |
Uncaught error outside protected scopes |
No universal case-7 guarantee |
Case 7 marks an active messenger inactive, closes streams/connector, and calls
coreservices.power.b.b((short)1) through the systemwide power manager to
PowerManagerService$c.b(). This cancels lease timers, clears leases, conditionally
releases a wake lock and requests state-machine transitions. It does not itself
immediately reconnect TCP. A later lifecycle resume can reopen the connector;
recovery timing, physical reset effects and whole-ECU reset are unresolved.
Integrity And Semantic Limits#
The plain connector and outer framing provide no TLS, peer credentials, cryptographic frame integrity or replay control. The effective boundary is the established TCP connection and surrounding network/configuration policy, not a frame-supplied sender identity. Port knowledge or source-address spoofing alone does not give control of an established stream. Application-specific signatures and MobileKey data are separate from outer-frame protection.
Binder consumption, array transaction correlation, wakeup flags, state booleans, active subscriptions and cryptographic license acceptance are separate gates. Current endpoints, enabled applications, network policy, downstream operation authorization and native-peer compatibility remain unresolved. The core’s 599 PubSubId fields across 45 groups include internal/backend symbols and are not additional numeric vehicle functions.
Receive Interceptors#
Order |
Binding |
Role |
Chunk Bounds |
|---|---|---|---|
1 |
|
Logging LOG_MESSAGE -> Log.println, consume |
not specified |
2 |
|
LOCATION provider filter |
not specified |
3 |
|
LOCATION/SPEED PearlChain construction |
not specified |
4 |
|
configuration extraction; actual values excluded |
not specified |
5 |
|
Obdc DATA_GROUP_DATAGRAM assembly |
not specified |
6 |
|
HV timer list/update |
not specified |
7 |
|
166-entry whitelist cache and realtime TIME query |
not specified |
8 |
|
MobileKey DATA_EXCHANGE_RESULT assembly |
not specified |
9 |
|
Diagnostics DATASET_ADAPTION assembly |
not specified |
10 |
|
FoD FUNCTION_UPDATE incremental/full assembly |
not specified |
11 |
|
coding filter while VTS license active |
not specified |
12 |
|
ChallengeList array get/ack |
not specified |
13 |
|
ServiceList array get/set/ack |
not specified |
14 |
|
UserList array get/ack |
not specified |
15 |
|
FoD List array get/ack |
not specified |
16 |
|
steering-dependent passenger-side mapping |
not specified |
Outbound Interceptors#
Order |
Binding |
Role |
Chunk Bounds |
|---|---|---|---|
1 |
|
SET_HV_CHARGING_TIMERS |
not specified |
2 |
|
Diagnostics RESPONSE segmentation |
not specified |
3 |
|
MobileKey VTAN/PROTECTED_FUNCTION_LOGIN segmentation |
data_chunk_max=234 |
4 |
|
OnlineUpdate UPDATE_INFO segmentation |
first_text_chunk_max=211, subsequent_text_chunk_max=244 |
5 |
|
VTS license tracking |
not specified |
6 |
|
FoD ACTIVATION_REQUEST segmentation |
data_chunk_max=238 |
7 |
|
ChallengeList cache/change |
not specified |
8 |
|
ServiceList cache/change |
not specified |
9 |
|
UserList cache/change |
not specified |
10 |
|
internal FoD full List to array cache |
not specified |
11 |
|
Obdc ISO_TP_MESSAGE segmentation |
not specified |
12 |
|
AuthenticTime response/signature segmentation |
signature_chunk_max=244 |