Skip to content

EPITECH-Strasbourg-2021/CPP-Babel-Spec

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 

Repository files navigation

Babel Protocol: C++ Module (Strasbourg 2018)

This specification defines the protocol used in the Babel project as part of the EPITECH 2018 C++ module.

The protocol is to be used within a single connection.

The protocol is used for both client-server and client-client communication.
This is transport-layer agnostic (TCP, UDP or whatever).

WARNING: The protocol uses big-endian numbers.
WARNING: Don't forget to use #pragma pack() directives on each struct that you intend to directly read into or write from it.

Message structure

|__ size (4 bytes) __|__ type (1 byte) __|__ body (size bytes) __ ... __|

size is the size of the message body in bytes.
type is the message type.
body is the body/data of the message.

Message Size

This is the size of the message body, in bytes as a 4 bytes unsigned integer (uint32_t)

Message Type

This is the message type, as one byte (uint8_t). List of message types:

Client-Server

  • 00000000 (0) : Command::Ping
  • 10000000 (128) : Command::Pong
  • 00000001 (1) : Command::Login (request)
  • 10000001 (129) : Command::Login (response)
  • 00000010 (2) : Command::Logout (request)
  • 10000010 (130) : Command::Logout (response)
  • 00000011 (3) : Command::Register (request)
  • 10000011 (131) : Command::Register (response)
  • 00000100 (4) : Command::GetMessages (request)
  • 10000100 (132) : Command::GetMessages (response)
  • 00000101 (5) : Command::GetUsers (request)
  • 10000101 (133) : Command::GetUsers (response)
  • 00000110 (6) : Command::SendMessage (request)
  • 10000110 (134) : Command::SendMessage (response)
  • 00000111 (7) : Command::CallUser (request)
  • 10000111 (135) : Command::CallUser (response)
  • 00001101 (13) : Command::AddFriend (request)
  • 10001101 (141) : Command::AddFriend (response)
  • 00001110 (14) : Command::DelFriend (request)
  • 10001110 (142) : Command::DelFriend (response)

Server-Client

  • 00001000 (8) : Event::IncomingCall (event)
  • 10001000 (136) : Event::IncomingCall (response)
  • 00001010 (10) : Event::StatusUpdate (event)
  • 10001010 (138) : Event::StatusUpdate (response)
  • 00001011 (11) : Event::GetMessage (event)
  • 10001011 (139) : Event::GetMessage (response)
  • 00001111 (15) : Event::NewUser (event)
  • 10001111 (143) : Event::NewUser (response)

Client-Client

  • 00001100 (12) : Event::AudioFrame (event)

Prelude

These are types and defines that will be used throughout the specification.
It is strongly encouraged you use the exact same definitions of these types.

using u8 = uint8_t;
using u16 = uint16_t;
using u32 = uint32_t;
using i8 = int8_t;
using i16 = int16_t;
using i32 = int32_t;

#define STD_SIZE (256)
#define MSG_SIZE (1024)

/*
** This define is optional.
** It just allows to pack a struct
** by annotating it like this:
** 
**   PACK(struct Test {
**       bool status;
**       u32 id;
**   });
*/
#ifdef _MSC_VER
# define PACK(d) __pragma(pack(push, 1)) d __pragma(pack(pop))
#else
# define PACK(d) d __attribute__((packed))
#endif

enum class Status : u8 {
    Disconnected = 0,
    Available,
    Away,
    Busy,
    Hidden
};

enum class Request : u8 {
    Ping = 0,
    Login,	
    Logout,
    Register,
    GetMessages,
    GetUsers,
    SendMessage,
    CallUser,
    IncomingCall,
    StatusUpdate = 10,
    GetMessage,
    AudioFrame,
    AddFriend,
    DelFriend
};

enum class Response : u8 {
    Pong = 128,
    Login,	
    Logout,
    Register,
    GetMessages,
    GetUsers,
    SendMessage,
    CallUser,
    IncomingCall,
    StatusUpdate = 138,
    GetMessage,
    AudioFrame,
    AddFriend,
    DelFriend
};
    
struct Msg {
    u32 sender;
    char msg[STD_SIZE];
};

namespace Command {
    // All commands go in this namespace
};

namespace Event {
    // All events go in this namespace
};

Command::Login

Request

struct LoginRequest {
    char login[STD_SIZE];
    char passwd[STD_SIZE];
    Status status;
};

Response

struct LoginResponse {
    bool status;
    u32 id;
    char nickname[STD_SIZE];
};

Command::Logout

Request

Zero-sized request.

struct LogoutRequest {};

Response

struct LogoutResponse {
    bool status;
};

Command::Register

Request

struct RegisterRequest {
    char login[STD_SIZE];
    char nickname[STD_SIZE];
    char passwd[STD_SIZE];
};

Response

struct RegisterResponse {
    bool status;
};

Command::GetMessages

Request

struct GetMsgRequest {
    u32 dest_id;
};

Response

//! Can't be read directly
// messages.size() == body_size / sizeof(Msg)
struct GetMsgResponse {
    std::vector<Msg> messages;
};

Command::GetUsers

enum class UserQuery : u8 {
    All = 0,
    Contact,
    Friend,
};

Request

struct GetUsersRequest {
    UserQuery type;
};

Response

enum class UserType : u8 {
    Contact = 0,
    Friend,
};

struct User {
    UserType type;
    u32 id;
    char name[STD_SIZE];
    Status status;
};

//! Can't be read directly
// users.size() == body_size / sizeof(User)
struct GetUsersResponse {
    std::vector<User> users;
};

Command::SendMessage

Request

struct SendMessageRequest {
    Msg msg;
};

Response

struct SendMessageResponse {
    bool success;
};

Command::AddFriend

Request

struct AddFriendRequest {
    u32 friend_id;
};

Response

struct AddFriendResponse {
    bool status;
};

Command::DelFriend

Request

struct DelFriendRequest {
    u32 friend_id;
};

Response

struct DelFriendResponse {
};

Command::CallUser

Request

struct CallUserRequest {
    u32 dest_id;
    u16 port;
    u32 sampleRate;
    u32 frameSize;
};

Response

struct CallUserResponse {
    bool accepted;
    u8 ip[4];
    u16 port;
};

Event::IncomingCall

Event

struct IncomingCallRequest {
    u32 dest_id;
    u8 ip[4];
    u16 port;
};

Response

struct IncomingCallResponse {
    bool accepted;
};

Event::GetMessage

Event

struct GetMessageRequest {
    Msg msg;
};

Response

struct GetMessageResponse {
};

Event::StatusUpdate

Event

struct StatusUpdateRequest {
    u32 id;
    Status newStatus;
};

Response

struct StatusUpdateResponse {
};

Event::NewUser

Event

struct NewUserRequest {
   User user;
};

Response

struct NewUserResponse {
};

Event::AudioFrame

Event

//! This can't be read directly
struct AudioFrameRequest {
    HeaderAudioPacket header;
    std::vector<unsigned char> packet;
};
struct HeaderAudioPacket {
   u32 size;
   u32 timestamp;
}

About

C++ Module: Babel Protocol Specification

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •