/* Copyright (c) 2020-2022 The Creators of Simphone

   See the file COPYING.LESSER.txt for copying permission.
*/

#ifndef _PROTO_H_
#define _PROTO_H_

#define SIM_PROTO_PORT 443 /* port number to always listen to */

#define SIM_PROTO_VERSION_MAX 3        /* current protocol version */
#define SIM_PROTO_VERSION_MIN 2        /* minimal supported protocol version */
#define SIM_PROTO_VERSION_REVERSE (-1) /* connection reversal */

#define SIM_PROTO_PROXY_VERSION_MAX 2 /* current proxy protocol version */
#define SIM_PROTO_PROXY_VERSION_MIN 2 /* minimal supported proxy protocol version */

#define SIM_HANDSHAKE_TYPE_RSA "rsa-x"   /* XOR both RSA-encrypted values to produce a shared key */
#define SIM_HANDSHAKE_TYPE_EC "ec"       /* not sent over network (internal use) */
#define SIM_HANDSHAKE_TYPE_REVERSE "rev" /* not sent over network (internal use) */
#define SIM_SHAKEHAND_TYPE_CRYPT "crypt" /* handshake reply contains blk, encrypt and decrypt cipher */

/* handshake request (client-side) */

#define SIM_HANDSHAKE_TYPE "hs"        /* array of supported key exchange types */
#define SIM_HANDSHAKE_TAG_SIZE "blk"   /* tag/IV size of the client side */
#define SIM_HANDSHAKE_PREFERRED "pref" /* array of preferred cipher identifiers */
#define SIM_HANDSHAKE_SUPPORTED "supp" /* array of non-preferred cipher identifiers */

/* handshake reply (server-side) */

#define SIM_SHAKEHAND_TYPE "sh"         /* chosen key exchange type (SIM_HANDSHAKE_TYPE_CRYPT (values below) or SIM_HANDSHAKE_TYPE_RSA) */
#define SIM_SHAKEHAND_TAG_SIZE "blk"    /* tag/IV size of the server side */
#define SIM_SHAKEHAND_ENCRYPT "encrypt" /* server encrypt (client decrypt) cipher (encrypted string) */
#define SIM_SHAKEHAND_DECRYPT "decrypt" /* server decrypt (client encrypt) cipher (encrypted string) */

/* key revocation (both sides) */

#define SIM_REQUEST_REVOKE "REVOKE" /* irreversible key revocation */
#define SIM_REPLY_REVOKE "REVOKED"  /* key revocation has been accepted */

/* handshake version request (TCP) */

#define SIM_REQUEST "vereq"         /* SIM_PROTO_VERSION_xxx */
#define SIM_REQUEST_AGE "age"       /* login time milliseconds before now */
#define SIM_REQUEST_RANDOM "rnd"    /* simself.nonce[0], for detecting connection from myself */
#define SIM_REQUEST_SEQUENCE "seq"  /* initial sequence number for successfully reversed connection */
#define SIM_REQUEST_TO "to"         /* ip address this connection was established to (ASCII string) */
#define SIM_REQUEST_TO_PORT "top"   /* port number this connection was established to */
#define SIM_REQUEST_PROXY_IP "pip"  /* ip addresses of proxy (array of ASCII string). not present if no proxy */
#define SIM_REQUEST_PROXY_PORT "pp" /* listening ports of proxy (array of number). not present if no proxy */
#define SIM_REQUEST_IP "gip"        /* own ip addresses (array of ASCII strings) if known */
#define SIM_REQUEST_PORT "gp"       /* listening ports (array of numbers) */
#define SIM_REQUEST_LOCAL_IP "lip"  /* local ip addresses (array of ASCII string) */
#define SIM_REQUEST_LOCAL_PORT "lp" /* local listening ports (array of number) */
#define SIM_REQUEST_ACK "ack"       /* 62-bit number of last received message (zero if unknown) */
#define SIM_REQUEST_CODECS "acs"    /* array of supported audio codec names */
#define SIM_REQUEST_FLAGS "flags"   /* SIM_REQUEST_FLAG_xxx | SIM_REPLY_FLAG_VERIFY_xxx. array of strings when sent over network */
#define SIM_REQUEST_BAD "bad"       /* name of insecure operating system (array of string). missing if secure */
#define SIM_REQUEST_ID "cid"        /* permanent 61-bit computer identifier for file transfers */

#define SIM_REQUEST_FLAG_VERIFY 16   /* verify my (proxy) ip address */
#define SIM_REPLY_FLAG_VERIFY_OK 32  /* willing to verify my (proxy) ip address */
#define SIM_REPLY_FLAG_VERIFY_NOK 64 /* not willing to verify my (proxy) ip address */

/* handshake version reply (TCP) */

#define SIM_REPLY "verep"         /* SIM_PROTO_VERSION_xxx or SIM_CMD_REVERSED */
#define SIM_REPLY_AGE "age"       /* login time milliseconds before now */
#define SIM_REPLY_RANDOM "rnd"    /* simself.nonce[1], for detecting connection to myself */
#define SIM_REPLY_SEQUENCE "seq"  /* initial sequence number for successfully reversed connection */
#define SIM_REPLY_FROM "from"     /* ip address this connection was received from (ASCII string) */
#define SIM_REPLY_IP "gip"        /* own ip addresses (array of ASCII strings) if known */
#define SIM_REPLY_PORT "gp"       /* listening ports (array of numbers) */
#define SIM_REPLY_LOCAL_IP "lip"  /* local ip addresses (array of ASCII string) */
#define SIM_REPLY_LOCAL_PORT "lp" /* local listening ports (array of number) */
#define SIM_REPLY_ACK "ack"       /* 62-bit number of last received message (zero if unknown) */
#define SIM_REPLY_CODECS "acs"    /* array of supported audio codec names */
#define SIM_REPLY_LOGON "logon"   /* minimally desired logon (version/status) period in seconds */
#define SIM_REPLY_FLAGS "flags"   /* SIM_REPLY_FLAG_xxx. array of strings when sent over network */
#define SIM_REPLY_BAD "bad"       /* name of insecure operating system (array of string). missing if secure */
#define SIM_REPLY_ID "cid"        /* permanent 61-bit computer identifier for file transfers */

#define SIM_REPLY_FLAG_MSG 1     /* pending messages (request connect) */
#define SIM_REPLY_FLAG_PROXY 2   /* willing to serve as a proxy */
#define SIM_REPLY_FLAG_CONNECT 4 /* was already trying to connect (connection accepted while connecting) */

/* UDP control packet (sent over UDP) */

#define SIM_CMD_UDP "udp"         /* SIM_CMD_UDP_REQUEST, SIM_CMD_UDP_ACK or SIM_CMD_UDP_CALL */
#define SIM_CMD_UDP_REQUEST "req" /* request UDP communication */
#define SIM_CMD_UDP_ACK "ack"     /* reply to UDP request (switch audio port to UDP) */
#define SIM_CMD_UDP_CALL "cal"    /* reply to UDP acknowledge (switch audio port to UDP) */

#define SIM_CMD_UDP_TIME "T"      /* incremental 62-bit timestamp; usually the same as SIM_CMD_AUDIO_NUMBERS_TIME */
#define SIM_CMD_UDP_SRC_IP "sip"  /* ip address UDP packet was received from */
#define SIM_CMD_UDP_SRC_PORT "sp" /* port number UDP packet was received from */
#define SIM_CMD_UDP_DST_IP "dip"  /* ip address UDP packet was sent to */
#define SIM_CMD_UDP_DST_PORT "dp" /* port number UDP packet was sent to */

#define SIM_CMD_UDP_PAD "pad" /* pad to audio packet size to make sure audio packets will flow as well */

/* TCP commands */

#define SIM_CMD ""        /* SIM_CMD_xxx */
#define SIM_CMD_BYE "BYE" /* disconnect request; no other keys */

/* latency reporting */

#define SIM_CMD_PING "ping"               /* keep-alive request; three optional keys (SIM_CMD_PxNG_PAD, SIM_CMD_PING_PONG and SIM_CMD_PING_PONG_NUMBER) */
#define SIM_CMD_PING_PAD "ping"           /* pad ping packet to the requested size (string) */
#define SIM_CMD_PING_PONG "ms"            /* number of milliseconds since connection was established */
#define SIM_CMD_PING_PONG_NUMBER "num"    /* user-supplied number */
#define SIM_CMD_PING_TICK "tick"          /* not sent over network (tick when ping was received) */
#define SIM_CMD_PING_NUMBER_LATENCY (-1)  /* sim_contact_get_(CONTACT_BIT_LATENCY) */
#define SIM_CMD_PING_NUMBER_TYPING (-2)   /* typing notification ping */
#define SIM_CMD_PING_NUMBER_CONSOLE (-99) /* console ping command */

#define SIM_CMD_PONG "pong"           /* keep-alive reply; echoes all keys of ping packet. one optional key or four additional (if currently talking) */
#define SIM_CMD_PONG_PAD "pong"       /* pad ping and pong packet to the requested size (string) */
#define SIM_CMD_PONG_AUDIO_READ "AR"  /* CONTACT_FRAMES_READ (missing if zero) */
#define SIM_CMD_PONG_AUDIO_WRITE "AW" /* CONTACT_FRAMES_WRITE (missing if zero) */
#define SIM_CMD_PONG_AUDIO_ALL "AA"   /* CONTACT_FRAMES_ALL (missing if zero) */
#define SIM_CMD_PONG_AUDIO_LOST "AL"  /* CONTACT_FRAMES_LOST (missing if zero) */

/* status command */

#define SIM_CMD_STATUS "status"     /* status change */
#define SIM_CMD_STATUS_STATUS "s"   /* SIM_STATUS_xxx (see below). string when sent over network. SIM_CMD_STATUS_RIGHTS is array of strings */
#define SIM_CMD_STATUS_RIGHTS "f"   /* CONTACT_FLAG_VERIFY | CONTACT_FLAG_UTF | CONTACT_FLAG_AUDIO | CONTACT_FLAG_TYPING | CONTACT_FLAG_TYPE | \
                                       CONTACT_FLAG_ECHO_CANCEL_Y | CONTACT_FLAG_ECHO_CANCEL_N */
#define SIM_CMD_STATUS_EDIT "em"    /* number of last sent messages that should be edited or zero to disallow */
#define SIM_CMD_STATUS_NICK "nick"  /* nickname */
#define SIM_CMD_STATUS_LINE "line"  /* info line */
#define SIM_CMD_STATUS_HOSTS "host" /* DNS hosts array of strings ("client.host") */

#define SIM_MAX_HOST_COUNT 2    /* maximal number of hosts that can be stored */
#define SIM_MAX_HOST_LENGTH 255 /* maximal length of hostname */

#define SIM_STATUS_MIN (-2)       /* minimal possible status for UI */
#define SIM_STATUS_IDLE (-2)      /* auto-away (idle). not sent over network */
#define SIM_STATUS_INVISIBLE (-1) /* invisible (connected to the DHT but appear offline). not sent over network */
#define SIM_STATUS_OFF 0          /* offline (not connected to the DHT) */
#define SIM_STATUS_ON 1           /* online (available) */
#define SIM_STATUS_AWAY 2         /* away from keyboard */
#define SIM_STATUS_BUSY 3         /* do not disturb (no playing of sounds) */
#define SIM_STATUS_HIDE 4         /* UI not currently visible */
#define SIM_STATUS_MAX 4          /* maximal possible status for UI */

/* chat message commands */

#define SIM_CMD_ACK "ack"      /* acknowledge chat message; only key is SIM_CMD_ACK_HANDLE */
#define SIM_CMD_ACK_HANDLE "a" /* 62-bit number of last received message (zero if unknown) */

#define SIM_CMD_MSG "ms"         /* chat message */
#define SIM_CMD_MSG_TYPE "k"     /* message type string (missing for SIM_MSG_TYPE_UTF) */
#define SIM_CMD_MSG_TEXT "m"     /* chat message in UTF-8 */
#define SIM_CMD_MSG_HANDLE "n"   /* 62-bit number of message (zero for local messages) */
#define SIM_CMD_MSG_ACK "a"      /* 62-bit number of last received message (zero if unknown) */
#define SIM_CMD_MSG_EDIT "e"     /* 62-bit original number of message (missing if message is not being edited) */
#define SIM_CMD_MSG_TIME "t"     /* time when message was sent; sent over network as a time delta to the past */
#define SIM_CMD_MSG_SENDER "u"   /* not sent over network: nickname of user who sent the message */
#define SIM_CMD_MSG_STATUS "s"   /* not sent over network: SIM_MSG_INCOMING if received, SIM_MSG_xxx if sent */
#define SIM_CMD_MSG_RECEIVED "r" /* not sent over network: time when message arrived */
#define SIM_CMD_MSG_NICK "c"     /* not sent over network: nickname of contact */

#define SIM_CMD_MANY "msg"   /* multiple command tables */
#define SIM_CMD_MANY_ACK "a" /* 62-bit number of last received message (zero if unknown) */
#define SIM_CMD_MANY_MSG "M" /* array of command tables */

/* file transfer commands */

#define SIM_CMD_XFER_INIT_PAUSE_ALL (-1) /* pause all transfers */
#define SIM_CMD_XFER_INIT_PAUSE_NONE 1   /* unpause all transfers */

#define SIM_CMD_XFER_INIT "fp"       /* configure file transfer parameters */
#define SIM_CMD_XFER_INIT_PAUSE "n"  /* 62-bit number of file transfer to start or SIM_CMD_XFER_INIT_PAUSE_xxx */
#define SIM_CMD_XFER_INIT_NAME "fn"  /* number of bytes of assumed overhead per file name */
#define SIM_CMD_XFER_INIT_NAMES "fm" /* maximal accepted number of bytes of file names */

#define SIM_CMD_XFER_SEND "fs"       /* initiate file transfer */
#define SIM_CMD_XFER_SEND_TYPE "k"   /* file type string (missing for XFER_TYPE_DATA) */
#define SIM_CMD_XFER_SEND_NAME "m"   /* file name in UTF-8 (missing if already known) */
#define SIM_CMD_XFER_SEND_HANDLE "n" /* 62-bit number of file transfer. missing when only replying to SIM_CMD_XFER_INIT */
#define SIM_CMD_XFER_SEND_SIZE "fs"  /* file size in bytes */
#define SIM_CMD_XFER_SEND_TIME "t"   /* time when file was sent (sent over network as a delta to the past) */

#define SIM_CMD_XFER_RECV "fr"       /* accept or refuse file transfer */
#define SIM_CMD_XFER_RECV_HANDLE "n" /* 62-bit number of file transfer */
#define SIM_CMD_XFER_RECV_HASH "md5" /* contents of existing file (binary string). missing if only sending a check reply */
#define SIM_CMD_XFER_RECV_SIZE "fs"  /* existing file size (positive if resuming, negative if refusing) */

#define SIM_CMD_XFER_DATA "f"       /* send data fragment */
#define SIM_CMD_XFER_DATA_BYTES "d" /* data fragment (binary string) */

#define SIM_CMD_XFER_OFFSET "fo"        /* some data fragments have been received */
#define SIM_CMD_XFER_OFFSET_SIZE "fs"   /* current position (size) of received file in bytes */
#define SIM_CMD_XFER_OFFSET_SPEED "bps" /* current speed limit (bytes per second) or zero if none */

#define SIM_CMD_XFER_CLOSE "fc"        /* file transfer completed */
#define SIM_CMD_XFER_CLOSE_HANDLE "n"  /* 62-bit number of file transfer */
#define SIM_CMD_XFER_CLOSE_HASH "md5"  /* contents of whole file (binary string) if any */
#define SIM_CMD_XFER_CLOSE_TIME "ft"   /* file time in nanoseconds (missing if unknown) */
#define SIM_CMD_XFER_CLOSE_ERROR "err" /* code of final error. missing when only checking if transfer exists */

#define SIM_CMD_XFER_END "fe"        /* file transfer finished or pause/unpause processed */
#define SIM_CMD_XFER_END_HANDLE "n"  /* 62-bit number of file transfer or zero if unpause has been received */
#define SIM_CMD_XFER_END_ERROR "err" /* control error code */

/* audio call commands */

#define SIM_CMD_CALL "call"              /* initiate or answer audio call */
#define SIM_CMD_CALL_CODEC "ac"          /* audio codec name (SIM_CMD_CALL_CODEC_SPEEX) */
#define SIM_CMD_CALL_CODEC_SPEEX "speex" /* the only currently supported codec */
#define SIM_CMD_CALL_SAMPLE "hz"         /* desired sample rate: integer Hz (negative if fixed) or zero for default */
#define SIM_CMD_CALL_QUALITY "sq"        /* desired (minimal) speex quality level (0 to 10) */
#define SIM_CMD_CALL_FRAMES "fpp"        /* desired (maximal) frame aggregation latency (milliseconds) */
#define SIM_CMD_CALL_MTU "mtu"           /* desired maximal packet size (bytes) */
#define SIM_CMD_CALL_ECHO "echo"         /* echo canceller tail length (value of speex.echo) */

#define SIM_CMD_RING "ring"            /* call was received and i am now ringing (if no other keys) */
#define SIM_CMD_RING_SAMPLE "hz"       /* set sample rate (zero when answering a call, negative if not changed) */
#define SIM_CMD_RING_QUALITY "sq"      /* set speex quality level */
#define SIM_CMD_RING_FRAMES "fpp"      /* set frame aggregation latency (milliseconds) */
#define SIM_CMD_RING_LATENCY "latency" /* chosen audio latency (milliseconds) */
#define SIM_CMD_RING_LATENCY_ADD "add" /* chosen additional (incoming) latency (milliseconds) */

#define SIM_CMD_HANGUP "hangup"    /* terminate or refuse audio call */
#define SIM_CMD_HANGUP_ERROR "err" /* SIM_OK or code of error which caused the hangup */

#define SIM_CMD_REQUEST_CALL "req-call"  /* request a sample rate change */
#define SIM_CMD_REQUEST_CALL_SAMPLE "hz" /* desired sample rate (positive) */

#define SIM_CMD_REPLY_CALL "r-call"    /* accept or reject a sample rate change */
#define SIM_CMD_REPLY_CALL_SAMPLE "hz" /* accepted sample rate (positive). missing if rejected */

#define SIM_CMD_AUDIO_DATA 1    /* index of encoded audio frames (array of string) */
#define SIM_CMD_AUDIO_NUMBERS 2 /* index of numbers array (five indexes defined below) */

#define SIM_CMD_AUDIO_NUMBERS_TIME 1    /* 62-bit timestamp in audio frames: initial value is random */
#define SIM_CMD_AUDIO_NUMBERS_PING 2    /* number of milliseconds since connection was established (ping request sent on demand) */
#define SIM_CMD_AUDIO_NUMBERS_PONG 3    /* number of milliseconds since connection was established (ping reply) */
#define SIM_CMD_AUDIO_NUMBERS_PROXY 4   /* packet round-trip time to proxy in milliseconds (sent with SIM_CMD_AUDIO_NUMBERS_PONG) */
#define SIM_CMD_AUDIO_NUMBERS_LATENCY 5 /* packet round-trip time in milliseconds (sent with SIM_CMD_AUDIO_NUMBERS_PONG) */

/* connection reversal */

#define SIM_CMD_REVERSE "reverse"       /* connection reversal attempt; no other keys */
#define SIM_CMD_REVERSING "reversing"   /* request connection reversal attempt; no other keys */
#define SIM_CMD_REVERSEND "reverse-end" /* reversal attempts have finished; no other keys */
#define SIM_CMD_REVERSED "reversed"     /* reversal has succeeded; no other keys */

/* NAT traversal request and reply */

#define SIM_CMD_TRAVERSE_INIT "tr-init"       /* reversal has failed on the client; start initial traversal attempt on the server */
#define SIM_CMD_TRAVERSE_START "tr-start"     /* traversal request */
#define SIM_CMD_TRAVERSE_RESTART "tr-restart" /* repeated traversal request */
#define SIM_CMD_TRAVERSE_INVERSE "tr-inverse" /* inverse traversal request and request repeat */
#define SIM_CMD_TRAVERSE_INVERSED "tr-stop"   /* last inverse traversal request */
#define SIM_CMD_TRAVERSE_REPLY "tr-reply"     /* traversal reply (accept or reject) */

#define SIM_CMD_TRAVERSE_TIME "timeout" /* minimal duration of traversal attempt (seconds) */
#define SIM_CMD_TRAVERSE_DELAY "delay"  /* number of milliseconds to starting traversal (not sent by replier) */
#define SIM_CMD_TRAVERSE_PORT "port"    /* real port number of requester or replier */
#define SIM_CMD_TRAVERSE_DELTA "delta"  /* port delta of requester's or replier's NAT (not sent with SIM_CMD_TRAVERSE_RESTART/SIM_CMD_TRAVERSE_INVERSED) */
#define SIM_CMD_TRAVERSE_RANDOM "rnd"   /* 62-bit random nonce for authenticating successful traversal (not sent by replier) */

#define SIM_CMD_TRAVERSE_TIME_ABORT (-99) /* SIM_CMD_TRAVERSE_TIME value for SIM_CMD_TRAVERSE_REPLY: no traversal */
#define SIM_CMD_TRAVERSE_TIME_REJECT 0    /* SIM_CMD_TRAVERSE_TIME value for SIM_CMD_TRAVERSE_REPLY: no traversal now */

/* NAT traversal success */

#define SIM_CMD_TRAVERSED "traversed"    /* three keys below sent only over traversed connection */
#define SIM_CMD_TRAVERSED_RANDOM "rnd"   /* 62-bit random nonce (same value as the one sent by SIM_CMD_TRAVERSE) */
#define SIM_CMD_TRAVERSED_SEQUENCE "seq" /* initial sequence number for successfully traversed connection */
#define SIM_CMD_TRAVERSED_ACK "ack"      /* number of times to repeat traversal success packet */

/* connection drop notification (sent by server) */

#define SIM_CMD_DUPLICATE "req-drop"   /* duplicate connection received and ignored */
#define SIM_CMD_DUPLICATE_IP "ips"     /* ip addresses of duplicate connecter (array of ASCII string) */
#define SIM_CMD_DUPLICATE_PORT "ports" /* ports of duplicate connecter (array of number) */

/* verify own ip address */

#define SIM_CMD_REQUEST_VERIFY "req-verify" /* request proxy verification */
#define SIM_CMD_REQUEST_VERIFY_IP "ips"     /* own proxy ip addresses (array of ASCII string) */
#define SIM_CMD_REQUEST_VERIFY_PORT "ports" /* own proxy ports (array of number) */

#define SIM_CMD_REPLY_VERIFY "r-verify"    /* report verification willingness */
#define SIM_CMD_REPLY_VERIFY_FLAGS "flags" /* SIM_REPLY_FLAG_VERIFY_xxx. string when sent over network */

/* exchange information about proxy service */

#define SIM_CMD_REQUEST_PROXY "req-proxy" /* request proxy service (if no other keys) or report my own proxy */
#define SIM_CMD_REQUEST_PROXY_IP "pip"    /* own proxy ip addresses (array of ASCII string) */
#define SIM_CMD_REQUEST_PROXY_PORT "pp"   /* own proxy ports (array of number) */

#define SIM_CMD_REPLY_PROXY "r-proxy" /* proxy service available; no other keys if i am providing it */
#define SIM_CMD_REPLY_PROXY_IP "pip"  /* proxy ip addresses (array of ASCII string) */
#define SIM_CMD_REPLY_PROXY_PORT "pp" /* proxy ports (array of number) */

/* proxy version request */

#define SIM_PROXY_REQUEST "version"       /* SIM_PROTO_PROXY_VERSION_xxx */
#define SIM_PROXY_REQUEST_IP "ip"         /* ip address this connection was established to (ASCII string) */
#define SIM_PROXY_REQUEST_PORT "port"     /* port number this connection was established to */
#define SIM_PROXY_REQUEST_CIPHER "cipher" /* array of supported cipher identifiers */

/* proxy version reply */

#define SIM_PROXY_REPLY "vers"          /* SIM_PROTO_PROXY_VERSION_xxx */
#define SIM_PROXY_REPLY_VERSION "ver"   /* SIM_PROXY_REQUEST of connected server (missing if not a client connection) */
#define SIM_PROXY_REPLY_IP "ip"         /* real ip address of version requester (ASCII string) */
#define SIM_PROXY_REPLY_PORT "port"     /* source port number of version requester */
#define SIM_PROXY_REPLY_CIPHER "chosen" /* chosen cipher; zero if server (single encryption) instead of a proxy */
#define SIM_PROXY_REPLY_SPEED "speed"   /* array of two numbers: minimal and maximal speed limit (optional) */

/* proxy server (customer) protocol */

#define SIM_SERVER_CMD "c"         /* SIM_SERVER_CMD_xxx. missing if SIM_SERVER_DATA is present */
#define SIM_SERVER_DATA "*"        /* packet bytes to forward. missing if SIM_SERVER_CMD is present */
#define SIM_SERVER_DATA_NUMBER "#" /* connection (client) number. missing if SIM_SERVER_CMD is present */
#define SIM_SERVER_DATA_CYCLES "@" /* not sent over network */

