aboutsummaryrefslogtreecommitdiff
path: root/src/server/server.h
blob: 705503fd0ae6f68b94aae1ab694d8e7c5f7d2d53 (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// SPDX-License-Identifier: BSD-3-Clause

#ifndef INVERTER_TOOLS_SERVER_TCP_SERVER_H
#define INVERTER_TOOLS_SERVER_TCP_SERVER_H

#include <memory>
#include <string>
#include <vector>
#include <thread>
#include <mutex>
#include <csignal>
#include <atomic>
#include <netinet/in.h>

#include "connection.h"
#include "../numeric_types.h"
#include "../formatter/formatter.h"
#include "../p18/client.h"
#include "../p18/types.h"
#include "../voltronic/device.h"
#include "../voltronic/time.h"

namespace server {

typedef std::lock_guard<std::mutex> LockGuard;

class Connection;

struct CachedResponse {
    u64 time;
    std::vector<std::string> arguments;
    std::shared_ptr<p18::response_type::BaseResponse> response;
};

class Server {
private:
    int sock_;
    std::string host_;
    int port_;
    bool verbose_;
    p18::Client client_;
    std::shared_ptr<voltronic::Device> device_;

    u64 cacheTimeout_;
    u64 delay_;
    u64 endExecutionTime_;
    u32 deviceErrorLimit_;
    u32 deviceErrorCounter_;
    std::map<p18::CommandType, CachedResponse> cache_;

    std::mutex threads_mutex_;
    std::mutex client_mutex_;

    std::vector<Connection*> connections_;

public:
    static const u64 CACHE_TIMEOUT = 1000;
    static const u32 DEVICE_ERROR_LIMIT = 10;
    static const u64 DELAY = 0;

    volatile std::atomic<bool> sigCaught = 0;

    explicit Server(std::shared_ptr<voltronic::Device> device);
    ~Server();

    void setVerbose(bool verbose);
    void setCacheTimeout(u64 timeout);
    void setDelay(u64 delay);
    void setDeviceErrorLimit(u32 deviceErrorLimit);

    void start(std::string& host, int port);

    bool verbose() const { return verbose_; }
    void addConnection(Connection* conn);
    void removeConnection(Connection* conn);
    size_t getConnectionsCount() const;

    std::shared_ptr<p18::response_type::BaseResponse> executeCommand(p18::CommandType commandType, std::vector<std::string>& arguments);
};


class ServerError : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
};

}

#endif //INVERTER_TOOLS_SERVER_TCP_SERVER_H