Psion Link Protocol

Version 1.18, 18-Jul-07
by Alexander Thoukydides (alex@thouky.co.uk)

Copyright © Alexander Thoukydides.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".

Introduction

The SIBO and EPOC operating systems use a proprietary serial protocol, called the Psion Link Protocol (PLP), to allow remote access to their filesystems and to permit synchronization. This document attempts to provide sufficient information to allow the implementation of clients that communicate with SIBO or EPOC devices via the PLP.

The latest version of this document will normally be available from http://www.thouky.co.uk/software/psifs/plp.html.

History

RevisionDateAuthorDescription
1.1818-Jul-07Alexander ThoukydidesAdded standard names and other uses for the CRC algorithm.
1.1722-Aug-02Alexander ThoukydidesCorrected details of Connection Termination Frame and Disconnection Frame.
1.1631-Mar-02Alexander ThoukydidesCorrected some details of the WPRT print data format and NCP_GET_MACHINE_INFO parameters.
1.1502-Mar-02Alexander ThoukydidesAdded some details of the WPRT print data format.
1.1405-Feb-02Alexander ThoukydidesAdded information on the WPRT server.
1.1330-Jun-01Alexander ThoukydidesReplaced CRC table with algorithm to generate it.
Improved the GENCSERV server description.
1.1227-Jun-01Alexander ThoukydidesAdded more details of Ericsson R380 variant.
1.1117-Jun-01Alexander ThoukydidesAdded some details of Ericsson R380 variant.
Improved clipboard and CRC descriptions.
1.1010-Jun-01Alexander ThoukydidesModified clipboard description to fit the rest of the document better.
1.0910-Jun-01Fritz ElfertAdded description of Clipboard server and clipboard data.
1.0808-Jun-01Alexander ThoukydidesCorrected sense parameter for RFSV16_FSEEK and RFSV32_SEEK_FILE.
1.0730-Jan-01Alexander ThoukydidesCorrected parameters for RFSV32_READ_WRITE_FILE and added description of missing RFSV16_FDIRREAD parameter.
1.0609-Oct-00Alexander ThoukydidesAdded note that the EPOC variant of the data link layer is multi-windowed.
1.0528-Jul-00Alexander ThoukydidesAdded command line length parameter to NCP_GET_CMD_LINE response.
1.0402-Jun-00Alexander ThoukydidesReleased under version 1.1 of the GNU Free Documentation License.
1.0321-Apr-00Alexander ThoukydidesCorrected HTML
Updated email address.
Added URL for latest version of this document.
1.0223-Jan-00Alexander ThoukydidesAdded details for NCP_SET_TIME and NCP_GET_MACHINE_INFO.
1.0122-Dec-99Alexander ThoukydidesAdded descriptions for most RFSV server commands.
1.0009-Dec-99Alexander ThoukydidesFirst draft.
No descriptions for RFSV server commands.

Disclaimer

This document is supplied "as is"; no warranty, express or implied, of the merchantability of this document or its fitness for any particular purpose is given. In no circumstances shall the author, or any provider or distributor of this document, be liable for any damage, loss of profits, or any indirect or consequential loss arising out of the use or misuse of any information or particular in this document.

All trademarks are acknowledged.

Acknowledgements

The information contained within this document was collated from many different sources, including (but not restricted to):

Due to the diverse and incomplete nature of these sources, the description here probably contains both errors and omissions. Please send any corrections or additions to the author for inclusion in future revisions.

Layers

The PLP consists of a stack of layers that can be mapped onto the layers of the Open Systems Interconnection model:

OSI layerEPOC nameDescription
7Applicationn/a
6PresentationLINK, RPCS, RFSV etcMultiple servers, each providing a related set of services
5SessionNCPMultiplexing of multiple client-server communications channels with flow control
4Transportn/a
3Networkn/a
2Data linkLinkSynchronization, error detection and recovery
1PhysicalRS-232

Conventions

Unless otherwise specified the following conventions apply:

Physical Layer

At the lowest level, the PLP uses standard RS-232 for the physical layer. Depending on the exact devices being used, a special cable or converter may be required.

The DTR and RTS handshaking lines are both raised when the PLP is enabled and dropped when it is subsequently disabled. However, only the DSR line should be monitored to detect activity.

Any baud rate supported by both devices may be used. The data format is 8 data bits, 1 stop bit, and no parity checking.

Data Link Layer

The data link layer provides a simple byte orientated protocol to allow reliable communication between two devices. It is a connection orientated protocol with clear phases of link establishment, information transfer, and link termination. An acknowledgement and retry strategy is used to guarantee error free exchange of data.

This layer is sometimes referred to as LINK, but that leads to confusion with one of the higher level servers having the same name.

Frame Format

All data is transmitted within frames of the following format:

Bytes1111n112
DataSYNDLESTXContSeqDataDLEETXCRC

The Cont and Seq fields are combined into a single byte, with the Cont in the high nibble, and Seq in the low nibble. If the Seq value is greater than 7 then the most significant bit of the Seq nibble is set and an additional byte is inserted into the frame (EPOC variant only):

Bytes11111n112
DataSYNDLESTXCont(Seq & 7) | 8Seq >> 3DataDLEETXCRC

The length of the Data field (n) can vary from 0 to 300 bytes before byte stuffing. The session layer (NCP) is responsible for splitting and recombining longer messages to fit within this limit.

The 16 bit Cyclic Redundancy Check (CRC) is transmitted with the most significant byte followed by the least significant byte.

Note that the Ericsson R380 implementation uses ETB instead of SYN for the start of frame character. It also has a larger maximum frame size, with the length of the Data field (n) varying up to 2048 bytes before byte stuffing.

Special Characters

The following special characters are used within the protocol:

NameValueDescription
STX0x02Start of frame
ETX0x03End of frame
EOT0x04A stuffed ETX character
DLE0x10Field delimiter within a frame
DC10x11Not protocol characters, but stuffed (Ericsson R380)
DC30x13
SYN0x16Synchronize start of frame
ETB0x17Synchronize start of frame (Ericsson R380)

To prevent control characters within the frame body from being misinterpreted, a system of byte stuffing is employed. This replaces characters within the Cont/Seq and Data fields as follows:

Raw characterStuffed character sequenceVariants
NameValueNamesValues
DLE0x10DLE DLE0x10 0x10SIBO and EPOC
ETX0x03DLE EOT0x10 0x04EPOC
DC10x11DLE Space0x10 0x20Ericsson R380 only
DC30x13DLE !0x10 0x21

The reverse process is performed by the receiver.

Cyclic Redundancy Check

The standard x16 + x12 + x5 + 1 polynomial is used with an initial remainder of zero to generate a 16 bit CRC. This is the CRC-16-CCITT algorithm (also known as CRC-CCITT), as used by the XMODEM, X.25, V.41, Bluetooth, PPP and IrDA protocols. It is calculated over the Cont/Seq and Data bytes prior to any stuffing.

The following C code calculates a lookup table to allow efficient calculation of this CRC:

