blob: 3e6d968f7cb6774dc66eb261194c7759fba91f48 [file] [log] [blame]
#pragma once
#include "slp_service_info.hpp"
#include <stdio.h>
#include <array>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <string>
#include <tuple>
#include <vector>
namespace slp
{
using buffer = std::vector<uint8_t>;
template <typename T>
using deleted_unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;
namespace request
{
/*
* @struct ServiceType
*
* SLP Message structure for ServiceType Request.
*/
struct ServiceType
{
std::string prList;
std::string namingAuth;
std::string scopeList;
};
/*
* @struct Service
*
* SLP Message structure for Service Request.
*/
struct Service
{
std::string prList;
std::string srvType;
std::string scopeList;
std::string predicate;
std::string spistr;
};
} // namespace request
/*
* @enum FunctionType
*
* SLP Protocol supported Message types.
*/
enum class FunctionType : uint8_t
{
SRVRQST = 0x01,
SRVRPLY = 0x02,
ATTRRQST = 0x06,
ATTRRPLY = 0x07,
SRVTYPERQST = 0x09,
SRVTYPERPLY = 0x0A,
SAADV = 0x0B,
};
/*
* @enum Error
*
* SLP Protocol defined Error Codes.
*/
enum class Error : uint8_t
{
LANGUAGE_NOT_SUPPORTED = 0x01,
PARSE_ERROR = 0x02,
INVALID_REGISTRATION = 0x03,
SCOPE_NOT_SUPPORTED = 0x04,
AUTHENTICATION_UNKNOWN = 0x05,
AUTHENTICATION_ABSENT = 0x06,
AUTHENTICATION_FAILED = 0x07,
VER_NOT_SUPPORTED = 0x09,
INTERNAL_ERROR = 0x0A,
DA_BUSY_NOW = 0x0B,
OPTION_NOT_UNDERSTOOD = 0x0C,
INVALID_UPDATE = 0x0D,
MSG_NOT_SUPPORTED = 0x0E,
};
/*
* @struct Header
*
* SLP Protocol Header
*/
struct Header
{
uint8_t version = 0;
uint8_t functionID = 0;
std::array<uint8_t, 3> length;
uint16_t flags = 0;
std::array<uint8_t, 3> extOffset;
uint16_t xid = 0;
uint16_t langtagLen = 0;
std::string langtag;
};
/*
* @struct Payload
* This is a payload of the SLP Message currently
* we are supporting two request.
*
*/
struct Payload
{
request::ServiceType srvtyperqst;
request::Service srvrqst;
};
/*
* @struct Message
*
* This will denote the slp Message.
*/
struct Message
{
Header header;
Payload body;
};
namespace parser
{
/** Parse a buffer and fill the header and the body of the message.
*
* @param[in] buffer - The buffer from which data should be parsed.
*
* @return Zero on success and parsed msg object,
* non-zero on failure and empty msg object.
*
*/
std::tuple<int, Message> parseBuffer(const buffer& buf);
namespace internal
{
/** Parse header data from the buffer.
*
* @param[in] buffer - The buffer from which data should be parsed.
*
* @return Zero on success and fills header object inside message,
* non-zero on failure and empty msg object.
*
* @internal
*/
std::tuple<int, Message> parseHeader(const buffer& buf);
/** Parse a srvType request
*
* @param[in] buffer - The buffer from which data should be parsed.
*
* @return Zero on success,and fills the body object inside message.
* non-zero on failure and empty msg object.
*
* @internal
*/
int parseSrvTypeRqst(const buffer& buf, Message& req);
/** Parse a service request.
*
* @param[in] buffer - The buffer from which data should be parsed.
*
* @return Zero on success,and fills the body object inside message.
* non-zero on failure and empty msg object.
*
* @internal
*/
int parseSrvRqst(const buffer& buf, Message& req);
} // namespace internal
} // namespace parser
namespace handler
{
/** Handle the request message.
*
* @param[in] msg - The message to process.
*
* @return In case of success, the vector is populated with the data
* available on the socket and return code is 0.
* In case of error, nonzero code and vector is set to size 0.
*
*/
std::tuple<int, buffer> processRequest(const Message& msg);
/** Handle the error
*
* @param[in] msg - Req message.
* @param[in] err - Error code.
*
* @return the vector populated with the error data
*/
buffer processError(const Message& req, const uint8_t err);
namespace internal
{
using ServiceList = std::map<std::string, slp::ConfigData>;
/** Handle the SrvRequest message.
*
* @param[in] msg - The message to process
*
* @return In case of success, the vector is populated with the data
* available on the socket and return code is 0.
* In case of error, nonzero code and vector is set to size 0.
*
* @internal
*/
std::tuple<int, buffer> processSrvRequest(const Message& msg);
/** Handle the SrvTypeRequest message.
*
* @param[in] msg - The message to process
*
* @return In case of success, the vector is populated with the data
* available on the socket and return code is 0.
* In case of error, nonzero code and vector is set to size 0.
*
* @internal
*
*/
std::tuple<int, buffer> processSrvTypeRequest(const Message& msg);
/** Read the SLPinfo from the configuration.
*
* @param[in] filename - Name of the conf file
*
* @return the list of the services
*
* @internal
*
*/
ServiceList readSLPServiceInfo();
/** Get all the interface address
*
* @return the list of the interface address.
*
* @internal
*
*/
std::list<std::string> getIntfAddrs();
/** Fill the buffer with the header data from the request object
*
* @param[in] req - Header data will be copied from
*
* @return the vector is populated with the data
*
* @internal
*/
buffer prepareHeader(const Message& req);
} // namespace internal
} // namespace handler
} // namespace slp