class ugcs::vsm::Socket_processor

Overview

Socket processor. More…

#include <socket_processor.h>

class Socket_processor: public ugcs::vsm::Request_context
{
public:
    // typedefs

    typedef std::shared_ptr<Socket_processor> Ptr;
    typedef std::weak_ptr<Socket_processor> Weak_ptr;
    typedef Stream Socket_listener;
    typedef Callback_proxy<void, std::string, std::string, std::list<addrinfo>, Io_result> Get_addr_info_handler;
    typedef Callback_proxy<void, Stream::Ref, Io_result> Listen_handler;
    typedef Listen_handler Connect_handler;

    // classes

    class Stream;

    // construction

    Socket_processor(Piped_request_waiter::Ptr piped_waiter = Piped_request_waiter::Create());

    // methods

    template <typename... Args>
    static Ptr Create(Args&&... args);

    static Ptr Create();

    template <typename... Args>
    static Ptr Get_instance(Args&&... args);

    static std::list<Local_interface> Enumerate_local_interfaces();

    Operation_waiter Connect(
        std::string host,
        std::string service,
        Connect_handler completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create(),
        Io_stream::Type sock_type = Io_stream::Type::TCP,
        Socket_address::Ptr src_addr = nullptr
        );

    Operation_waiter Connect(
        Socket_address::Ptr dest_addr,
        Connect_handler completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create(),
        Io_stream::Type sock_type = Io_stream::Type::TCP,
        Socket_address::Ptr src_addr = nullptr
        );

    template <class Callback_ptr>
    Operation_waiter Accept(
        Socket_listener::Ref listener,
        Callback_ptr completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create()
        );

    Operation_waiter Get_addr_info(
        const std::string& host,
        const std::string& service,
        addrinfo* hints,
        Get_addr_info_handler completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create()
        );

    Operation_waiter Listen(
        const std::string& host,
        const std::string& service,
        Listen_handler completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create(),
        Io_stream::Type sock_type = Io_stream::Type::TCP
        );

    Operation_waiter Listen(
        Socket_address::Ptr addr,
        Listen_handler completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create(),
        Io_stream::Type sock_type = Io_stream::Type::TCP
        );

    Operation_waiter Bind_udp(
        Socket_address::Ptr addr,
        Listen_handler completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create(),
        bool multicast = false
        );

    Operation_waiter Bind_can(
        std::string interface,
        std::vector<int> filter_messges,
        Listen_handler completion_handler,
        Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create()
        );
};

Inherited Members

public:
    // typedefs

    typedef std::shared_ptr<Request_container> Ptr;
    typedef std::weak_ptr<Request_container> Weak_ptr;
    typedef std::shared_ptr<Request_context> Ptr;
    typedef std::weak_ptr<Request_context> Weak_ptr;

    // enums

    enum Type;

    // classes

    class Request;
    class Request_waiter;

    // methods

    template <typename... Args>
    static Ptr Create(Args&&... args);

    virtual Type Get_type() const;
    bool Check_type(Type mask);
    void Submit_request(Request::Ptr request);
    void Submit_request_locked(Request::Ptr request, Request_waiter::Locker locker);
    int Process_requests(int requests_limit = 0);
    int Process_requests(std::unique_lock<std::mutex>& lock, int requests_limit = 0);
    void Set_waiter(Request_waiter::Ptr waiter);
    Request_waiter::Ptr Get_waiter() const;
    const std::string& Get_name();
    void Enable();
    void Disable();
    bool Is_enabled() const;

    template <typename... Args>
    static Ptr Create(Args&&... args);

    virtual Type Get_type() const;
    Request_container(const std::string& name, Request_waiter::Ptr waiter = Request_waiter::Create());

Detailed Documentation

Socket processor.

Typedefs

typedef std::shared_ptr<Socket_processor> Ptr

Pointer type.

typedef std::weak_ptr<Socket_processor> Weak_ptr

Pointer type.

typedef Stream Socket_listener

Stream type is used for listener socket type also.

typedef Callback_proxy<void, std::string, std::string, std::list<addrinfo>, Io_result> Get_addr_info_handler

Callback used in Get_addr_info()

typedef Callback_proxy<void, Stream::Ref, Io_result> Listen_handler

Callback used in Listen()

typedef Listen_handler Connect_handler

Callback used in Connect() is the same as for listen handler.

Construction

Socket_processor(Piped_request_waiter::Ptr piped_waiter = Piped_request_waiter::Create())

Constructor.

Parameters:

piped_waiter

Request waiter based on a pipe to multiplex socket and request operations using select.

Methods

template <typename... Args>
static Ptr Create(Args&&... args)

Create an instance.

static Ptr Create()

Create processor instance.

template <typename... Args>
static Ptr Get_instance(Args&&... args)

Get global or create new processor instance.

template <class Callback_ptr>
Operation_waiter Accept(
    Socket_listener::Ref listener,
    Callback_ptr completion_handler,
    Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create()
    )

Accept incoming TCP/UDP connection.

TCP behavior is similar to accept() call. It returns a connected stream with its own socket.

For UDP this can be called on UDP (master) stream which is bound to specific port via Bind_udp() call. It will call completion_handler on each packet which has a new peer address:port tuple. All accepted streams share the same udp socket thus closing the the master stream implicitly closes all “accepted” streams. Read on accepted stream will return only packets from one peer. All Packets which do not belong to accepted streams can be read using from the master stream. All UDP streams use circular buffer for received packets. This is to avoid reads on accepted streams blocking on each other.

Operation_waiter Get_addr_info(
    const std::string& host,
    const std::string& service,
    addrinfo* hints,
    Get_addr_info_handler completion_handler,
    Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create()
    )

Interface for nonblocking call to getaddrinfo().

Parameters:

host

Hostname to resolve

service

Service name to resolve. common port name or numerid port as string.

hints

Passed as hints argument for getaddrinfo() call.

Operation_waiter Bind_udp(
    Socket_address::Ptr addr,
    Listen_handler completion_handler,
    Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create(),
    bool multicast = false
    )

create local UDP endpoint socket and associate stream with it.

See Listen_handler for completion handler parameters.

There is no such thing as listen() on udp socket. But we make it possible to create a similar workflow as for tcp. How it works: udp socket is bound on given ip_address:service User can issue Read, Read_from or Write_to on returned stream For simple Write() user must first call Set_peer_address() on stream.

Parameters:

addr

local ip address/port for listener socket. Should be numeric.

multicast

true : bind as multicast listener. On windows it uses SO_REUSEADDR. On Mac it uses SO_REUSEPORT.

Operation_waiter Bind_can(
    std::string interface,
    std::vector<int> filter_messges,
    Listen_handler completion_handler,
    Request_completion_context::Ptr completion_context = Request_temp_completion_context::Create()
    )

Create CAN socket and associate stream with it.

For now this is linux-only stuff (via SocketCAN API).

How it works: Socket is bound to a given can interface by name. User can issue Read, Write on returned stream.

Write will accept only valid raw CAN frames with length 16. Caller is responsible of producing a valid frame.

Read will return only valid CAN frames. Caller is responsible of parsing payload data from frame.

Read_from and Write_to are not supported.

See Listen_handler for completion handler parameters.

Parameters:

interface

CAN interface name. Typically “can0” or similar.

filter_messges

set of can_ids to listen for. Empty means read all.