const unsigned int polynomial = 0x1021;
unsigned int table[256], index;
table[0] = 0;
for (index = 0; index < 128; index++)
{
    unsigned int carry = table[index] & 0x8000;
    unsigned temp = (table[index] << 1) & 0xffff;
    table[index * 2 + (carry ? 0 : 1)] = temp ^ polynomial;
    table[index * 2 + (carry ? 1 : 0)] = temp;
}

The following line can then be used to add a byte (value) to a 16 bit CRC (old_crc) to give the new 16 bit CRC (new_crc):

new_crc = (old_crc << 8) ^ table[((old_crc >> 8) ^ value) & 0xff];

The CRC value should be initialised to 0 before any bytes are processed. It may be necessary to use unsigned values to prevent implementation dependant problems on systems with 16 bit integers.

Timers

Two timer events are used to implement timeouts:

TimerPeriod
Re-transmissionBaud rate dependant
InactivityApplication dependant

The re-transmission timeout is used to trigger the re-transmission of unacknowledged frames. To optimise the timeout for the operating conditions, it is calculated by summing the following three components:

ComponentDescription
Baud Rate Bits FactorThe estimated time required to transmit the number of bits in a frame at the current baud rate. A suitable timeout is given by (13200 / baud) seconds.
Round Trip Time FactorA running estimate of the additional time to receive an acknowledgement from the remote device. A constant offset of 0.2 seconds is probably adequate for simpler implementations.
Backoff FactorAn additional timeout dependant on the number of re-transmissions that have taken place. This factor may be omitted in a simple implementation.

The Baud Rate Bits Factor is most significant at low baud rates, but the Round Trip Time Factor is more significant at higher baud rates.

The inactivity timer period may be adjusted to suit the application. If no detection of an idle connection is required then it can be completely disabled, otherwise a timeout of 60 seconds is recommended.

Although two different timer events are required, they may both be implemented using a single timer since only one timer can be active at any time.

Protocol Data Units

There are four major types of frame or Protocol Data Unit (PDU):

ContSeqNameDescription
0Sequence number of last valid Data_Pdu receivedAck_PduUsed to complete handshaking during connection phase, and to acknowledge Data_Pdu frames.
10Disc_PduUsed to terminate a connection.
1Disc_Req_PduFirst disconnect in a handshaked disconnection. Not currently used.
20Req_PduUsed during connection phase to request a connection.
1 ... 3 (use 1)Req_Req_PduFirst request in connection establishment. EPOC variant of protocol only.
4 ... 6 (use 4)Req_Con_PduResponding request in connection establishment. EPOC variant of protocol only.
3Next sequence numberData_PduData frame.

Only the Data_Pdu and Req_Con_Pdu frames contain Data fields.

The Data_Pdu and Ack_Pdu both contain a sequence number. This is used to allow acknowledgements to be matched to the corresponding data frame. Each device maintains its own sequence number that is incremented for each Data_Pdu, modulo either 8 for the SIBO variant or 2048 for the EPOC variant. More details are given in the following sections.

Connection Sequence

The connection sequence is slightly different with the SIBO and EPOC variants of the protocol. The original SIBO implementation suffers from a modem echo problem, whereby the data link layer can establish a connection with itself if serial data is echoed back; this was corrected in the EPOC implementation.

Both client-server and peer to peer connections are supported. The peer to peer connection sequence is a symmetrical version of the client-server sequence, with both devices processing all of the PDUs.

SIBO Connection

The client-server connection sequence is initiated by the client:

From clientFrom serverDescription
Req_PduConnection requested by client
Req_PduConnection accepted by server
Ack_PduConnection established

The peer to peer connection sequence is very similar:

From device 1From device 2Description
Req_PduReq_PduBoth devices request a connection
Ack_PduAck_PduBoth devices accept the connection

In both cases the sequence numbers should be initialised to 0, and the Ack_Pdu sent with a Seq field of 0. However, if the received Ack_Pdu contains a non-zero Seq field then the sequence number should be seeded from the supplied value.

EPOC Connection

The client-server connection sequence is initiated by the client:

From clientFrom serverDescription
Req_Req_PduConnection requested by client
Req_Con_PduConnection request confirmed by server
Ack_PduConnection established

The peer to peer connection sequence is very similar:

From device 1From device 2Description
Req_Req_PduReq_Req_PduBoth devices request a connection
Req_Con_PduReq_Con_PduBoth devices confirm the connection request
Ack_PduAck_PduBoth devices accept the connection

The Data field of the Req_Con_Pdu frames contain a 4 byte magic number. This is a pseudo-random value generated independently by each device. If the magic numbers match then a peer to peer connection is rejected because it indicates that the device is attempting to connect to itself. To avoid the risk of the same pseudo-random number sequence being generated by both devices, it is advisable to include an additional unique element, such as the value of a clock.

In both cases the sequence numbers should be initialised to 0, and the Ack_Pdu sent with a Seq field of 0. However, if the received Ack_Pdu contains a non-zero Seq field then the sequence number should be seeded from the supplied value.

If the Ack_Pdu is not received within the re-transmission timeout, then the Req_Req_Pdu may be re-transmitted up to 4 times before aborting the connection attempt.

Universal Connection

With a little care it is possible to support both variants of the protocol within a single state machine. The modulo value for sequence numbers can then be selected once the protocol variant has been identified.

A Req_Req_Pdu frame can always be used to initiate a connection; a device that supports the EPOC variant of the protocol will then reply with a Req_Con_Pdu frame, but if the other device only supports the SIBO variant then it will treat it as a Req_Pdu and reply with an Ack_Pdu. Hence, the protocol variant is indicated by whether a Req_Con_Pdu is received prior to the Ack_Pdu.

Similarly, if the other device initiates the connection, then the protocol variant can be detected from whether a Req_Pdu or Req_Req_Pdu is received.

Data Transfer Sequence

The SIBO variant of the data link layer is single windowed, i.e. only a single acknowledgement can be outstanding at any time. This guarantees that only a single transmit buffer and a single receive buffer is required. Beware though, that due to the asynchronous nature of data transfer, the data transmission and acknowledgement in each direction may be interleaved.

The EPOC variant of the data link layer is multi windowed, i.e. more than one acknowledgement can be outstanding at any time. The default configuration will send up to 8 Data_Pdu frames before waiting for an acknowledgement.

The data transfer sequence is the same for both the SIBO and EPOC variants. Either device may initiate a data transfer, providing that there are not too many outstanding acknowledgements for the previous transfers.

From device 1From device 2Description
Data_PduData sent
Ack_PduData acknowledged

The only other difference between the SIBO and EPOC variants, as described earlier, is the range of sequence numbers used; the value is modulo 8 for the SIBO variant and modulo 2048 for the EPOC variant. The sequence number is incremented prior to sending the Data_Pdu.

An Ack_Pdu should always be sent in response to a received Data_Pdu, even if the sequence number does not match the expected value. However, the Seq field of the Ack_Pdu should be set to the value from the last valid Data_Pdu received, not necessarily that of the Data_Pdu being responded to.

