ARES-SDK/protocols/phase protocol.txt

215 lines
9.0 KiB
Plaintext

PHASE PROTOCOL VERSION 1.1
2024-06-25
The following is a general-purpose read/write protocol for data storage systems in Second Life. It originated in Nanite Systems ARES 0.4.4. Importantly, it is opaque enough to handle almost any underlying storage system, from read-only notecard access to a full-access web server.
Data sizes can be specified in either bytes or pages. A page is notionally 1024 bytes, but can be incomplete (known as a "ragged" page.) This size fits in a single SL channel message, and in a single line of a notecard.
Except where otherwise specified, each control message consists of the format:
<handle> <command> <argument> <argument> <argument> ...
Where <handle> is an arbitrary string (typically a UUID) generated by the OS for each interaction, <command> is one of:
connect disconnect access size read write ready delete deleted new update close
and the <argument>s are <command>-specific.
The main control channel is 1608011905, or "phase" in character ordinals (with "a" = 01). Side channels are sometimes created for sending data, in both directions.
READING CHANNELS
For efficiency, whenever the system wants to read a file from the storage device, it opens a listener and passes the channel number to the storage device, asking the storage device to send data there. This is called a reading channel. Messages sent on the reading channel are unadorned, and it is entirely up to the system to close the channel when it is no longer required. This allows data to be read in chunks of up to 1024 bytes (or one notecard line) without splitting.
If reading from the given filename is not possible, the storage device may reject the request by sending "stat none" (meaning that the file is not in a readable format, or does not exist) or "denied" (meaning that the system does not have adequate permissions.)
WRITING CHANNELS
Whenever the system wants to write to a file, it informs the storage device (with a "write" or "append" message), which includes a channel number as one of its arguments. The storage device then opens a listener on that channel number and announces that it is prepared to receive text with the "ready" message. All text received from the system should then be written by the storage device to the indicated file.
The system will announce it is done sending data by sending a "close" message.
If writing to the given filename is not possible, the storage device may reject the request by sending "stat none" (meaning that the file could not be created/accessed) or "denied" (meaning that the system does not have adequate permissions.)
DIRECTORY FORMAT
The phase directory format is simply a list of filenames, separated by 0x0a ('\n'). This is the same as the obsolete wf0 and wf1 formats.
MESSAGES
<handle> connect <mode>
system -> storage
where <mode> is one of: ro rd rw
Initiates a connection with the specified access level. The storage device should respond with an "access" command (below), and store the host UUID and granted level of permission for future reference. The modes are defined as "read only" (ro), "read and delete" (rd), or "full access" (rw).
At this point, the storage device should also check through all existing connections and confirm that the hosts involved still exist (that is, llGetOwnerKey(id) != id). Failing that, delete those connections and close any writing channels (described earlier) associated with them.
However, if <handle> is NULL_KEY, the system is simply pinging and does not want to alter the state of any existing connections. A storage device that wants to be seen by the inquiring party (e.g. for public use) should respond with a "version" message; otherwise, no response is required.
<handle> version <version> <label>
storage -> system
Sent in response to "connect" when <handle> is NULL_KEY. The reply handle should also be NULL_KEY.
<version> is an implementation-specific string up to 64 characters in length with no spaces, e.g. "ARES-_fs-0.4.4"
<label> is a human-readable (space-containing) descriptor of the volume.
<handle> reset
storage -> system
The storage device has been rebooted and has lost its active connections list. Any system that recognizes the storage device's channel and UUID should re-send the "connect" message (above).
The standard implementation of phase sends this message publicly using llRegionSay(). Implementations may alternatively send it selectively, e.g. to the owning avatar (and therefore all its attachments) or to a predetermined whitelist of UUIDs.
<handle> access <mode> <unit> <label>
storage -> system
where <mode> is one of: ro rd rw
Responds to a request to a "connect" command (above). The storage device should indicate the level of access it is willing/capable of giving the system. It should also store the host UUID and granted level of permission for future reference. The useful modes are defined as "read only" (ro), "read and delete" (rd), or "full access" (rw). A mode of "none" indicates the connection was rejected and not stored.
where <unit> is one of: b p l
If the unit is b, then size measurements are in bytes.
If the unit is p, then size measurements are in pages. Each page can hold up to 1024 bytes. Pages may be less than this size, in which case they are called "unsaturated" or "ragged".
If the unit is l, then size measurements are in lines. This is the same as pages but the system should always assume lines are separated by a linebreak character. Writing to line-based storage should be done one line at a time.
<label> is a freeform text label that describes the volume.
If no access is granted, the device should send the "denied" command.
<handle> disconnect
system -> storage
The system no longer wishes to access the device. Forget the session, and close any associated writing channels (described earlier).
<handle> stat <filename>
system -> storage
The system wants to know the size and type of a file. Please send it in reply with the message below.
<handle> stat <amount> <type> <desc>
<handle> stat none
storage -> system
The storage reports the metrics of a file. Amount is a non-negative integer (measured in units as described by "access")
<type> is one of: d f o
where f is a normal (readable) text file, o is a non-readable (object) file, and d is a directory (reserved for future use)
If the file does not exist, return the "stat none" syntax.
<handle> read <filename> <offset>+<length> <channel>
<handle> read <filename> <offset> <channel>
system -> storage
The system wants to read data from a file and has created a listener on <channel> to receive information. Please send the text at <offset> on that channel. If +<length> is not specified, only send 1 unit of storage.
If the file cannot be appended to, or opening it failed for some other reason, the device should reply with "stat none".
If <filename> is *, then provide text from the file directory for the current (root) location. See section on DIRECTORY FORMAT.
<handle> write <filename> <channel>
<handle> append <filename> <channel>
system -> storage
The system wants to begin writing to a file. If the system has rw access, then the device should open a listener on <channel> to receive data for <filename>, and send "ready". Otherwise send "denied".
Writing to line-based storage should be done one line at a time.
If the command is "write", then delete the contents of the file first.
If the command is "append", add data to the end of the file. If the file does not exist, create it first.
If the system does not have permission to write, the device should reply with "denied".
If the file cannot be appended to, or opening it failed for some other reason, the device should reply with "stat none".
<handle> ready
storage -> system
The device sends this in response to a "write" or "append" command. It is listening on the <channel> provided in that command and data can now be sent.
For page or line devices, send data 1 line at a time. Otherwise send it 1024 bytes at a time.
<handle> delete <filename>
system -> storage
Delete a file. The device should respond with a "deleted" message if successful, "denied" if not allowed, or "stat none" if the file did not exist.
<handle> deleted <filename>
storage -> system
A file has been removed from the system.
The storage device may send this spontaneously in response to an outside action. The handle should be NULL_KEY in this case.
<handle> new <filename>
storage -> system
A file has been added from the system.
The storage device may send this spontaneously in response to an outside action. The handle should be NULL_KEY in this case.
<handle> update
storage -> system
A file has changed in stat information (size, type, desc, etc).
The storage device may send this spontaneously in response to an outside action. The handle should be NULL_KEY in this case.
<handle> close
system -> storage
Close the writing channel associated with <handle>. Writing channels are explained earlier in the document.
<handle> denied
storage -> system
The requested action exceeds the permissions granted.