SX-RPC

Renamed due to confusion with "XMPP".

Initial: 2003-08-06
Update: 2003-08-08

Basic goals:
    Simplistic;
    Limited internal semantics;
    Allows nodes to operate with only partial understanding of a message.

Init

This will use port 7936/TCP, I will use an init protocol.
Current version is "0.1".

Init protocol could use SX-Notation:
(SXRPC <version>)
...
It would work by sending messages until agreement is reached, eventually sending (OK) or (REJECT). sending (OK) will mean "clear to send messages".

At present a connection sequence would probably go:
(SXRPC 0.1)
Expects similar to show up, otherwise rejecting.
Sends (OK).

Form
Description
(SXRPC <version>)
Flags that this connection uses SXRPC and is the given version.
(REJECT <reason> <opts...>)
Rejects the connection for the given reason.
(OK)
Connection was accepted.
(ASK <property>)
Asks for the value of a given property.
(TELL <property> <value>)
Indicates the value of a given property.

Rejection Reasons
Name
Options
Description
bad-version
<valid-version>
Does not know how to handle that protocol version.

Rejection for an unknown reason or one that can't be resolved should be handled by closing the connection.

SX-Notation


Transport will be an ulta stripped-down s-expression like syntax.
Basically:
    It uses parenthesis;
    Everything is either a form or a string.

Syntax
Description
(key ...)
Denotes a form.
key
Denotes an unwrapped string. Spaces or the chars "()[]{}'\;#| are not allowed.
"text"
Denotes a wrapped string. Wrapped strings may contain spaces or other such chars, though '"', newlines, ... are to be escaped (c-stlye '\' notation).
|mime|
Denotes a glob of base64 data (optional).

Wrapped and unwrapped strings are considered equivalent.

Whitespace is required between tokens, however it is optional parens or between parens and tokens.
'(foo (bar))' is ok;
'(foo(bar))' is also ok;
'(text "hello world!")' is ok;
'(text"hello world!")' is not;
'(foo bar)' is 2 tokens in a form;
'(foobar)' is only 1.

Basic Protocol


Message Passing will be naturally unidirectional.
Messages will have the form:
(<command> ...)

Command
Description
(pass <proc> (args ...))
Pass args to proc without sending a return, proc uses "Link Notation".
(call <proc> (args ...))
Calls the target identified in proc and uses args. Sends a return.
(return <value>)
Sends a return value. Returns are to be sent in the same order calls are recieved.
(error <err-name> <opts...>)
Flags that there was an error with the message.

Unknown commands are to be generally ignored.

It is recommended that extended commands/types be named in the form '<creator>-<name>', where creator can be initials of an author/short form of a company name, or the long form if desired. This is inteded to reduce the amount that extensions will collide.

Error names:
Name
Options
Description
bad-command
<command-name>
Should be sent by a node in response to an unknown command. The sender should stop sending this command.
bad-type
<type-name>
Should be sent by a node in response to an unknown type. The sender should stop sending this type.
bad-proc
<proc>
Should be sent by a node in response to an invalid function.

Value Types

A number of form types may be defined:
Form
Description
(int <value>)
Denotes an integer value.
(float <value>)
Denotes a float value.
(string <string>)
Denotes the value as a string.
(base64 <data...>)
Denotes the following string as a glob of base64 encoded data (needs to be a normal string, not a glob of data, though).
(time <time-str>)
Denotes the time in iso 8601 form 'yyyymmddThh:mm:ss'
(map {<key> <value>}...)
Generate a 'map' between key and value in each case. Key is a string naming the value.
(array <values...>)
Generate an array of values.
(link <link-notation>)
Identifies an object via a link (optional).

Along with this will be a few literal values:
Name
Description
(true)
The value corresponding to the boolean true.
(false)
The value corresponding to the boolean false.
(null)
The null value.


Link Notation

Link Notation may just be supported simply ('#name' only), or more fully if it is within the ability of the node.

!protocol
Identifies the protocol used to communicate with the target node.
As one can probably guess the protocol for SX-RPC nodes is 'sxrpc'...

@addr/hostname
Identifies the address/hostname of the target.
IPv6 Addresses are to be represented as defined in RFC 2732 (eg: '[<addr>]' or '[<addr>]:<port>').

#name/objid
Identifies the name/objid within the defined host (refers to the reciever if no host is identified).
An objid is an integer or some other name that can be distinguished from a name. The encoding of an objid may be specific to a node.

$name/objid
Refers to a name/objid relative to the sender, a host can't be identified with this form.

An alternate syntax could be:
sxrpc:<link-notation>
Which is to be used for external representation of links.