aboutsummaryrefslogtreecommitdiff
path: root/client/sock.h
blob: dbe6d6acfb914c643333d50cf66494df5b508acd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#pragma once

#include <cstdint>
#include <thread>

/**
 * \ingroup pbc
 * \defgroup pbc_sock Socket
 * \brief TCP socket handling
 * \{
 */

/**
 * \brief Asynchronous puzzle box socket connection
 * \note Once connected, this class will call \c i2c_recv() when a complete I2C
 * message has been received
 */
class PBSocket {
public:
	PBSocket();
	//! Constructor that immediately calls \c set_server()
	PBSocket(const char * addr, uint16_t port);
	virtual ~PBSocket();

	//! Configure target server
	void set_server(const char * addr, uint16_t port);

	//! Attempt to connect to server and start \c sock_task() in a thread
	void sock_connect();

	/**
	 * \brief Send data over the TCP connection
	 *
	 * \param buf Data to send
	 * \param buf_sz Size of \p buf in bytes
	 */
	void send(const char * buf, size_t buf_sz);

private:
	/**
	 * \brief Continously read from the TCP socket and read \ref i2ctcp messages
	 * using \c i2ctcp_read().
	 *
	 * Once a complete message has been parsed, \c i2c_recv() is called with the
	 * complete message. This message is automatically free'd after \c i2c_recv()
	 * returns.
	 *
	 * \note This function is run in a separate thread
	 */
	void sock_task();
	//! Close the socket
	void sock_close();

	//! Pointer to thread running \c sock_task()
	std::thread * _thread = nullptr;

	/**
	 * \brief IP address of server to connect to
	 *
	 * \note This member must contain an IP address, as no hostname resolution is
	 * done in pbc.
	 */
	const char * _addr = NULL;
	//! Port number of server to connect to
	uint16_t _port = 0;

	//! Unix file descriptor of opened socket
	int _fd = -1;
};

//! Singleton \c PBSocket instance
extern PBSocket * sock;

/// \}