j200lx Project

Documentation: HP200LX Filer protocol

SourceForge Logo

HP200LX Filer communication protocol

In this document you found the description of the communication protocol that the Filer of the HP200lX uses.

Please don't hold me responsible for inaccuracies or errors, because I'm sure I've got some in here.

This document is part of proyect j200lx.

Rodrigo Serra
09/02/2002

Common Parts

Here are some common part of messages used in this document.

int PACKET_DATA_SIZE=0x800;

// Commands
char CMD_CONNECT_SERVER=0x40;
char CMD_DISCONNECT_SERVER=0x41;
char CMD_SEND_PATH=0x08;
char CMD_SEND_FILENAME=0x03;
char CMD_GET_FILENAME=0xB;
char CMD_REN_FILE=0xD;
char CMD_SEND_DATA=0x15;
char CMD_INIT_GET=0x16;
char CMD_GET_DATA=0xC;
char CMD_DATA_END=0x1;
char CMD_DEL_FILE=0x4;
char CMD_MAKE_DIR=0xA;
char CMD_DEL_DIR=0xE;
char CMD_ASK_DIR=0x12;
char CMD_GET_DIR=0x9;

Packet format

For every packet send another is resived. All the packet have the following structure:

Transmit

Packet Signature   CMD CNT DM DATA End CRC
0x16 0x16 0x16 0x10 0x02 0x01 ? ? 0x01 0x02 ... 0x10 0x03 L H

Receive

Packet Signature   CMD CNT STAT   DATA End CRC
0x16 0x16 0x16 0x10 0x02 0x01 ? ? ? 0x02 ... 0x10 0x03 L H

Thant means:

CMD is the command requested. See commands.
CNT: is a count of packed.
STAT is the result of the operation.
DATA is the data send to or from then palmotop.
underline indicate no CRC calculation for this byte/s.

CRC is constructed whit the calculating this  for every byte except the bytes preceded by the ! symbol. The following code calculate CRC for one byte.

        int i, polynomial = 0xa001;
        crc^=b;
        for(i=0;i<8;i++) crc = (crc >> 1) ^ ((crc & 1)!=0 ? polynomial : 0);

The following explanation of packet only show the command and DATA part of the packet. Data=null means no bytes transmited.

CONNECT

T: CMD=CMD_CONNECT_SERVER, DATA=null;
R: CMD=CMD_CONNECT_SERVER, STATUS=0x81, DATA=null;

DISCONNECT

T: CMD=CMD_DISCONNECT_SERVER, DATA=null;
R: CMD=CMD_DISCONNECT_SERVER, STATUS=0x81, DATA=null;

DEL DIR

T: CMD=CMD_DEL_DIR, DATA={DirectoryName[].length()%256,DirectoryName[].length()/256,DirectoryName[],0x00,0x00};
R: CMD=CMD_DEL_DIR, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

MK DIR

T: CMD=CMD_MAKE_DIR, DATA={DirectoryName[].length()%256,DirectoryName[].length()/256,DirectoryName[],0x00,0x00};
R: CMD=CMD_MAKE_DIR, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

DEL FILE

T: CMD=CMD_DEL_FILE, DATA={FileName[].length()%256,FileName[].length()/256,FileName[],0x00,0x00};
R: CMD=CMD_DEL_FILE, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

RENAME FILE OR DIR

T: CMD=CMD_REN_FILE, DATA={FileNameFrom[].length()%256,FileNameFrom[].length()/256,FileNameFrom[],FileNameTo[].length()%256,FileNameTo[].length()/256,FileNameTo[],0x00,0x00};
R: CMD=CMD_REN_FILE, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

LIST DIR

T: CMD=CMD_ASK_DIR, DATA={DirectoryName[].length()%256,DirectoryName[].length()/256,DirectoryName[],0x00,0x00};
R: CMD=CMD_ASK_DIR, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

T: CMD=CMD_GET_DIR, DATA=null;
R: CMD=CMD_GET_DIR, STATUS=0x81, DATA={0x00,0x00,DirEntry[].length()%256,dirEntry[].length()/256,dirEntry,LastEntry==0x01,0x00,0x00,0x00};
...
T: CMD=CMD_GET_DIR, DATA=null;
R: CMD=CMD_GET_DIR, STATUS=0x81, DATA={0x00,0x00,DirEntry[].length()%256,dirEntry[].length()/256,dirEntry,LastEntry==0x00,0x00,0x00,0x00};

Structure of dirEntry:

dirEntry[0]   =fileFlag;

dirEntry[1..4]=(UINT)timeStamp;
               (timeStamp>>>25)+1980=year;
               (timeStamp>>>21)&15=month;
               (timeStamp>>>16)&31=day;
               (timeStamp>>>11)&31=hours;
               (timeStamp>>>5)&63=minutes;
               (timeStamp&63=seconds;
               
dirEntry[5..8]=(UINT)size;

GET FILE

T: CMD=CMD_GET_FILENAME, DATA={FileName[].length()%256,FileName[].length()/256,FileName[],0x00,0x00};
R: CMD=CMD_GET_FILENAME, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

T: CMD=CMD_INIT_GET, DATA=null;
R: CMD=CMD_INIT_GET, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

T: CMD=CMD_GET_DATA, DATA={0x00,0x00,Buffer[].length()%256,Buffer[].length()/256};
R: CMD=CMD_GET_DATA, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,Buffer[].length()%256,Buffer[].length()/256,Buffer[]};
...
Last packet when T.Buffer.length() != R.Buffer.length()

T: CMD=CMD_DATA_END, DATA={0x00};
R: CMD=CMD_DATA_END, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};

SEND FILE

T: CMD=CMD_SEND_FILENAME, DATA={FileName[].length()%256,FileName[].length()/256,FileName[],0x00,0x00};
R: CMD=CMD_SEND_FILENAME, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,Buffer[].length()%256,Buffer[].length()/256};

T: CMD=CMD_SEND_DATA, DATA={0x00,0x00,Buffer[].length()%256,Buffer[].length()/256,Buffer[]};
R: CMD=CMD_SEND_DATA, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,Buffer[].length()%256,Buffer[].length()/256};
...
T: CMD=CMD_DATA_END, DATA={0x00};
R: CMD=CMD_DATA_END, STATUS=0x81, DATA={0x00,0x00,0x00,0x00,0x00,0x00};