/*---------------------------------------------------------------------------*/
/* turn_stun.h                                                               */
/* copyright (c) innovaphone 2017                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#define TURN_ALLOCATE_REQUEST               0x0003
#define TURN_ALLOCATE_RESPONSE              0x0103
#define TURN_ALLOCATE_ERROR                 0x0113
#define TURN_REFRESH_REQUEST                0x0004
#define TURN_REFRESH_RESPONSE               0x0104
#define TURN_REFRESH_ERROR                  0x0114
#define TURN_SEND_INDICATION                0x0016
#define TURN_DATA_INDICATION                0x0017
#define TURN_CREATE_PERMISSION_REQUEST      0x0008
#define TURN_CREATE_PERMISSION_RESPONSE     0x0108
#define TURN_CREATE_PERMISSION_ERROR        0x0118
#define TURN_CHANNEL_BIND_REQUEST           0x0009
#define TURN_CHANNEL_BIND_RESPONSE          0x0109
#define TURN_CHANNEL_BIND_ERROR             0x0119
#define TURN_ERROR_TRY_ALTERNATE            0x300
#define TURN_ERROR_BAD_REQUEST              0x400
#define TURN_ERROR_UNAUTHORIZED             0x401
#define TURN_ERROR_FORBIDDEN                0x403
#define TURN_ERROR_UNKNOWN_ATTRIBUTE        0x414 // Class 4, number 20
#define TURN_ERROR_ALLOCATION_MISMATCH      0x425 // Class 4, number 37
#define TURN_ERROR_STALE_NONCE              0x426 // Class 4, number 38
#define TURN_ERROR_WRONG_CREDENTIALS        0x429 // Class 4, number 41
#define TURN_ERROR_UNSUPPORTED_TRANSPORT_ADDRESS 0x42a // Class 4, number 42
#define TURN_ERROR_ALLOCATION_QUOTA_REACHED 0x456 // Class 4, number 86
#define TURN_ERROR_SERVER_ERROR             0x500
#define TURN_ERROR_INSUFFICIENT_CAPACITY    0x508
#define TURN_FLAG_TRANSPORT_UDP             (17 << 24)  // protocol type for UDP packets
#define TURN_FLAG_TRANSPORT_MASK            0xff000000
#define TURN_FLAG_EVEN_PORT                 0x00000100
#define TURN_FLAG_RESERVE_NEXTHIGHER_PORT   0x00000080
#define TURN_FLAG_LIFETIME                  0x00000200
#define TURN_FLAG_DONT_FRAGMENT             0x00000400
#define TURN_FLAG_RESERVATION_TOKEN         0x00000800
#define TURN_FLAG_ERROR                     0x00001000
#define TURN_FLAG_ERROR_CODE                0x00002000
#define TURN_FLAG_REALM                     0x00004000
#define TURN_FLAG_NONCE                     0x00008000
#define TURN_FLAG_RELAYED_ADDR              0x00010000
#define TURN_FLAG_MAPPED_ADDR               0x00020000
#define TURN_FLAG_ALTERNATE_SERVER          0x00040000
#define TURN_FLAG_SLOW_SERVER               0x00080000

class TurnStun {
public:
    static void createId(OS_GUID * id);
    static char * writeAllocateRequest(OS_GUID *id, const char *username, const char *password, const char *realm, const char *nonce, dword flags, dword lifetime, byte reservationToken[8], int & len);
    static char * writeRefreshRequest(OS_GUID *id, const char *username, const char *password, const char *realm, const char *nonce, dword flags, dword lifetime, int & len);
    static char * writeChannelBindResponse(OS_GUID *id, word ch, const char *user, const char *pwd, const char *realm, int & len);
    static char * writeChannelBindRequest(OS_GUID *id, const char *username, const char *password, const char *realm, const char *nonce, word channelNumber, IPaddr addr, word port, int & len);
    static bool readAllocateResponse(char * data, int len, const char *username, const char *password, OS_GUID *id, char **realm, char **nonce, dword *flags, dword *errorCode, dword *lifetime, IPaddr * relayedAddr, word *relayedPort, IPaddr * mappedAddr, word *mappedPort, byte reservationToken[8], IPaddr * alternateAddr, word *alternatePort);
    static bool readRefreshResponse(char *data, int len, const char *username, const char *password, OS_GUID *id, char **realm, char **nonce, dword *flags, dword *errorCode, dword *lifetime);
    static bool readChannelBindResponse(char * data, int len, const char *username, const char *password, OS_GUID *id, char **realm, char **nonce, word *channelNumber, dword *flags, dword *errorCode);
    static const char * getErrorPhrase(dword code);
    static const char * getMessageType(char * data);
};