#define SIM_SERVER_CMD_HANDSHAKE "handshake"     /* handshake from proxy to server (customer) if ip present or else report disconnect reason */
#define SIM_SERVER_CMD_HANDSHAKE_ERROR "err"     /* error code that indicates reason for refusal of proxy service (SIM_OK if no refusal) */
#define SIM_SERVER_CMD_HANDSHAKE_PROXY_IP "pip"  /* real ip addresses of proxy (array of ASCII string). not present on (disconnect) error */
#define SIM_SERVER_CMD_HANDSHAKE_PROXY_PORT "pp" /* listening ports of proxy (array of number). not present on (disconnect) error */

#define SIM_SERVER_CMD_SHAKEHAND "shakehand"   /* handshake from server (customer) to proxy or/and request resource allocation. three optional keys */
#define SIM_SERVER_CMD_SHAKEHAND_PORT "p"      /* listening ports (array of numbers) of customer (zero/missing if reverse connection check not desired) */
#define SIM_SERVER_CMD_SHAKEHAND_SPEED "speed" /* array of two numbers: minimal and maximal speed limit. zero limit means deallocate(d) */
#define SIM_SERVER_CMD_SHAKEHAND_NUMBER "#"    /* connection (client) number. missing if not allocating/deallocating with a specific client */

#define SIM_SERVER_CMD_SHAKEHAND_REPLY "limits"    /* proxy resource report; three optional keys (the two keys above and the two keys below) */
#define SIM_SERVER_CMD_SHAKEHAND_SOCKETS "sockets" /* array of three numbers: minimal and maximal socket limit */
#define SIM_SERVER_CMD_SHAKEHAND_TIMES "times"     /* array of number (value of limit.time in milliseconds) */

#define SIM_SERVER_CMD_CONNECT "connect"     /* new connection from client (only sent by proxy). three or four keys */
#define SIM_SERVER_CMD_CONNECT_VERSION "ver" /* SIM_PROXY_REQUEST of connecting client */
#define SIM_SERVER_CMD_CONNECT_IP "ip"       /* real ip address of connecting client (ASCII string). missing if my ip (local) */
#define SIM_SERVER_CMD_CONNECT_NUMBER "#"    /* connection (client) number */
#define SIM_SERVER_CMD_CONNECT_BUFSIZE "bs"  /* required socket buffer size (zero if not known) */

#define SIM_SERVER_CMD_PING "ping"     /* ping request; two optional keys (SIM_SERVER_CMD_PING_PONG and SIM_SERVER_CMD_PxNG_PAD) */
#define SIM_SERVER_CMD_PONG "pong"     /* ping reply; two optional keys (SIM_SERVER_CMD_PING_PONG and SIM_SERVER_CMD_PONG_PAD) */
#define SIM_SERVER_CMD_PING_PONG "ms"  /* number of milliseconds since server connection was established */
#define SIM_SERVER_CMD_PING_PAD "ping" /* pad ping packet to the requested size (string) */
#define SIM_SERVER_CMD_PONG_PAD "pong" /* pad ping and pong packet to the requested size (string) */

#define SIM_SERVER_CMD_END "end"       /* close client connection. two other keys (SIM_SERVER_CMD_END_ERROR and SIM_SERVER_DATA_NUMBER) */
#define SIM_SERVER_CMD_END_ERROR "err" /* error code which caused the disconnect */

/* proxy client protocol */

#define SIM_CLIENT_CMD "k"         /* SIM_CLIENT_CMD_xxx. missing if SIM_CLIENT_DATA is present */
#define SIM_CLIENT_DATA "*"        /* packet bytes to forward. missing if SIM_CLIENT_CMD is present */
#define SIM_CLIENT_DATA_NUMBER "#" /* random 16-bit number. missing if SIM_CLIENT_CMD is present */

#define SIM_CLIENT_CMD_PING "PING"    /* ping request (usually sent from proxy to client); one optional key (SIM_CLIENT_CMD_PING_PONG) */
#define SIM_CLIENT_CMD_PONG "PONG"    /* ping reply (usually sent from client to proxy); one optional key (SIM_CLIENT_CMD_PING_PONG) */
#define SIM_CLIENT_CMD_PING_PONG "ms" /* number of milliseconds since client connection was established */

#define SIM_CLIENT_CMD_END "bye"       /* connection is about to close (only sent from proxy to client). one other key */
#define SIM_CLIENT_CMD_END_ERROR "err" /* error code which caused the disconnect */

#endif
