Re: RFC 9205 - Building Protocols with HTTP

My protocol translator is running in a BSD jail with no network stack/apps. It has access to COM1, which connects an RS-485 serial bus speaking MODBUS protocol. It speaks HTTP over FastCGI via POSIX IPC. If you want to send data to a device (calibration factor to a pH sensor probe), you need 'x' permission on the file handle for that IPC socket. So, no MODBUS TCP, or HTTP behavior in jail, or ya go in the (/dev/null) hole! The following, are the values I send over MODBUS to a multifunction, submerged soil probe in an aquarium -- for this example and audience, I'm not using MODBUS syntax:



0x03 : COM1 : 0x01 : 40014 : 0013H : 0x12 : 0x02

GET example.org/fishroom1/aquarium1/{substrate|water}/temperature?scale={F|C|K}



Remember, this is an abstraction layer, we're hiding implementation details behind a uniform interface. The MODBUS response is a hex value which equals 9,427 "ohms of resistance measured across a thermistor". I default to F, so my httpd is configured to default to F (80 degrees in this case) in absence of the query string. The protocol translator is configured for the serial device in question, e.g. "has a 10K ohm = room temperature NTC thermistor circuit". Some other device might have cryogenic range, using a PTC thermistor where 10K ohms maps to absolute zero. Not in my fish room!



Speaking of abstraction, the jail has no idea its host FreeBSD is in a Zone administered by Tribblix running on a Sun T5120 (SPARC T2, 128GB, 1.8GHz 8-core NOS from bitd, Oracle EOL'd it before I ever unboxed it, talk about a rug-pull). My httpd is tightly integrated with UNIX security, 'w' allows PUT to reconfigure the translator, but 'x' is required have a POST sent out COM1 to a device...



POST example.org/fishroom2/aquarium1/water/pH?calibrate=6.8

(fishroom2 = COM2, actually COM7 on my laptop)



The pH=6.8 value comes from a handheld instrument, the translator knows how to make the MODBUS request to tell the buried sensor what its "drift" is, by sending it 0x2A8. The translator knows what to make of a MODBUS response value of 0x2A8 -- that's 680 = 6.8 pH. We want the HTTP response to say pH=6.8, not 0x2A8. And this is why we don't want to use MODBUS TCP, which sends register addresses and offsets over the Internet, exposing your infrastructure blueprint on the wire. My MODBUS traffic does not go over the WAN.



The 0x01 and 0x02 devices are in aquarium 1. The next three devices, are in aquarium 2. This logical hierarchy isn't reflected anywhere in MODBUS, it's added in by the abstraction layer (protocol translator). My httpd in the FreeBSD zone, and my translator in the jail, both parse XProc 3 config files into a nice "tree" data structure I can hit with recursive XQUERY's, e.g. there's a "/fishroom1" node which contains the particulars of the FCGI IPC socket for the protocol translator in the jail bound to COM1. All my apps are jailed like this. Legacy custom WordPress install on PHP 4.3? Do not pass Go, do not collect $200...



Once that socket's established, r-w-x permissions on its file handle lead to HTTP response codes based on the method, i.e. if you don't have 'x' your POST won't make it into the jail, you'll get 401/403. This is a uniform interface, not what's come to be known as a "REST API". MODBUS translates really well, once you understand that a 0x03 function code in an interrogation frame, is really just a GET. Not a MODBUS query POSTed to an endpoint! The resource is the register address of the sensor being interrogated, which a device has one or more of, which may have sub-resources, which are at different offsets (and lengths) within a register. With no sense of the hierarchical nature of the resources or their logical groupings.



BTW, stackless BSD jail isn't all that difficult, but you do need to globally find/replace 127.0.0.1 with 0.0.0.0 across all text files, handful of things will hang the boot waiting for loopback to initialize, but they're TCP-aware so they'll just fail and continue with all zeros. Yeah, I'm running FreeBSD on SPARC! Swap the four-disk striped-mirror ZFS with Tribblix, for the drives I installed NetBSD on, same ZFS RAID root pool can run a clone of the FreeBSD zone. L2ARC on 160GB HPE SLC SSD PCIe x4 card, I have two, one for each OS. This is a few hundreds of dollars' worth of NOS hardware resources.



Using MONT protocol, the DR (DeReference) method is GET, RE (REsolve) is HEAD, there is no POST equivalent, PA (tch) implements DARCS, and if I need to offline a pH probe to calibrate it to a reference standard solution I use INhibit and ReStore -- the translator does chmod 0000 on IN and chmod 0764 (or whatnot) on RS. The montd responds 503 (equivalent) if it sees 0000 on the referenced file handle, unless you sent the IN request. But, this is HTTP so we just use POST for everything and introspect deeper than a log file to get a sense of what the application is doing.



INHIBIT and RESTORE methods are there in the deep history of HTTP, can't remember where, just that I ripped 'em off for my in-house protocol. Surfacing to this list, is on-topic particularly when it comes to fleshing out the pros and cons of vendor-specific methods in RFC 9205. They could also trigger a server to respond 402 if the chmod is 0740, in my way of doing things, failed payment for webhosting. Very specific semantics of temporarily off-lining a resource for maintenance, recalibration, etc. which can be spelled out in the message entity of various 4xx/5xx possibilities.


-Eric

Received on Friday, 1 March 2024 22:25:13 UTC