Select Git revision
api.h 10.36 KiB
#ifndef API_H
#define API_H
#include <sys/types.h>
#include <msgpack.hpp>
#include <cstdint>
#include <string>
#define MSG_HDR(name, def_op) \
struct name : public rpc_msg {\
name() : rpc_msg{def_op} {}
#define SERIALISE(...) \
MSGPACK_DEFINE(op, __VA_ARGS__)
namespace blue
{
constexpr size_t MAX_RPC_MSG_SIZE = 4096;
/*
* This enum class listst all the RPC messages available for
* communication between the daemon and the client.
*
* Messages are grouped by OP_OPERATION_MSG, where OPERATION is a task
* to perform and MSG represents a message used to accomplish
* OPERATION. An example is the scan operation whose messages are
* named OP_SCAN_REQUEST, OP_SCAN_START, etc.
*
* After each message, a comment is present that describes what
* message type should be used to serialise and deserialise the
* message for that operation.
*
* An example is the OP_SCAN_ITEM message with type
* blue::msg_scan_item, which the client could deserialise as
*
* msgpack::object deserialised = oh.get();
* blue::msg_scan_item item;
* deserialised.convert(item);
* std::cout << item.name << std::endl;
*
* See bluecontrol/src/bluecontrol.cpp as reference.
*/
enum class rpc_op : uint32_t
{
OP_UNUSED = 0x0000,
/* Normal scan flow
* ================
*
* CLIENT DAEMON
* ----------------------
* -- OP_SCAN_REQUEST ->
* <- OP_SCAN_START --
* <- OP_SCAN_ITEM --
* .
* .
* .
* <- OP_SCAN_DONE --
*
* The client sends the daemon a OP_SCAN_REQUEST request and the
* daemon responds with OP_SCAN_START followed by zero or more
* OP_SCAN_ITEM messages followed by OP_SCAN_DONE.
*/
OP_SCAN_REQUEST, // blue::rpc_msg
OP_SCAN_START, // blue::rpc_msg
OP_SCAN_ITEM, // blue::msg_scan_item
OP_SCAN_DONE, // blue::rpc_msg
/*
* Normal pairing flow
* ===================
*
* CLIENT DAEMON
* ----------------------
* -- OP_PAIR_REQUEST ->
* <- OP_PAIR_START --
* <- OP_PAIR_DONE --
*
* The client initiates the pairing request and the daemon
* responds that it has stared followed by an indication that the
* pairing has completed.
*
* Trying to pair unknown device
* =============================
*
* CLIENT DAEMON
* ---------------------
* -- OP_PAIR_REQUEST ->
* <- OP_PAIR_UNKNOWN --
*
* The client initiates a pairing and the daemon responds that no
* device with that address is known.
*
* A pairing error occurred
* ========================
*
* CLIENT DAEMON
* ---------------------
* -- OP_PAIR_REQUEST ->
* <- OP_PAIR_START --
* <- OP_PAIR_ERROR --
*
* CLIENT DAEMON
* ---------------------
* -- OP_PAIR_REQUEST ->
* <- OP_PAIR_ERROR --
*
* An error occurred when trying to start the pairing process.
* The error can occur before or after OP_PAIR_START.
*
* The device is already paired
* ============================
*
* CLIENT DAEMON
* ----------------------------
* -- OP_PAIR_REQUEST ->
* <- OP_PAIR_ALREADY_PAIRED --
*
* The client tries to initiate a pairing with a device that is
* already considered paired. The client sends a OP_PAIR_REQUEST
* to the daemon that responds with OP_PAIR_ALREADY_PAIRED.
*/
OP_PAIR_REQUEST, // blue::msg_pair_request
OP_PAIR_START, // blue::rpc_msg
OP_PAIR_UNKNOWN, // blue::rpc_msg
OP_PAIR_ERROR, // blue::rpc_msg
OP_PAIR_DONE, // blue::rpc_msg
OP_PAIR_ALREADY_PAIRED, // blue::rpc_msg
/*
* List request flow
* =================
*
* CLIENT DAEMON
* ----------------------------
* -- OP_LIST_KNOWN_REQUEST ->
* <- OP_LIST_KNOWN_ITEM --
* .
* .
* .
* <- OP_LIST_KNOWN_ITEM --
* <- OP_LIST_KNOWN_DONE --
*
* A list request is sent to the daemon that responds with zero
* or more OP_LIST_KNOWN_ITEM messages followed by a
* OP_LIST_KNOWN_DONE message that indicates the end of the
* exchange.
*/
OP_LIST_KNOWN_REQUEST, // blue::rpc_msg
OP_LIST_KNOWN_ITEM, // blue::msg_known_item
OP_LIST_KNOWN_DONE, // blue::rpc_msg
/*
* Normal PIN setting flow
* =======================
*
* CLIENT DAEMON
* ------------------------
* -- OP_DEVICE_PIN_SET ->
* <- OP_DEVICE_PIN_DONE --
*
* The device sends a OP_DEVICE_PIN_SET request and the daemon
* sets the device PIN and responds with OP_DEVICE_PIN_DONE.
*
* Trying to set a too long PIN
* ============================
*
* CLIENT DAEMON
* ----------------------------
* -- OP_DEVICE_PIN_SET ->
* <- OP_DEVICE_PIN_TOO_LONG --
*
* The client sends a OP_DEVICE_PIN_SET request with a PIN that
* is too long and the daemon does not set the device PIN and
* replies with OP_DEVICE_PIN_TOO_LONG.
*
* Trying to set a PIN for an unknown device
* =========================================
*
* CLIENT DAEMON
* ---------------------------
* -- OP_DEVICE_PIN_SET ->
* <- OP_DEVICE_PIN_UNKNOWN --
*
* The client send a OP_DEVICE_PIN_SET with an unknown device
* address and the daemon replies with OP_DEVICE_PIN_UNKNOWN.
*/
OP_DEVICE_PIN_SET, // blue::msg_set_pin_request
OP_DEVICE_PIN_DONE, // blue::rpc_msg
OP_DEVICE_PIN_UNKNOWN, // blue::rpc_msg
OP_DEVICE_PIN_TOO_LONG, // blue::rpc_msg
/*
* Normal unpairing
* ================
*
* CLIENT DAEMON
* ------------------------
* -- OP_UNPAIR_REQUEST ->
* <- OP_UNPAIR_DONE --
*
* The client sends a OP_UNPAIR_REQUEST to the daemon, the daemon
* unpairs the device and replies with OP_UNPAIR_DONE.
*
* Device unknown
* ==============
*
* CLIENT DAEMON
* ------------------------
* -- OP_UNPAIR_REQUEST ->
* <- OP_UNPAIR_UNKNOWN --
*
* The client sends a OP_UNPAIR_REQUEST to the daemon but the
* daemon does not know the device and replies with
* OP_UNPAIR_UNKNOWN.
*
* Not paired
* ==============
*
* CLIENT DAEMON
* ------------------------
* -- OP_UNPAIR_REQUEST ->
* <- OP_UNPAIR_NOT_PAIRED --
*
* The client sends a OP_UNPAIR_REQUEST to the daemon but the
* device is not paired and can not be unpaired so the daemon
* responds with OP_UNPAIR_NOT_PAIRED.
*
* An error occurred
* =================
*
* CLIENT DAEMON
* ------------------------
* -- OP_UNPAIR_REQUEST ->
* <- OP_UNPAIR_ERROR --
*
* The client sends a OP_UNPAIR_REQUEST to the daemon but an error
* occurrs and the daemon responds with OP_UNPAIR_ERROR.
*/
OP_UNPAIR_REQUEST, // blue::msg_unpair_request
OP_UNPAIR_DONE, // blue::rpc_msg
OP_UNPAIR_UNKNOWN, // blue::rpc_msg
OP_UNPAIR_NOT_PAIRED, // blue::rpc_msg
OP_UNPAIR_ERROR, // blue::rpc_msg
/*
* Normal name request
* ===================
*
* CLIENT DAEMON
* --------------------------
* -- OP_NAME_REQUEST ->
* <- OP_NAME_REQUEST_DONE --
*
* The client sends a OP_NAME_REQUEST to the daemon that queries
* the device for its name. The daemon then responds with
* OP_NAME_REQUEST_DONE containing the human readable name of the
* device.
*
* Unknown device
* ==============
*
* CLIENT DAEMON
* -----------------------------
* -- OP_NAME_REQUEST ->
* <- OP_NAME_REQUEST_UNKNOWN --
*
* The client send a OP_NAME_REQUEST for a device not known by the
* daemon. The daemon responds with OP_NAME_REQUEST_UNKNOWN.
*
* An error occurs
* ===============
*
* CLIENT DAEMON
* ---------------------------
* -- OP_NAME_REQUEST ->
* <- OP_NAME_REQUEST_ERROR --
*
* The client send a OP_NAME_REQUEST to the daemon but an error
* occurs and the daemon responds with OP_NAME_REQUEST_ERROR.
*/
OP_NAME_REQUEST, // blue::msg_name_request
OP_NAME_REQUEST_DONE, // blue::msg_name_request_done
OP_NAME_REQUEST_UNKNOWN, // blue::rpc_msg
OP_NAME_REQUEST_ERROR, // blue::rpc_msg
/*
* Normal connection request
* ===================
*
* CLIENT DAEMON
* --------------------------------
* -- OP_CONNECTION_REQUEST ->
* <- OP_CONNECTION_REQUEST_DONE --
*
* The client sends a OP_CONNECTION_REQUEST to the daemon that
* tries to connect to the device and answers with
* OP_CONNECTION_REQUEST_DONE when connected.
*
* Unknown device
* ==============
*
* CLIENT DAEMON
* -----------------------------------
* -- OP_CONNECTION_REQUEST ->
* <- OP_CONNECTION_REQUEST_UNKNOWN --
*
* The user sends a OP_CONNECTION_REQUEST for an unknown device so
* the daemon can't connect and responds with
* OP_CONNECTION_REQUEST_UNKNOWN.
*
* An error occurs
* ===============
*
* CLIENT DAEMON
* ----------------------------------
* -- OP_CONNECTION_REQUEST ->
* <- OP_CONNECTION_REQUEST_FAILED --
*
* The client send a OP_CONNECTION_REQUEST to the daemon but an
* error occurs and the daemon responds with
* OP_CONNECTION_REQUEST_ERROR.
*/
OP_CONNECTION_REQUEST, // blue::msg_conn_request
OP_CONNECTION_REQUEST_DONE, // blue::rpc_msg
OP_CONNECTION_REQUEST_UNKNOWN, // blue::rpc_msg
OP_CONNECTION_REQUEST_ERROR, // blue::rpc_msg
};
// Header for all messages to easily extract the op field.
struct rpc_msg
{
rpc_op op;
MSGPACK_DEFINE(op);
};
// Scanning
MSG_HDR(msg_scan_item, rpc_op::OP_SCAN_ITEM)
std::string addr;
SERIALISE(addr);
};
// Pairing
MSG_HDR(msg_pair_request, rpc_op::OP_PAIR_REQUEST)
std::string addr;
SERIALISE(addr);
};
// Listing paired devices
MSG_HDR(msg_known_item, rpc_op::OP_LIST_KNOWN_ITEM)
std::string addr;
bool paired;
bool connected;
SERIALISE(addr, paired, connected);
};
// Set device PIN
MSG_HDR(msg_set_pin_request, rpc_op::OP_DEVICE_PIN_SET)
std::string addr;
std::string pin;
SERIALISE(addr, pin);
};
// Unpair a device
MSG_HDR(msg_unpair_request, rpc_op::OP_UNPAIR_REQUEST)
std::string addr;
SERIALISE(addr);
};
// Request a device name
MSG_HDR(msg_name_request, rpc_op::OP_NAME_REQUEST)
std::string addr;
SERIALISE(addr);
};
// addr - bdaddr, name - human readable name
MSG_HDR(msg_name_request_done, rpc_op::OP_NAME_REQUEST_DONE)
std::string addr;
std::string name;
SERIALISE(addr, name);
};
// Attempt to connect to device addr
MSG_HDR(msg_conn_request, rpc_op::OP_CONNECTION_REQUEST)
std::string addr;
SERIALISE(addr);
};
}
// Allow serialisation of blue::rpc_op
MSGPACK_ADD_ENUM(blue::rpc_op);
#endif // API_H