If the Ack_Pdu is not received within the re-transmission timeout, or if an Ack_Pdu is received with a different sequence number from that sent in the Data_Pdu, then the Data_Pdu may be re-transmitted up to 8 times before the link is disconnected. The sequence number must not be incremented when re-transmitting a Data_Pdu.

Disconnection Sequence

No handshaking occurs during the PLP disconnection sequence, so there is a risk of one device disconnecting without the other noticing. A fix was planned for the EPOC variant of the protocol, but does not appear to have been implemented.

A disconnection may also occur if the serial cable is physically disconnected, so the DSR handshaking line should also be monitored as described earlier. Additionally, if the inactivity timeout is exceeded without any frames being received then a disconnection should be assumed.

SIBO Disconnection

Either device may initiate the disconnection:

From device 1From device 2Description
Disc_PduInitiator requests a disconnection

Note that there is no reply to the Disc_Pdu, so the disconnection must be assumed to have succeeded.

EPOC Disconnection

The following disconnection sequence was proposed to fix the problem described above, but does not appear to be implemented. Either device may initiate the disconnection:

From device 1From device 2Description
Disc_Req_PduInitiator requests a disconnection
Disc_PduDisconnection confirmed

Even if this enhanced disconnection sequence is supported, the original SIBO disconnection sequence must still be supported. In particular, if the Disc_Pdu is not received within the re-transmission timeout then a Disc_Pdu frame should be sent and the disconnection assumed to have succeeded.

State Machine

This section describes a sample state machine that implements both the SIBO and EPOC variants of the data link layer. A peer to peer connection is attempted, but client-server connections should also be supported.

This is not intended to be the definitive implementation, but should help to clarify the operation of the protocol. In particular, only single windowed behaviour is supported, but this does not present interoperability with systems that do support multi-windowed operation; it just reduces that maximum achievable transfer rate.

States

Five states are used:

StateDescription
Idle_StateDisconnected
Idle_Req_StateReq_Req_Pdu sent, awaiting Req_Con_Pdu response
Idle_Ack_StateReq_Con_Pdu sent, awaiting Ack_Pdu response
Data_StateConnected, no acknowledgement pending
Data_Ack_StateData_Pdu sent, awaiting Ack_Pdu acknowledgement

Events

The following events are processed by the state machine:

EventSourceDescription
Ack_RxReceived frameAck_Pdu (acknowledge) received
Disc_RxDisc_Pdu or Disc_Req_Pdu (disconnect) received
Req_RxReq_Pdu (connection request) received
Req_Req_RxReq_Req_Pdu (handshaked connection request) received
Req_Con_RxReq_Con_Pdu (handshaked connection accepted) received
Data_RxData_Pdu (data) received
ConnectLocal clientConnection requested
DisconnectDisconnection requested
WriteData to transmit
TimeoutTimerRe-transmission timer or inactivity timer expired

Note that only a single timer event is used; both the re-transmission and inactivity timeouts are implemented using a single timer.

Only the SIBO disconnection sequence is implemented, so Disc_Pdu and Disc_Req_Pdu are treated identically.

Variables

The following variables are required to store additional state:

VariableDescriptionDefault
EnabledIs the link enabledFALSE
VariantThe protocol variant: SIBO or EPOCSIBO
RetriesNumber of retries remaining0
Seq_TxLast sequence number for transmitted data frames0
Seq_RxLast sequence number for received data frames0
MagicMagic number for this devicePseudo-random

State Tables

The following tables detail the actions taken for each event, with a separate table for each state.

The function Inc(x) is defined to return the next sequence number after x, modulo the appropriate value.

The Reset() function sets all of the variables, except for Enabled, back to the defaults given in the above table. This should select a different pseudo-random number for Magic. It also starts the re-transmission timer.

Idle_State
EventConditionActionNext state
Ack_RxAlwaysNo actionIdle_State
Disc_RxAlwaysNo actionIdle_State
Req_RxEnabledVariant = SIBO
Send Req_Con with Magic as data
Start re-transmission timer
Retries = 4
Idle_Ack_State
elseNo actionIdle_State
Req_Req_RxEnabledVariant = EPOC
Send Req_Con with Magic as data
Start re-transmission timer
Retries = 4
Idle_Ack_State
elseNo actionIdle_State
Req_Con_RxAlwaysNo actionIdle_State
Data_RxAlwaysNo actionIdle_State
ConnectAlwaysEnabled = TRUEIdle_State
DisconnectAlwaysEnabled = FALSEIdle_State
WriteAlwaysError - not connectedIdle_State
TimeoutEnabledSend Req_Req_Pdu
Start re-transmission timer
Idle_Req_State
elseNo actionIdle_State
Idle_Req_State
EventConditionActionNext state
Ack_RxEnabledSeq_Tx = sequence number
Seq_Rx = 0
Start inactivity timer
Connection established
Data_State
elseNo actionIdle_Req_State
Disc_RxAlwaysReset()Idle_State
Req_RxEnabledVariant = SIBO
SeqTx = 0
Seq_Rx = 0
Send Ack_Pdu with sequence number Seq_Rx
Start inactivity timer
Connection established
Data_State
elseNo actionIdle_Req_State
Req_Req_RxEnabledVariant = EPOC
Send Req_Con with Magic as data
Start re-transmission timer
Retries = 4
Idle_Ack_State
elseNo actionIdle_Req_State
Req_Con_RxAlwaysNo actionIdle_Req_State
Data_RxAlwaysNo actionIdle_Req_State
ConnectAlwaysError - already enabledIdle_Req_State
DisconnectAlwaysEnabled = FALSE
Send Disc_Pdu
Reset()
Idle_State
WriteAlwaysError - not connectedIdle_Req_State
TimeoutEnabledTry next baud rate if attempting auto-baud rate identification
Send Req_Req_Pdu
Start re-transmission timer
Idle_Req_State
elseReset()Idle_State
Idle_Ack_State
EventConditionActionNext state
Ack_RxEnabledSeq_Tx = sequence number
Seq_Rx = 0
Start inactivity timer
Connection established
Data_State
elseNo actionIdle_Ack_State
Disc_RxAlwaysReset()Idle_State
Req_RxEnabledVariant = SIBO
SeqTx = 0
Seq_Rx = 0
Send Ack_Pdu with sequence number Seq_Rx
Start inactivity timer
Connection established
Data_State
elseNo actionIdle_Ack_State
Req_Req_RxEnabledVariant = EPOC
Send Req_Con with Magic as data
Start re-transmission timer
Retries = 4
Idle_Ack_State
elseNo actionIdle_Ack_State
Req_Con_RxEnabled and (magic number != Magic)Variant = EPOC
Seq_Tx = 0
Seq_Rx = 0
Send Ack_Pdu with sequence number Seq_Rx
Start inactivity timer
Connection established
Data_State
elseNo actionIdle_Ack_State
Data_RxAlwaysNo actionIdle_Ack_State
ConnectAlwaysError - already enabledIdle_Ack_State
DisconnectAlwaysEnabled = FALSE
Send Disc_Pdu
Reset()
Idle_State
WriteAlwaysError - not connectedIdle_Ack_State
TimeoutEnabled and (0 < Retries)Retries = Retries - 1
Send Req_Con with Magic as data
Idle_Ack_State
elseResetIdle_State
Data_State
EventConditionActionNext state
Ack_RxAlwaysNo actionData_State
Disc_RxAlwaysReset()
Connection terminated
Idle_State
Req_RxAlwaysReset()
Connection terminated
Idle_State
Req_Req_RxAlwaysReset()
Connection terminated
Idle_State
Req_Con_RxAlwaysReset()
Connection terminated
Idle_State
Data_Rxsequence number == Inc(Seq_Rx)Seq_Rx = Inc(Seq_Rx)
Send Ack_Pdu with sequence number Seq_Rx
Start inactivity timer
Data_State
elseSend Ack_Pdu with sequence number Seq_RxData_State
ConnectAlwaysError - already enabledData_State
DisconnectAlwaysEnabled = FALSE
Send Disc_Pdu
Reset()
Connection terminated
Idle_State
WriteAlwaysSeq_Tx = Inc(Seq_Tx)
Send Data_Pdu with sequence number Seq_Tx
Start re-transmission timer
Retries = 8
Data_Ack_State
TimeoutAlwaysSend Disc_Pdu
Reset()
Connection terminated
Idle_State
Data_Ack_State
EventConditionActionNext state
Ack_Rxsequence number == Seq_TxStart inactivity timerData_State
elseNo actionData_Ack_State
Disc_RxAlwaysReset()
Connection terminated
Idle_State
Req_RxAlwaysReset()
Connection terminated
Idle_State
Req_Req_RxAlwaysReset()
Connection terminated
Idle_State
Req_Con_RxAlwaysReset()
Connection terminated
Idle_State
Data_Rxsequence number == Inc(Seq_Rx)Seq_Rx = Inc(Seq_Rx)
Send Ack_Pdu with sequence number Seq_Rx
Start re-transmission timer
Data_Ack_State
elseSend Ack_Pdu with sequence number Seq_RxData_Ack_State
ConnectAlwaysError - already enabledData_Ack_State
DisconnectAlwaysEnabled = FALSE
Send Disc_Pdu
Reset()
Connection terminated
Idle_State
WriteAlwaysError - connection busyData_Ack_State
Timeout0 < RetriesRetries = Retries - 1
Send Data_Pdu with sequence number Seq_Tx
Start re-transmission timer
Data_Ack_State
elseSend Disc_Pdu
Reset()
Connection terminated
Idle_State

PLP Mode on Erisson R380

The Ericsson R380 incorporates a modem, so it is necessary to reconfigure the serial port for PLP use.

Starting PLP

An "AT" command is used to start the PLP connection:

From hostFrom R380Description
0x41 0x54 0x2a 0x45 0x53 0x59 0x4e 0x3d 0x31 0x0dRequest PLP mode: AT*ESYN=1
0x41 0x54 0x2a 0x45 0x53 0x59 0x4e 0x3d 0x31 0x0dEcho command: AT*ESYN=1
0x0d 0x0a 0x4f 0x4b 0x0d 0x0aAcknowledge command: OK
0x11 0x11Start PLP operation

A peer to peer PLP connection is then established as described above.

Ending PLP

Following the Req_Req_Pdu the Erisson R380 sends a single DC1 character and returns to "AT" mode.

Session Layer

The Network Control Protocol (NCP) provides multiplexed communication channels between multiple clients and servers. It also supports fragmentation and recombination to allow arbitrary sized messages to be transmitted via data link layer frames that have a maximum permitted data field size.

Channels

Numbered channels are used to address frames to the appropriate process. The SIBO variant supports 8 simultaneous channels, but the EPOC variant increases this to 256. Channel 0 is always used for the NCP control channel, and channel 1 is always used for the special LINK channel used to register additional servers. Other channels are dynamically allocated as required.

Frame Formats

The general format for an NCP frame is:

Bytes111n
DataDestination channelSource channelFrame typeData

The channel pair (Source channel and Destination channel) specifies a connection between two processes. PDUs for channel 0 are expedited; they must be delivered and processed before any PDUs for other channels.

Command Frames

Command frames are always send to channel 0. The interpretation of the source channel is defined below for each command.
XOFF Frame
Bytes111
Data0x00Channel0x01

Block transmission of frames to the specified Channel until an XON frame is received. All channels default to being unblocked.

XON Frame
Bytes111
Data0x00Channel0x02

Unblock transmission of frames to the specified Channel. This reverses the effect on an XOFF frame.

Connect Frame
Bytes111n
Data0x00Client channel0x03Server name

A client is requesting connection to the server called Server name. A Connect Response frame is always sent in reply.

The maximum length of the server name field is 16 characters, including the NUL terminator.

Connect Response Frame
Bytes11111
Data0x00Server channel0x04Client channelStatus code

This is the reply sent in response to a Connect frame. The source channel is set to the server's channel if the connection was successful, or 0 for the control channel otherwise. The Status code is zero (E_SIBO_NONE) for a successful connection, or non-zero (E_SIBO_FILE_NXIST) if the server cannot be found.

Connection Termination Frame
Bytes111
Data0x00Server channel0x05

The specified server has disconnected all clients.

NCP Information Frame
Bytes11114
Data0x000x000x06VersionID

This is the first frame that is sent by an invocation of NCP when a connection has been established. It enables the NCP and servers to adapt to the capabilities of the other device.

The following Version numbers are currently used:

VersionDescription
0x02SIBO (old)
0x03SIBO (new)
0x06EPOC (ER3)
0x10EPOC (ER5)

For maximum compatibility it is recommended that 6 be used if the data link layer has identified the EPOC variant of the protocol, and 2 be used otherwise. The behaviour of servers should be controlled by the received version number.

The ID is a unique identifier for the current NCP process. It does not appear to be used for anything, so it is probably sufficient to generate a pseudo-random number.

Disconnection Frame
Bytes1111
Data0x00Client channel0x07Server channel

The specified client has disconnected from the specified server.

NCP Termination Frame
Bytes111
Data0x00Channel0x08

The NCP has shut down.

Data Frames

As described above, the NCP fragments and recombines messages to fit within the data link layer's maximum data field size. Zero or more Partial frames are sent followed by a Complete frame to transmit the full message.
Complete Frame
Bytes111n
DataDestination channelSource channel0x01Data

A Complete frame serves as either the final frame in a series of Partial frames which make a single large frame, or as a single frame which fits into the data link layer's frame size.

Partial Frame
Bytes111n
DataDestination channelSource channel0x02Data

A Partial frame is sent as one of a series that should be re-assembled to form a larger frame.

Connection Sequence

The following general sequence of frames are exchanged after a connection has been established:

From device 1From device 2
NCP Information frameNCP Information frame
Connect frame for LINK.*Connect frame for LINK.*
Connect frame for other serversConnect frame for other servers
Connect Response framesConnect Response frames

