The OSI 7 Layer Model and FreeDiag.
freediag and OSI Layers
If you don't know for sure what the "OSI Layers" are, you can google "OSI layers" and read around, because most OSs and comms systems use it in some form or another.
I would say that layers 1 and 2 are universally present and recognisable in all information systems - from layer 3 up, things get more blurred and dificult to distinguish. There is always a Layer 7 (the Application), which (in a poorer design) may implement some of the features of lower layers...
As a quick example, take your common Web browsing (HTML over HTTP over TCP/IP over Ethernet):
Please note that what one layer considers to be a Packet, another layer may see as just part of a Packet - TCP/IP Datagrams can span more than one Ethernet Packet, and an FTP file can be much larger than a TCP/IP datagram.... it depends on the size of each layer's packets.
Now let's look at OBD2/freediag layers.
Our little project is not at all simple, because it tries to deal with a lot of different physical interfaces, which can implement different sets of features. The more expensive ones ("active" or "smart") have their own "intelligence" and therefore can implement features from one, two, or more OSI layers...
Not only that, but this project also aims higher than the simpler OBD applications: it tries to convert the simple Tester/ECU link into a full-blown network stack, with multiple interface connections and protocol sessions simultaneously on the same tester machine (the PC).
The only way to explain each layer separately and completely, is to describe the code for those interfaces I call the "passive" ones ("dumb", or without processors). Their very simple hardware is easilly classified as Layer 1 (all they do is change voltages and currents, because cars use 12V ports, and laptops use 5V ports (mostly), and you don't want car spikes to fry your laptop ports), and this means they don't do any processing of the data coming through. So this kind of interface has to use 100% of the L1 code in freediag.
But extrapolating for the "smart" interfaces is easy: they do by hardware(HW) some of the stuff we otherwise do by software(SW), and that's why each interface driver implementation file (diag_l0_*.c) will state which features the interface HW implements on its own. From there, all the protocol layers above it can access those flags and choose between actually executing each protocol feature, or expecting/requesting the interface to do it automatically. That's the difference between "smart" and "dumb" in freediag... ;) This has a number of impacts on the code, like the execution of message framing and timeouts - some "smart" interfaces will handle them automatically (and therefore take longer to respond), so freediag can't apply the strict protocol timing parameters when talking to them - hence there are "relaxed" timeouts for talking to "smart" interfaces.
(Personally, I don't like "active" or "smart" interfaces because only their manufacturers can fully support them, and we depend on their good will and information to implement their drivers. But I have to admit they come in handy for most people because they take care of the icky details of slow initialization, checksums, timeouts, etc.)
I would expect to find a one-to-one correspondence between OSI layers and the freediag layers (diag_l0_*, diag_l1_*, diag_l3_*, etc.). Unfortunately, I don't think this is the case.... For starters, OSI layers begin counting from 1, and freediag counts from 0... (professional hazard amongst the C coders, I think...;). Anyway, the original authors took some degree of liberty while naming all the stuff they managed into the code. I don't blame them, it IS a confusing task to homogeneise different interfaces from different manufacturers, and different protocols from ISO and SAE, and wanting to build over that... And the OSI layers can be quite tiresome, too...
Looking at freediag specifically (this is what I THINK - so correct me if I'm wrong):
- Layer 1 (PHY) - Composed by:
- Hardware: OBD2 plug + Passive or Smart Interface + PC Serial Port (usually 16550 controller chip); We don't use its electrical handshaking capabilities (except to power some smart interfaces through DTR/RTS ;)
- Software(low): Serial Port device driver - recognizes 7/8-bit "packets" known as bytes or characters ;). There is no addressing (Peer-2-Peer). We don't use its error control capabilities (parity bits); freediag's hook into the serial port is "diag_tty.c".
- Software(high): The "diag_l0_*.c" interface driver files contain functions that emulate timings and behaviours that should normally be implemented in HW;
- Layer 2 (LNK) - Composed by more than one freediag layer.
The "diag_l1.c" file manages:
- Physical interface addresses (for more than one interface/port on the same machine, like Ethernet's MAC addresses);
- Physical interface flags (device capabilities, like Ethernet NIC parameters);
- Validation of half-duplex transmission with echo (on passive interfaces);
- Inter-Byte gap timing (removed for smart interfaces, applied for passive interfaces);
The "diag_l2.c" file manages (with help from the "diag_l2_*.c" files):
- Transparent calls to all the supported link protocols.
- Associations between link protocols and interface devices;
- Link protocol specific timeouts and delays;
- Framing: Building of link protocol messages from interface packets - i.e., joining lose bytes into a full diagnostic telegram;
- Validation of message Headers and CRC/Checksum;
- Addressing (to distinguish between different ECUs in the car network);
The different "diag_l2_*.c" files implement:
- Official International Standard Protocols: "_iso9141.c" (the father of OBD) / "_iso14230.c" (a.k.a. "Keyword Protocol 2000") / "_saej1850.c" (an all-american favorite) / "_can.c" (Controller Area Network - not yet used for OBD; just inside the car network itself);
- Extra "proprietary protocols": /"_raw.c" (a debug pass-through?) / "_vag.c" (for Volkwagen/Audi) / "_mb1.c" (for Mercedes gearbox or something).
- Layer 3 (NET) - Unlike the TCP/IP protocol suite, the ISO-9141, ISO-14230, and SAE-J1850 protocols do not define this layer.
- Layer 4 (TRN) - Unlike the TCP/IP protocol suite, the ISO-9141, ISO-14230, and SAE-J1850 protocols do not define this layer.
- Layer 5 (SES) - Session initiation/termination. Although ISO/SAE state that this layer is not defined by their standards for the OBD applications, I think that's not true... they define it in their docs, alright, but as part of Layer 2 - the link protocol session. The car ECUs normally require a specific initialization to start a communication session, and then "keepalive" packets may be required to maintain it open. To end the session, it may be needed a timeout or a specific message. This session control is implemented in "diag_l3.c", where it is started, stopped, and checked for timeouts. The protocol timeout checks are triggered by an OS timer that is configured in "diag_os.c", and the timeout behaviour is defined by the specific "diag_l3_*.c" files.
- Layer 6 (PRE) - Data interpretation/presentation. Again, ISO/SAE state that they don't define this layer... I think they do define it, they just bundle it up in Layer 7 (APP). This knowledge about the valid message payload contents is stored by the "diag_l3_*.c" files. Unfortunately, in freediag, this knowledge is yet incomplete and somewhat garbled... but with a little work, we'll sort it out.
- "_saej1979.c": Presentation of the message data like a SAE-J1979 Scantool diagnostic application (the official OBD2 standard); This file is still a little "attached" to SAE-J1850, by virtue of one of the original authors... but it also covers the iso9141 part, which is common to all protocols.
- "_iso14230.c": Presentation of the message data like a KWP2000 (ISO-14230) Scantool (minus iso9141 part);
- "_vag.c": same thing, but for the VAGtool application suite - and clearly incomplete;
- Layer 7 (APP) - Finally, we get to the application level - the SAE-J1979 Diagnostic ScanTool. It is implemented in the files:
- "scantool_cli.c": command line interface with general application flow, auxiliary data conversion, pretty formatting, etc;
- "scantool.c": main program code, with full OBD2 response decoders and J1979 Scantool application implementation (auto-discovery of OBD2 in car);
- "diag_dtc.c": Diagnostic Trouble Code interpretation;
- and the remaining "scantool_*.c" files, which implement a few other commands we can issue inside the application.
I hope I'm helping people understand the code, and not confusing them further! :)
For further enlightenment, read the source code!