S-Class messages refer to individual status bits on a train describer, and are a subset of (or the same as) the inputs to the train describer. C-Class messages, particularly step messages, are generated based on the content of berths and a state transition on an individual input to the train describer.
For example, if the track section between 1069 and 1071 signals south of Broxbourne transitions from 'clear' to 'occupied', and signal 1067 is showing a proceed aspect, then the TD will send a CA (step) message from 1067 to 1079 berth. When 1069 signal then changes to a danger aspect, another S-Class message will be sent out.
If the track section is configured on the TD to be output, an S-Class messages will be sent, which will usually be before the C-Class message is sent, but could be after (I'm looking at you, Havant ASC TD where the signal changes to a danger aspect and then the trains step) but likely only by a matter of seconds, if that. It depends on the software running on the TD, and there is no standard that exists which says that messages must be sent in a particular order.
Suppose there is an additional track section between 1067 and 1069 signal which has its own indication - you will get an S-Class message showing the second track section occupied but with no corresponding C-Class message. The TD covering Welwyn North is actually configured with a signal berth and two or three berths relating to the occupation of track sections behind it.
This is very low-level data you're working with, hence it's complex. It's a bit like writing assembler code and rather than writing "5 + 10", you have to load register 'A' with the value '5', the register 'B', then call the 'ADD' function, then copy the result of register 'A' back to where you want the result. Do that in Python and it's "c = a + b".
Peter