2007-03-01

QPS Protocol

The following describes the format of the QPS 3.5 protocol. Earlier versions of QPS are very similar, with only minor packet changes. All communication between the client and the QPS server is done via Messages.

Message from Client to Server.
0000 0002 Session ID
0002 0002 Code
0004 0004 Version (0x003f003f)
0008 0002 Sequence Number
000a 0004 Sub-Data Length
000e 0004 Packet Length
0012 **** Data
**** **** Sub-Data


Just like the Quark file format, everything is stored in Network Byte Order. Packet length is the length of Data + length of Sub-Data. Sequence numbers start at 1 and are incremented for each message sent by the client. Session ID starts at 0, and is initialized by the server upon successful login.

Message from Server to Client
0000 0004 Version (0x003f003f)
0004 0002 Code
0006 0002 Status
0008 0002 Sequence Number
000a 0004 Flags
000e 0004 Length
0012 **** Data


All server communication is a response to a message from the client. The sequence number can be used to identify which request from the client prompted this response.


Signon Packet (0x05)
The Signon packet is the first packet sent from the client to the server. It contains the username and password of the client.
0000 0012 Message Header (Code: 0x05)
0012 0001 Username Length
0013 **** Username
**** 0001 Password Length
**** **** Password
**** 0004 0x100


0000 0012 Response Header
0012 0004 Session ID


If the Code is 0, then login was successful. Otherwise, the login failed. The Session ID returned should be used in all future packets sent by the client.


GetHeaders (0x4a)
This packet retrieves a list of headers from the server.
0000 0012 Message Header (Code: 0x4a)


0000 0012 Response Header
0012 0004 Unknown
0016 0004 Number of Header Items
001a 0034 Header Item 0
004e 0034 Header Item 1...


Header Item
0000 0004 Header ID
0004 0004 Data Type
0008 0004 Reserved
000c 0001 Name Length
000d 0027 Name


The Data Types supported are:
0001 String
0002 Time Stamp
0004 Integer
0005 Float
0006 Checkbox
0007 Dropdown


GetPublications (0x66)
This packet asks the server for the list of Publications hosted by the server.
0000 0012 Message Header (Code: 0x66)
0012 0014 All zeroes


0000 0012 Response Header
0012 0008 Unknown
001a 0004 Number of Publications
001e 0001 Publication 0 Name Length
001f **** Publication 0 Name
**** 0004 Publication 0 ID
**** 0001 Publication 1 Name Length
**** **** Publication 1 Name
**** 0004 Publication 1 ID...


If Publication Name Length is even, then there's a 1 byte pad at the end of the
Publication Name.

GetStatuses (0x2b)
This call gets all the possible Statuses from the server. Statuses may differ
across publications, which is why the publication is sent with the request.
0000 0012 Message Header (Code: 0x2b)
0012 0001 Publication Length
0013 0043 Publication Name


Why we don't send the ID instead of the Name is a mystery.

0000 0012 Response Header
0012 0008 Unknown
001a 0004 Number of Statuses
001e **** Status 0
**** **** Status 1...


Status
0000 0004 Unknown
0004 0004 Status ID
0008 000e Unknown
0016 0001 Status Length
0017 **** Status Name
**** 0002 Unknown


If Status Length is even, then Status Name has a 1 byte pad at the end of it.

GetRepositories (0x40)
This call returns the repository information (the file share where the story files are actually kept).
0000 0012 Message Header (Code: 0x40)


0000 0012 Response Header
0012 0004 Number of Repositories
0016 **** Repository 0
**** **** Repository 1...


Repository
0000 0004 Length of Repository packet
0004 0032 Unknown
0036 0001 Repository Name Length
0037 **** Repository Name
**** 009a Unknown
**** 0002 Key 0
**** 0002 Value 0 Length
**** **** Value 0
**** 0002 Key 1
**** 0002 Value 1 Length
**** **** Value 1... (until Key=0xffff)


If Value Length is odd, then the Value has a 1 byte pad at the end of it.

The Keys are below.

0x09 Mount Info
0x12 Pathname
0x13 Mount Point


For Mount Point and Pathname, the Value is pretty simple, it's simply a string.
Mount Info is more complicated.

0000 0002 Unknown
0002 0004 Mount Type
0006 **** Mount Data


Mount Data depends n the Mount Type. There are two common mount types. "cifs" for Samba, and "afpm" for Apple File Share.

cifs
0000 000a Unknown
000a **** CIFS Share


afpm
0000 000c Unknown
000c 0002 Offset to IP Length (from beginning of Mount Data)
000e 0002 Offset to Share Length (from beginning of Mount Data)
**** 0001 IP Length
**** **** AFP IP
**** 0001 Share Length
**** **** AFP Share


