It is 1) variant a. i.e. the untagged stuff.
The protocol itself is third-party and I implemented a tranceiver that runs in a separate thread and does the I/O on the serial port including the handling of so-called callbacks (i.e. unsolicited responses) 1.
The host with the communicate()
interface is responsible for handling "atomic" send-and-reply transactions for which I (think I) need that interface and communicates with the transceiver via channels.