Due to the asynchronous nature of the protocol, the Connect Response frames may occur at any time after the corresponding Connect frame has been sent. Also, with the exception of the LINK.* connection, the Connect frames may be sent at any time to connect to additional servers.

Disconnection Sequence

There may not be an opportunity to perform a controlled disconnection sequence, for example if the cable is physically disconnected, but the ideal sequence would be:

From disconnecting device
Disconnection frames and Connection Termination frames for each connection
NCP Termination frame

Note that no confirmations are received; it is the responsibility of the data link layer to ensure that the frames are communicated without errors. Connect frames received during this sequence should be ignored; the remote device may attempt to re-establish terminated connections.

Presentation Layer

Named servers provide a set of related services, such as remote file system access. All operations consist of a command sent by the client and a reply from the server.

LINK Server

The LINK server is closely associated with the NCP; it is always connected before any other servers, always uses channel 1, and allows allows additional servers to be registered. The name "LINK.*" is used in the Connect frame to start the LINK server.

Command Frames

LINK only supports a single command.
Link Register Command
Command:

Bytes12n
Data0x00Operation IDServer name

or:

Bytes12n114
Data0x00Operation IDServer nameMajor versionMinor versionBuild

Reply:

Bytes1222n
Data0x01Operation IDStatus code???Server name

This command is used to register a server for connection using a Connect frame. It should normally be tried after a connection has been unsuccessfully attempted.

The Operation ID is a unique identifier used to verify that commands and replies match. A different value within the range 0 to 65535 should be generated for each command, and the reply checked to confirm that it contains the same value.

The Server name in the command is the name of the required server, but without any extension specified. If the reply contains a valid Server name (at least 4 characters long and not containing any control characters) then that should be used as the name within the Connect frame, otherwise ".*" should be appended to the name specified in the command.

The second form of the command allows a minimum version of the server to be specified. The two forms behave identically if the Version and Build are both set to 0.

A typical sequence of operations would be:

From clientFrom server
Connect frame for SYS$RPCS.*
Connect Response frame indicating failure
Link Register command for SYS$RPCS
Link Register response specifying SYS$RPCS.*
Connect frame for SYS$RPCS.*
Connect Response frame indicating success

RPCS Server

The RPCS server provides Remote Command Services. This supports general operations, such as launching and terminating processes. The name "SYS$RPCS.*" is used in the Connect frame to start the RPCS server. However, as mentioned above, it may be necessary to use the Link Register command to register the server first. On some SIBO devices, the RPCS server is not present by default, and is normally downloaded as M:\SYS$RPCS.IMG by either RCOM or PsiWin.

Note that the Ericsson R380 uses the name "SYS$RPCSU.*" instead, where the additional "U" in the name indicates that Unicode strings are used.

Command Frames

All RPCS command frames generate a response frame. The first byte of the response is a result code; this is always a SIBO status code, even with the EPOC variant of the protocol. However, the SIBO variant uses the SIBO character set for any text strings, and the EPOC variant uses the EPOC character set.
NCP_QUERY_SUPPORT
Command:

Bytes111
Data0x00Major versionMinor version

Reply:
Bytes111
DataStatus codeMajor versionMinor version

Exchange NCP version numbers.

All existing implementations use a Major version of 1, with the Minor version varying between 1 and 30.

NCP_EXEC_PROGRAM
Command:

Bytes11281n
Data0x01Program nameArguments lengthArguments

Reply:
Bytes1
DataStatus code

Start a copy of Program name with the specified Arguments.

If the Program name is shorter than 128 characters then it is padded to 128 characters with 0 bytes, otherwise the field is extended as required. The Arguments length field specifies the length of the Arguments string, excluding the terminator character.

NCP_QUERY_DRIVE
Command:

Bytes11
Data0x02Drive letter

Reply:
Bytes1Repeated fields:
nimi
DataStatus codeProgram nameArguments

List the programs with open files on the specified drive.

The EPOC variant lists all applications, regardless of which drive they are using. The result is a list of Program name and Argument pairs; one for each open program.

NCP_STOP_PROGRAM
Command:

Bytes1n
Data0x03Program name

Reply:
Bytes1
DataStatus code

Attempt to terminate the specified process.

This may result in the application opening a dialogue box to allow any modifications to be saved. NCP_PROG_RUNNING can be used to detect when the process has been stopped.

NCP_PROG_RUNNING
Command:

Bytes1n
Data0x04Program name

Reply:
Bytes1
DataStatus code

Check whether the specified process is running.

This returns E_SIBO_NONE if the process is running, or E_SIBO_FILE_NXIST otherwise.

NCP_FORMAT_OPEN
Command:

Bytes1n
Data0x05Device name

Reply:
Bytes122
DataStatus codeHandleCount

Initiate formatting a drive.

This is a slow process, so NCP_FORMAT_READ should be called Count times with the returned Handle to progress the format.

NCP_FORMAT_READ
Command:

Bytes12
Data0x06Handle

Reply:
Bytes1
DataStatus code

Continue formatting a drive.

The Handle returned by NCP_FORMAT_OPEN must be passed to specify the operation to progress.

NCP_GET_UNIQUE_ID
Command:

Bytes1n
Data0x07Device name

Reply:
Bytes14
DataStatus codeUnique ID

Read the Unique ID for the specified removable device.

NCP_GET_OWNER_INFO
Command:

Bytes1
Data0x08

Reply:
Bytes1n
DataStatus codeOwner information (not NUL terminated)

Read the user information.

The returned Owner information is plain text; any formatting is stripped.

NCP_GET_MACHINE_TYPE
Command:

Bytes1
Data0x09

Reply:
Bytes12
DataStatus codeMachine type

Read the type of the remote machine.

The following Machine type numbers are currently used:

Machine typeDescription
0x00Unknown
0x01PC
0x02MC
0x03HC
0x04Series 3
0x05Series 3a, 3c, or 3mx
0x06Workabout
0x07Sienna
0x08Series 3c
0x20Series 5
0x21WinC

Be careful; some of these values are untested.

NCP_GET_CMD_LINE
Command:

Bytes1n
Data0x0aProcess name

Reply:
Bytes1n
DataStatus codeProgram name
or:
Bytes1n1m
DataStatus codeProgram namemCommand line (not NUL terminated)
or:
Bytes1n256 - nm40 - m
DataStatus codeProgram namemCommand line???

Read the Command line for Process name.

The first form of the reply is used if there is no open file. The other two forms are used by the EPOC and SIBO variants respectively.

NCP_STOP_FILE
Command:

Bytes1n
Data0x0bFile name

Reply:
Bytes1n
DataStatus codeProcess name

Find the Process name of the program using the named file.

NCP_GET_MACHINE_INFO
Command:

Bytes1
Data0x64

Reply:
Bytes14112816444444444444444444444444444444444488
DataStatus codeMachine typeMajor ROM versionMinor ROM versionROM buildReservedMachine nameDisplay widthDisplay heightMachine UID lowMachine UID highTime lowTime highCountry codeUTC offsetDSTDST zoneMain battery inserted lowMain battery inserted highMain battery statusMain battery used lowMain battery used highMain battery currentMain battery used powerMain battery voltageMain battery max voltageBackup battery statusBackup battery voltageBackup battery maximum voltageExternal powerExternal power used lowExternal power used high???RAM sizeROM sizeRAM maximum freeRAM freeRAM disk sizeRegistry sizeROM reprogrammableLanguageReserved

This command is only supported by the EPOC variant of the protocol.

See NCP_GET_MACHINE_TYPE for a description of the possible Machine type values.

The Major ROM version, Minor ROM version, and ROM build fields combine to give the version number of the operating system. This is typically displayed with the Major ROM version followed by a decimal point, Minor ROM version using two digits, and finally the ROM build in brackets. All values are displayed in decimal.

The Machine name is a string giving a textual description of the machine type and revision.

The Display width and Display height indicate the size of the LCD in pixels.

The Machine UID low and Machine UID high fields combine to form a 64 bit unique identifier for this machine.

See NCP_SET_TIME for a description of the Time low, Time high, Country code, UTC offset, DST and DST zone values.

The Main battery inserted low and Main battery inserted high fields combine to form a 64 bit date specifying when the main batteries were inserted, specified as the number of micro-seconds since 00:00 on 1st January 1.

Main battery status gives the condition of the main batteries. See RFSV32_VOLUME for a description of the possible values.

The Main battery used low and Main battery used high fields combine to form a 64 bit value giving the number of micro-seconds that the main battery has been used.

Main battery current is the main battery current in milli-amps.

Main battery used power is the integrated main battery usage in mA-seconds.

Main battery voltage and Main battery max voltage give the current and maximum main battery voltages in milli-volts.

Backup battery status gives the condition of the backup batteries. See RFSV32_VOLUME for a description of the possible values.

Backup battery voltage and Backup battery maximum voltage give the current and maximum backup battery voltages in milli-volts.

The External power field indicates whether the machine is operating on external power.

The External power used low and External power used high fields combine to form a 64 bit value giving the number of micro-seconds that the machine has been operating on external power.

RAM size and ROM size give the total size of ROM and RAM fitted.

RAM maximum free and RAM free give the maximum and current free RAM in bytes.

RAM disk sizeis the current size of the internal RAM disk in bytes.

Registry size is the current size of the registry in bytes.

The ROM reprogrammable field indicates whether the ROM can be modified.

The Language may be one of the following:

LanguageDescription
0x00Test
0x01UK English
0x02French
0x03German
0x04Spanish
0x05Italian
0x06Swedish
0x07Danish
0x08Norwegian
0x09Finnish
0x0AAmerican English
0x0BSwiss French
0x0CSwiss German
0x0DPortuguese
0x0ETurkish
0x0FIcelandic
0x10Russian
0x11Hungarian
0x12Dutch
0x13Belgian Flemish
0x14Australian English
0x15Belgian French
0x16Austrian German
0x17New Zealand English
0x18International French
0x19Czech
0x1ASlovak
0x1BPolish
0x1CSlovenian
0x1DTaiwan Chinese
0x1EHong Kong Chinese
0x1FRPC Chinese
0x20Japanese
0x21Thai

NCP_CLOSE_HANDLE
Command:

Bytes12
Data0x65Handle

Reply:
Bytes1
DataStatus code

Close a previously opened resource Handle. This command is only supported by the EPOC variant of the protocol.

NCP_REG_OPEN_ITER
Command:

Bytes1???
Data0x66???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_REG_READ_ITER
Command:

Bytes1???
Data0x67???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_REG_WRITE
Command:

Bytes1???
Data0x68???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_REG_READ
Command:

Bytes1???
Data0x69???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_REG_DELETE
Command:

Bytes1???
Data0x6a???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_SET_TIME
Command:

Bytes1444444
Data0x6bTime lowTime highCountry codeUTC offsetDSTDST zone

Reply:
Bytes1
DataStatus code

Set the clock. This command is only supported by the EPOC variant of the protocol.

The Time low and Time high fields combine to form a 64 bit date, specified as the number of micro-seconds since 00:00 on 1st January 1 in the home time zone.

The Country code indicates the country of the home time zone. This is 0 for most countries, but should probably be the international dial code.

The UTC offset is the number of seconds offset of the home time zone from UTC.

The DST consists of a combination of the following flags, specifying which zones daylight saving time is active:

DST zoneDescription
0x00000000None
0x00000001European
0x00000002Northern
0x00000004Southern
0x40000000Home

The DST zone is a single flag, from those listed above, specifying which DST zone the home time zone is part of.

The easiest way to use this command is to read the various time zone and DST fields using NCP_GET_MACHINE_INFO and just change the Time low and Time high fields to the new time.

NCP_CONFIG_OPEN
Command:

Bytes1???
Data0x6c???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_CONFIG_READ
Command:

Bytes1???
Data0x6d???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_CONFIG_WRITE
Command:

Bytes1???
Data0x6e???

Reply:
Bytes1???
DataStatus code???

This command is only supported by the EPOC variant of the protocol.

NCP_QUERY_OPEN
Command:

Bytes11
Data0x6fDrive letter

Reply:
Bytes12
DataStatus codeHandle

Start a query to read the files open on the specified drive. This command is only supported by the EPOC variant of the protocol.

NCP_QUERY_READ should be called repeatedly with the returned Handle to read the details, and NCP_CLOSE_HANDLE should be called to close the Handle when finished.

NCP_QUERY_READ
Command:

Bytes12
Data0x70Handle

Reply:
Bytes1Repeated fields:
nimi
DataStatus codeProgram nameArguments

List the programs with open files on the specified drive. This command is only supported by the EPOC variant of the protocol.

NCP_QUERY_OPEN should be used to obtain the Handle. The result is a list of Program name and Argument pairs; one for each open program. This should be called repeatedly until no further details are returned.

NCP_QUIT_SERVER
Command:

Bytes1
Data0xff

Reply:
Bytes1
DataStatus code

Quit the RPCS server.

It is not necessary to use this command; use of the Connection Termination frame is adequate.

RFSV Server

The RFSV server provides Remote File Services. This provides a remote interface that behaves similarly to local file accesses; files must be opened before they can be read or written, and a sequential file pointer is maintained for each open file. A current directory is also maintained, allowing use of relative file names.

The name "SYS$RFSV.*" is used in the Connect frame to start the RFSV server. The Ericsson R380 uses the name "SYS$RFSVU.*" instead, where the additional "U" in the name indicates that Unicode strings are used.

The version number specified in the NCP Information frame selects the RFSV version; a value of 6 or higher is required to use the EPOC variant, otherwise the SIBO variant is used.

SIBO Command Frames

All RFSV command frames have the following general format:

Bytes22n
DataReason codenRequest data

The maximum length of Request data is 852 bytes, leading to a maximum command frame size of 856 bytes.

All RFSV reply frames have the following general format:

Bytes222n
Data0x2an + 2Status codeReply data

The Status code is a SIBO status code.

The maximum length of Reply data is 852 bytes, leading to a maximum reply frame size of 858 bytes. To make allowance for possibly buggy implementations, it is recommended that at most 640 bytes of data are read or written to a file in a single operation, but all received frames up to the maximum size of 858 bytes should be accepted.

The SIBO character set is used for any text strings.

RFSV16_FOPEN
Command:

Bytes222n
Data0x00Frame lengthModeFile name

Reply:

Bytes2222
Data0x2aFrame lengthStatus codeHandle

Open File name for reading or writing via the returned Handle.

The Mode consists of one of the following operations:

ModeDescription
0x0000Open an existing file
0x0001Create a new file
0x0002Create a new file, or truncate an existing file to zero length
0x0003Append to an existing file
0x0004Create a new file with a unique name

combined with one of these stream types:

ModeDescription
0x0000Open as a binary stream
0x0010Open as a text stream
0x0020Open as a binary record
0x0030Open as a directory record
0x0040Open as a format
0x0050Open as a device list
0x0060Open as a node list

and any of the following flags:

ModeDescription
0x0100Open for read and write access
0x0200Open for random access
0x0400Open for sharing

RFSV16_FCLOSE must be used to close the Handle when it is no longer required.

RFSV16_FCLOSE
Command:

Bytes222
Data0x02Frame lengthHandle

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Close the Handle previously opened using RFSV16_FOPEN or RFSV16_OPENUNIQUE.

RFSV16_FREAD
Command:

Bytes2222
Data0x04Frame lengthHandleLength

Reply:

Bytes222n
Data0x2aFrame lengthStatus codeData

Read Length bytes from the file identified by Handle.

The reply contains the Length bytes of data read.

RFSV16_FDIRREAD
Command:

Bytes222
Data0x06Frame lengthHandle

Reply:

Bytes2222Repeated fields:
22444ni
Data0x2aFrame lengthStatus codeBuffer lengthVersionAttributesSizeModifiedReservedFile name

Read entries from the directory specified by Handle.

The reply contains details of entries from the specified directory. To read all of the directory entries this operation should be repeated until the returned Status code is E_SIBO_FILE_EOF.

The Buffer length is the length of the repeated fields, i.e. Frame length - 4.

The Attrubutes consists of a combination of the following flags:

AttributeDescription
0x0001Writeable
0x0002Hidden
0x0004System
0x0008Volume label
0x0010Directory
0x0020Modified
0x0100Readable
0x0200Executable
0x0400Stream
0x0800Text

The Size is simply the length of the file in bytes.

The Modified date is specified as the number of seconds since 13:00 on 1st January 1970. This is always a multiple of two.

RFSV16_FDEVICEREAD
Command:

Bytes222
Data0x08Frame lengthHandle

Reply:

Bytes22222244n216
Data0x2aFrame lengthStatus codeVersionMedia typeRemovableSizeFreeVolume labelBattery statusReserved

Read information about the device specified by Handle.

The Media type consists of a type:

Media typeDescription
0x0000Not a known type
0x0001Floppy disk
0x0002Hard disk
0x0003Flash disk
0x0004RAM
0x0005ROM
0x0006Write protected

combined with any of the following flags:

Media typeDescription
0x0800Formattable
0x1000Dual density
0x2000Internal
0x4000Dynamic
0x8000Compressible

The Removable flag is non-zero for a removable device, or zero otherwise.

Size and Free give the total size and the remaining free space on the device.

The Battery status may be one of the following:

Media typeDescription
0Dead
1Very low
2Low
3Good

RFSV16_FWRITE
Command:

Bytes222n
Data0x0aFrame lengthHandleData

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Write Data to the file identified by Handle.

The number of bytes is not explicitly specified; this is inferred from the size of the frame.

RFSV16_FSEEK
Command:

Bytes22242
Data0x0cFrame lengthHandleSeek offsetSense

Reply:

Bytes2224
Data0x2aFrame lengthStatus codeNew offset

Reposition the sequential file pointer for the file specified by Handle.

The interpretation of the signed New offset value depends on the Sense specified:

SenseDescription
0x0001Absolute position from the start of the file
0x0002Offset from the current position
0x0003Offset from the end of the file
0x0004Read the current position without changing it
0x0005Set
0x0006Rewind

The value of the sequential file pointer after the seek is returned as New offset.

RFSV16_FFLUSH
Command:

Bytes222
Data0x0eFrame lengthHandle

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Flush to disk any cached data for the file specified by Handle.

RFSV16_FSETEOF
Command:

Bytes2224
Data0x10Frame lengthHandleSize

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Set the length of the file specified by Handle to Size bytes.

RFSV16_RENAME
Command:

Bytes22nm
Data0x12Frame lengthSource nameDestination name

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Rename Source name to Destination name.

RFSV16_DELETE
Command:

Bytes22n
Data0x14Frame lengthFile name

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Delete File name.

RFSV16_FINFO
Command:

Bytes22n
Data0x16Frame lengthFile name

Reply:

Bytes22222444
Data0x2aFrame lengthStatus codeVersionAttributesSizeModifiedReserved

Read details about File name.

See RFSV16_FDIRREAD for a description of the returned values.

RFSV16_SFSTAT
Command:

Bytes2222n
Data0x18Frame lengthSetMaskFile name

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Set the Mask attributes of File name to the state specified by Set.

See RFSV16_FDIRREAD for a description of the possible attribute values.

If both the Set and Mask values are both specified as 0x0008, indicating a volume label, then this changes the volume label. As an example, if File name is C:\FOOBAR then it will set the volume label for drive C: to FOOBAR.

RFSV16_PARSE
Command:

Bytes22n
Data0x1aFrame lengthFile name

Reply:

Bytes222n
Data0x2aFrame lengthStatus codeParsed name

Parse File name to give Parsed name.

This can be used to remove wildcards from a file name.

RFSV16_MKDIR
Command:

Bytes22n
Data0x1cFrame lengthDirectory name

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Create a new directory called Directory name.

RFSV16_OPENUNIQUE
Command:

Bytes222n
Data0x1eFrame lengthModeFile name

Reply:

Bytes2222n
Data0x2aFrame lengthStatus codeHandleOpened name

Open File name for reading or writing via the returned Handle.

See RFSV16_FOPEN for a description of the possible Mode values.

The actual name of the file opened is returned as Opened name. This is useful when requesting a unique file to be opened.

RFSV16_STATUSDEVICE
Command:

Bytes22n
Data0x20Frame lengthDevice name

Reply:

Bytes22222244n216
Data0x2aFrame lengthStatus codeVersionMedia typeRemovableSizeFreeVolume labelBattery statusReserved

Read the status of the device specified by Device name.

See RFSV16_FDEVICEREAD for details of the returned values.

RFSV16_PATHTEST
Command:

Bytes22n
Data0x22Frame lengthFile name

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Check if File name specifies a valid path.

RFSV16_STATUSSYSTEM
Command:

Bytes22n
Data0x24Frame lengthFile system

Reply:

Bytes222222
Data0x2aFrame lengthStatus codeVersionTypeFormattable

Read the status of the specified File system.

RFSV16_CHANGEDIR
Command:

Bytes22n
Data0x26Frame lengthDirectory name

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Change the current directory to Directory name.

RFSV16_SFDATE
Command:

Bytes224n
Data0x28Frame lengthModifiedFile name

Reply:

Bytes222
Data0x2aFrame lengthStatus code

Set the Modified date of File name.

The date is specified as number of seconds since 13:00 on 1st January 1970.

EPOC Command Frames

All RFSV command frames have the following general format:

Bytes22n
DataReason codeOperation IDRequest data

All RFSV reply frames have the following general format:

Bytes224n
Data0x11Operation IDStatus codeReply data

The Operation ID is a unique identifier used to verify that commands and replies match. A different value within the range 0 to 65535 should be generated for each command, and the reply checked to confirm that it contains the same value.

The Status code is an EPOC status code.

The maximum frame size is not well defined, but to avoid potential incompatibilities it is recommended that at most 2048 bytes of data are read or written to a file in a single operation, but all received frames up to a maximum size of 2079 bytes should be accepted.

Strings are usually passed as a 2 byte length followed by the data using the EPOC character set. Strings are not NUL terminated. The most significant bit of the length field may be set to indicate Unicode strings.

RFSV32_CLOSE_HANDLE
Command:

Bytes224
Data0x01Operation IDHandle

Reply:

Bytes224
Data0x11Operation IDStatus code

Close the Handle previously opened using RFSV32_OPEN_DIR, RFSV32_OPEN_FILE, RFSV32_TEMP_FILE, RFSV32_CREATE_FILE, RFSV32_REPLACE_FILE or RFSV32_OPEN_DIR_UID.

RFSV32_OPEN_DIR
Command:

Bytes2242 + n
Data0x10Operation IDAttributesFile name

Reply:

Bytes2244
Data0x11Operation IDStatus codeHandle

Open a Handle to read files that match the wildcarded File name.

RFSV32_READ_DIR should be used to read the list of matching files. The description for that command also details the possible Attributes that may be specified.

RFSV32_READ_DIR
Command:

Bytes224
Data0x12Operation IDHandle

Reply:

Bytes224Repeated fields:
0 to 3444444444ni0 to 3mi
Data0x11Operation IDStatus codeAlignmentShort name lengthAttributesSizeModified lowModified highUID 1UID 2UID 3Long name lengthLong nameAlignmentShort name

Read directory entries specified by the Handle previously opened using RFSV32_OPEN_DIR.

The reply contains details of entries from the specified directory. To read all of the directory entries this operation should be repeated until the returned Status code is E_EPOC_EOF.

Two names are returned for each file. The Long name is the actual name of the file, and the Short name is the SIBO compatible version. Unlike the other commands, the lengths of these strings are specified by 4 byte values. If the Short name length is 0 then the Short name field is omitted, and both names should be treated as being identical.

The Attributes consist of a combination of the following flags:

AttributeDescription
0x0001Read only
0x0002Hidden
0x0004System
0x0010Directory
0x0020Archive
0x0040Volume label
0x0080Normal
0x0100Temporary
0x0800Compressed

The Size is simply the length of the file in bytes.

The Modified low and Modified high fields combine to form a 64 bit modification date, specified as the number of micro-seconds since 00:00 on 1st January 1.

The UID 1, UID 2 and UID 3 fields are the first three words of the file, and indicate the type of data it contains. These fields are only valid if bit 28 (0x10000000) of the Attributes was passed to RFSV32_OPEN_DIR. The UIDs for some of the standard applications are:

ApplicationUID 1UID 2UID 3
Word0x100000370x1000006D0x1000007F
Sheet0x100000370x1000006D0x10000088
Record0x100000370x1000006D0x1000007E
OPL0x100000370x1000006D0x10000085
Data0x100000500x1000006D0x10000086
Agenda0x100000500x1000006D0x10000084
Sketch0x100000370x1000006D0x1000007D

The two Alignment fields ensure that the offset for the start of the following field is a multiple of 4 bytes.

RFSV32_GET_DRIVE_LIST
Command:

Bytes22
Data0x13Operation ID

Reply:

Bytes22426
Data0x11Operation IDStatus codeDrive list

Read the status of all drives.

A single byte is returned for each drive letter A: to Z:.

RFSV32_VOLUME
Command:

Bytes224
Data0x14Operation IDDrive

Reply:

Bytes2244444444444n
Data0x11Operation IDStatus codeMedia typeBattery statusDrive attributesMedia attributesUIDSize lowSize highFree lowFree highVolume label lengthVolume label

Read information about a single device.

The Drive is the number of the device, from 0 for A: to 25 for Z:.

The Media type may be one of the following:

Media typeDescription
0Not present
1Not a known type
2Floppy disk
3Hard disk
4CD-ROM
5RAM
6Flash disk
7ROM
8Remote

The Battery status may be one of the following:

Battery statusDescription
0Dead
1Very low
2Low
3Good

The Drive attributes consists of the following flags:

Drive attributeDescription
0x01Local
0x02ROM
0x04Redirected
0x08Substituted
0x10Internal
0x20Removable

The Media attributes consists of the following flags:

Media attributeDescription
0x01Variable size
0x02Dual density
0x04Formattable
0x08Write protected

The Size low and Size high fields combine to give the 64 bit total size, and the Free low and Free high fields combine to give the 64 bit remaining free space on the device.

Unlike the other commands, the length of the Volume label string is specified by the 4 byte Volume label length.

RFSV32_SET_VOLUME_LABEL
Command:

Bytes2242 + n
Data0x15Operation IDDriveVolume label

Reply:

Bytes224
Data0x11Operation IDStatus code

Set the Volume label of a device.

The Drive is the number of the device, from 0 for A: to 25 for Z:.

RFSV32_OPEN_FILE
Command:

Bytes2242 + n
Data0x16Operation IDModeFile name

Reply:

Bytes2244
Data0x11Operation IDStatus codeHandle

Open File name for reading or writing via the returned Handle.

The Mode consists of one of the following sharing types:

ModeDescription
0x0000Exclusive access
0x0001Share for read access
0x0002Share for any access

combined with one of these stream types:

ModeDescription
0x0000Open as a binary stream
0x0020Open as a text stream

and any of the following flags:

0X0200Open for read and write access

RFSV32_TEMP_FILE
Command:

Bytes2242 + n
Data0x17Operation IDModeFile name

Reply:

Bytes22442 + n
Data0x11Operation IDStatus codeHandleOpened name

Create a new file with a unique file name for reading or writing via the returned Handle.

See RFSV32_OPEN_FILE for a description of the possible Mode values.

The actual name of the file opened is returned as Opened name.

RFSV32_READ_FILE
Command:

Bytes2244
Data0x18Operation IDHandleLength

Reply:

Bytes224n
Data0x11Operation IDStatus codeData

Read Length bytes from the file identified by Handle.

The reply contains the Length bytes of data read.

RFSV32_WRITE_FILE
Command:

Bytes224n
Data0x19Operation IDHandle