Search (0x14)
The client sends the search criteria to the server to create a new "search session".
0000 0012 Message Header (Code: 0x14)
0012 0004 0x8


This is the first packet that contains sub-data. This is defined below.
0000 0004 Sub Data Length
0004 0004 0x00060006
0008 0004 0xb46dd345
000c 0020 All zeroes
002c 0004 0x2
0030 0004 0xaf7fffff
0034 0004 0x48
0038 0004 Length of Publications
003c 0004 Offset of Publication 0 ID
0040 0004 Queries Length
0044 0004 Offset of Queries
**** 0004 Publication 0 ID
**** 0004 0x0
**** 0004 Publication 1 ID
**** 0004 0x0...
**** **** Queries


Query
0000 0004 Query Length
0004 0004 Header Key
0008 0004 Header Type
000c **** Query Value


Query Value depends on the Header Type

Header Type 6 (Checkbox):
0000 0004 0x2
0004 0004 0x10000
0008 0004 0x1
000c 0004 0x18
0010 0004 0x1
0014 0004 0x1
0018 0004 0x1
001c 0004 Checkbox Value (0 or 1)
0020 0004 0x0


Header Type 7 (Dropdown):
0000 0004 0x0
0004 0004 0x10000
0008 0004 0x1
000c 0004 0x18
0010 0004 0x1
0014 0004 0x1
0018 0004 0x1
001c 0004 Dropdown ID
0020 0004 0x0


The server will return your search ID.

0000 0012 Response Header
0012 0002 Search ID


This Search ID will be used to fetch the results.

SearchCount (0x42)
This message requests the total # of results from the search.
0000 0012 Message Header (Code: 0x42)
0012 0002 Search ID
0014 000e 0
0022 0001 1
0023 0001 0


There is a Sub-Data component attached to this message.
0000 0004 1


The server will respond with the number of stories that match your query.
0000 0012 Response Header
0012 0004 Number of Stories


GetSearchResults (0x43)
This message gets a bunch of search results.
0000 0012 Message Header (Code: 0x43)


The server will respond with the results. If Code is not zero, then the server is
finished answering. If Code is zero, the response contains a list of matching stories.
You should continue to call GetSearchResults until the server is done.
0000 0012 Response Header
0012 0002 Entry 0 Length
0014 **** Entry 0
**** 0002 Entry 1 Length
**** **** Entry 1...


Entry
0000 0010 Unknown
0010 0001 File Status
0011 0025 Unknown
0036 0001 Filename Length
0037 **** Filename


If File Status has high-bit set, then the story is checked out by someone.

SearchUpdate

After doing a search.. the client should listen for updates from the server. The
server will send new updates whenever stories get added or removed from
the search results. Updates can be identified because they have a Status of 5.
The message will have its Flags set to identify whether or not the story is being added or removed from the search results. If the Flags & 0x100 then the story is being added, otherwise it is being removed.
0000 0012 Response Header
0012 0008 Unknown
001a 0001 Filename Length
001b **** Filename


OpenHeader (0x08)
This message will open the header of a story for reading and editing.
0000 0012 Message Header (Code: 0x08)
0012 0008 0
001a 0001 Filename Length
001b 0100 Filename
011b 0001 2 (for writing)


0000 0012 Response Header
0012 0002 Header ID


ReadHeader (0x09)
This message will fetch the current story header information.
0000 0012 Message Header (Code: 0x09)
0012 0002 Header ID


0000 0012 Response Header
0012 0120 Unknown
0132 0004 Number of Header Items
0136 0014 Header Item 0
014a 0014 Header Item 1...


Header Item
0000 0004 ID
0004 0004 Type
0008 0004 Reserved
000c 0004 Flags
0010 0004 Value


For some Types, Value may reference data in the packet. This data is located at 0x118+Value from the beginning of the current Header Item.

If Flags&0x1000000 then the value is blank. This is important, because the flags may say a field is blank, but the Value might point to data.

SaveHeader (0x0a)
0000 0012 Message Header (Code: 0x0a)
0012 0002 Header ID


The raw Header should be put into the SubData part of the message.

0000 0012 Response Header


CloseHeader (0x0e)
This message tells the server that we're done with the header.
0000 0012 Message Header (Code: 0x0e)
0012 0002 Header ID


If you made changes to the header, you MUST open the file on disk, and make the same changes to the end of the file. Otherwise, if the QPS server reboots, all changes you made will be undone.

SignOff (0x16)
This message tells the server that we want to sign off.
0000 0012 Message Header (Code: 0x16)
0012 0002 Session ID


0000 0012 Response Header


Close (0x06)
After we've signed off, we need to close the socket or sign back on. If we close the socket, we send this packet before doing so.
0000 0012 Message Header (Code: 0x06)

No comments: