A payload command is a special type of command that spans multiple lines. The best way to think of these commands is as regular single-line commands followed by a payload with a specified number of bytes of binary data.
Unlike commands, payloads have no universal format. Their format is defined by the rules of each specific payload command. You cannot separate them from the regular command flow by trying to figure out where they end. You must read the number of bytes specified in the payload command and use it to parse the payload.
A payload command (not including the payload itself - just the first line) might or might not have a TrID (depending on the context). It can have any number of parameters following the TrID depending on the syntax of the specific command. After the last parameter (or the TrID if there are no parameters) comes a positive integer. This number represents the length of the payload in bytes. Certain commands have specific limits on the length of the payload.
After the payload length, the command always ends with a newline. As usual, this is treated as specified in the Commands page.
Right after the newline comes the payload itself. It will always be the specified length in bytes. After the payload, normal command flow resumes.
Sending payload commands is very easy. Most programming languages have some sort of len() function that will find the length of the string you are sending in bytes. Just use this number, but remember not to include the newline at the end of the actual payload command itself (before the payload).
Note that the server relies on the message length that you provide. If you say that you are going to send 88 bytes and you send 87, the server will wait until you send something else, and then interpret the first byte of the next command as the last byte of the payload. You will end up sending an invalid command to the server. Similar problems will occur if your message length is too short.
Receiving payload commands is much harder. You cannot rely on the entire command to be in one packet, or to end with a newline. You absolutely must read the specified message length, and read that many bytes out of the socket after the initial newline. For suggestions on how to implement this, read this frequently asked question.
Messages were the first and are arguably the most important payload command in the protocol. They are represented by the MSG
command. Because messages are very common and are used in both the NS and the SB, the syntax will be described here.
When receiving MSG
s, the command will always have no TrID and two parameters before the payload length parameter. The first parameter is the account name of the source of the message and the second parameter is the URL-encoded friendly name for the source. On the NS, the account name and friendly name are always both Hotmail
(even though that is not a valid email address), but that might be subject to change. On the SB, the two parameters are the account name and friendly name of the source of the message.
When sending messages, you must include a TrID and one parameter specifying the acknowledgment you wish to receive from the server. You can only send message in an SB session, not in an NS session. More details about the syntax of outgoing messages are described in the Switchboard Messages page.
When sending messages, because the server does not interpret the payload, you can send anything you want in the payload, as long as it's not too long and the payload length parameter is correct. However, the payloads of messages are expected to be formatted in a particular way.
Much like in MIME, each message is divided into a header and a body. The header and body are separated by the first appearance of new newlines in a row.
The header of a message should be in the form of a standard MIME header as described in RFC 1521. The MIME header consists of an unordered list of fields separated by newlines. Each newline must be a \r\n
, or else it will not be interpreted properly by the official client.
Every field has a key and a value, for example:
preferredEmail: example@passport.com
The key should be considered case-sensitive. Third party clients should always send field key names in the case provided in this documentation. The last character of a key must be a colon, and will be followed by a space. The key can't have a colon anywhere else in it, but the value can have several or none. For example, in file transfer, one client might send:
Request-Data: IP-Address:
And the other client might come back with:
IP-Address: 10.44.102.65
Additional parameters may be specified in any one field. Each parameter is separated by a semi-colon followed by a space, and each parameter should be a key/value pair separated by an equal sign. Below is an example of a field with five parameters:
X-MMS-IM-Format: FN=Arial; EF=I; CO=ff0000; CS=0; PF=22
Because fields are unordered, a client must be prepared to see them in any order, regardless of the fact that the official client always sends fields in the same order. Also, a client must be prepared to receive messages with unknown fields and should ignore these. For example, GAIM will include a field something like User-Agent: Gaim/0.59
in all of its messages.
Every valid message is required to have a Content-Type
field identifying what type of message it is. Every message should also have a MIME-Version
field, but the official client still displays messages without that field.
The body of the message can pretty much be anything. If the header of the message specifies that the body of the message is UTF-8 encoded, then the body should be UTF-8 encoded. Note that this does not affect the message length. You must calculate the message length based on the raw number of bytes, and not the number of "characters".
In regular text messages, the official client adds newlines with \r\n
. These are to be interpreted as actual line breaks in the message. Note that the official client only parses \r
, so you can end lines with \r
and it would work the same as ending lines with \r\n
. Ending lines with just \n
will not work. For this reason, you must be prepared to receive messages with lines ending in \r
. All \n
's are completely ignored by the official client.
It's possible for messages to have no body. If you just end a message with the two newlines at the end of the header, it will have an empty body.
There are several other commands besides MSG
which have payloads. Their specific syntaxes are discussed in their respective sections.