SOME/IP
The Sd state machines
Lessons 12 to 15 told the Service Discovery behaviour as stories. Here are the same rules as the three state machines of the specification: one for each service instance a server offers, one for each service instance a client uses, and one for each eventgroup on the server.
Server: Not Ready and Ready
Sd keeps one server state machine per service instance it offers. The machine is Not Ready (the service instance is not offered) until two things hold: ifstatus is up_and_configured (the network interface is up and its IP address is assigned), and service-status is up (BswM has set the server service instance to AVAILABLE). Then it is Ready (the service instance is offered), which holds the three phases from lesson 12: Initial Wait Phase, Repetition Phase and Main Phase, each with one timer.
REPETITIONS_MAX is 0. Every arrow inside Ready that fires on "timer expired" sends an OfferService.| In state | Event | Action and next state |
|---|---|---|
| Not Ready | ifstatus up_and_configured and service-status up | Initial Wait Phase; timer = random in [INITIAL_DELAY_MIN, INITIAL_DELAY_MAX]; open the socket connections, enable the routing group for methods |
| Initial Wait Phase | timer expired | send OfferService; Repetition Phase with run = 0 (or Main Phase if REPETITIONS_MAX = 0) |
| Initial Wait Phase | FindService received | ignored |
| Repetition Phase | timer expired | send OfferService, run + 1; after REPETITIONS_MAX offers go to the Main Phase |
| Repetition Phase, Main Phase | FindService received | answer with an OfferService after the REQUEST_RESPONSE_DELAY; counter and timer unchanged |
| Main Phase | timer expired | send OfferService, restart the timer (only if CYCLIC_OFFER_DELAY is not 0) |
| Repetition Phase, Main Phase | service-status down | send StopOfferService, release all event handlers, disable the routing groups; Not Ready |
| any phase | ifstatus no longer up_and_configured | clear all timers; Not Ready |
Protocol and module disagree in one place. The protocol's state machine sends an OfferService as soon as the Main Phase is entered, while its own text and the Sd module specification say the first OfferService of the Main Phase comes one CYCLIC_OFFER_DELAY later. The course follows the module specification. The Sd module also counts the Repetition Phase so that the REPETITIONS_MAX-th repetition OfferService ends it at once.
Client: Not Requested, Searching for Service, Main Phase
The client machine has more states, because a client listens even when it does not need the service. Two big groups: Not Requested (BswM has not requested the service instance, but offers are still noted) and the requested states. Inside Not Requested the client is in Service Not Seen (no valid OfferService known) or Service Seen (a valid OfferService known, its TTL running). Once the service instance is REQUESTED, the client is in Searching for Service (sending FindService in an Initial Wait Phase and a Repetition Phase), in the Main Phase with Service Ready (the service is offered and used) or Stopped (the server sent a StopOfferService), or in Requested_but_not_ready (requested, but ifstatus is not up_and_configured).
OfferService saves the whole search, and an expired TTL restarts it. Not shown: RELEASED in any requested state leads back to Not Requested, and ifstatus going down parks a requested service in Requested_but_not_ready.| In state | Event | Action and next state |
|---|---|---|
| Service Not Seen | OfferService received | start the TTL timer; Service Seen |
| Service Seen | TTL expired, StopOfferService received, ifstatus down | Service Not Seen |
| Service Not Seen | REQUESTED, ifstatus up_and_configured | Initial Wait Phase; timer = random in [INITIAL_DELAY_MIN, INITIAL_DELAY_MAX] |
| Service Not Seen | REQUESTED, ifstatus not up_and_configured | Requested_but_not_ready; when ifstatus becomes up_and_configured go to the Initial Wait Phase |
| Service Seen | REQUESTED | Service Ready: open the socket connections, enable the routing groups, report AVAILABLE, send SubscribeEventgroup |
| Initial Wait Phase | timer expired | send FindService; Repetition Phase (or Stopped if REPETITIONS_MAX = 0) |
| Repetition Phase | timer expired | send FindService, run + 1, double the wait; after REPETITIONS_MAX FindService entries: Stopped |
| Initial Wait Phase, Repetition Phase, Stopped | OfferService received | cancel the timer, start the TTL timer; Service Ready |
| Service Ready | OfferService received | restart the TTL timer; send SubscribeEventgroup for each wanted eventgroup |
| Repetition Phase, Service Ready | StopOfferService received | cancel the timers, report DOWN; Stopped (no FindService is sent) |
| Service Ready | TTL expired | report DOWN; Initial Wait Phase (search again) |
| Service Ready | RELEASED | send StopSubscribeEventgroup, report DOWN; Service Seen |
| any requested state | ifstatus down | cancel the timers, report DOWN; Requested_but_not_ready |
Read the protocol text of this machine with care. In R20-11 the textual list of client transitions contains slips: the entry into Requested_but_not_ready is written as "Service Not Requested", the move from Service Ready to Stopped is triggered by "receive(OfferService)" where StopOfferService is meant, the move back to Searching for Service is guarded by "ifstatus != up_and_configured" where "==" is meant, and a few transitions appear twice. The table above follows the evident intent and the Sd module specification (lesson 13).
Server eventgroup: counting subscribers
For every eventgroup it offers (its event handler) the server keeps a small machine. While the service is Service Down (not offered) the machine does nothing. While it is Service Up (offered), it moves between Not Subscribed (no subscriber) and Subscribed (at least one), counts the subscriptions in the SubscriptionCounter (the number of current subscribers) and switches routing groups on and off with enableTxRoutingGroup and disableTxRoutingGroup (start or stop sending the events of this eventgroup). The plain unicast and multicast machines are special cases of the adaptive one, which compares the counter with the UnicastLimit (the multicast threshold minus one).
SubscribeEventgroup from a new client and down with each StopSubscribeEventgroup or expired TTL. The UnicastLimit is the multicast threshold minus one; the threshold 0 keeps the machine in its unicast half for ever.| Machine | Behaviour |
|---|---|
| Unicast eventgroup | Not Subscribed → Subscribed on the first SubscribeEventgroup: enable the events (enableTxRoutingGroup), send SubscribeEventgroupAck. Further SubscribeEventgroup entries: SubscribeEventgroupAck. StopSubscribeEventgroup or TTL expiry with counter 1: disable the events. |
| Multicast eventgroup | Same states; every SubscribeEventgroup increments the SubscriptionCounter and is acknowledged; every StopSubscribeEventgroup or TTL expiry decrements it; at 0 the events are disabled. |
| Adaptive (unicast to multicast) | Unicast while SubscriptionCounter ≤ UnicastLimit; the SubscribeEventgroup that makes it exceed the limit switches to multicast; the StopSubscribeEventgroup or TTL expiry that brings it back to UnicastLimit switches back to unicast. |
| All three | Initial events of fields are sent after the SubscribeEventgroupAck, by unicast, to the new subscriber only. Service down: back to Service Down, all subscriptions gone. |
Try it
Pick a state machine and feed it events. The current state is highlighted; the log shows the actions. Settings here: REPETITIONS_MAX = 3; for the eventgroup machine, choose the multicast threshold.
Things to notice. In the server machine a FindService never moves the state, it only produces an extra OfferService, and in the Initial Wait Phase not even that. In the client machine an OfferService leads to Service Ready from almost anywhere, while a StopOfferService leads to Stopped, where no FindService is sent. In the eventgroup machine with multicast threshold 3, the third SubscribeEventgroup switches to multicast and the next StopSubscribeEventgroup switches back.
Check yourself optional
New terms in this lesson
| Term | Meaning |
|---|---|
| Not Ready / Ready | The two top states of the SD server state machine: service instance not offered / offered (with the Initial Wait, Repetition and Main Phase inside) |
ifstatus up_and_configured | The network interface is up and its IP address is assigned |
service-status up / down | BswM has set the server service instance to AVAILABLE / DOWN |
| Not Requested | Client state group: BswM has not requested the service instance; offers are still noted |
| Service Not Seen / Service Seen | Inside Not Requested: no valid OfferService known / one known, its TTL running |
| Searching for Service | Client state group: the Initial Wait and Repetition Phase, sending FindService |
| Service Ready / Stopped | Client states in the Main Phase: the service is offered and used / the server sent StopOfferService; no FindService is sent |
| Requested_but_not_ready | Client state: requested, but ifstatus is not up_and_configured |
| Service Down / Service Up | Top states of the server eventgroup state machine: the service instance is not offered / offered |
| Not Subscribed / Subscribed | Inside Service Up: no subscriber / at least one |
SubscriptionCounter | Number of current subscribers of the eventgroup |
UnicastLimit | Multicast threshold minus one: up to this many subscribers the events go by unicast |
enableTxRoutingGroup / disableTxRoutingGroup | Action of the eventgroup state machines: start or stop sending the events of this eventgroup |
Source: SOME/IP-SD Protocol Specification, R20-11, sections 4.1.4.1, 4.1.4.4 (server and client machines) and 4.1.6 (publish/subscribe machines); Service Discovery, R20-11, sections 7.6 and 7.7.