1 #include "acmp_client.h"
6 #include <sys/socket.h>
12 #include <sys/ioctl.h>
16 ACMPClient::ACMPClient(const string &host, int port)
17 : host(host), port(port) {}
19 void ACMPClient::add_init_command(const string &cmd)
21 init_commands.push_back(cmd + "\r\n");
24 void ACMPClient::start()
26 t = thread(&ACMPClient::thread_func, this);
29 void ACMPClient::end()
34 void ACMPClient::send_command(const string &cmd)
36 lock_guard<mutex> lock(mu);
37 queued_commands.push_back(cmd + "\r\n");
40 void ACMPClient::change_server(const string &host, int port)
42 lock_guard<mutex> lock(mu);
43 queued_commands.push_back(""); // Marker for disconnect.
48 void ACMPClient::set_connection_callback(const std::function<void(bool)> &callback)
50 connection_callback = callback;
55 int lookup_and_connect(const char *host, int port)
58 memset(&hints, 0, sizeof(hints));
59 hints.ai_family = AF_UNSPEC;
60 hints.ai_socktype = SOCK_STREAM;
64 snprintf(portstr, sizeof(portstr), "%d", port);
65 int err = getaddrinfo(host, portstr, &hints, &res);
67 fprintf(stderr, "Lookup of %s:%d failed: %s\n", host, port, strerror(errno));
71 for (addrinfo *p = res; p != NULL; p = p->ai_next) {
72 int sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
78 if (connect(sock, p->ai_addr, p->ai_addrlen) == -1) {
95 void ACMPClient::thread_func()
97 if (connection_callback) {
98 connection_callback(false);
104 lock_guard<mutex> lock(mu);
108 sock = lookup_and_connect(host_copy.c_str(), port_copy);
115 if (ioctl(sock, FIONBIO, &one) == 1) {
116 perror("ioctl(FIONBIO)");
122 printf("Connected to CasparCG.\n");
123 if (connection_callback) {
124 connection_callback(true);
130 vector<string> commands;
132 commands = init_commands;
135 lock_guard<mutex> lock(mu);
136 swap(commands, queued_commands);
141 for (const string &cmd : commands) {
144 printf("Closing CasparCG socket for reconnection.\n");
154 printf("Writing: '%s'\n", buf.c_str());
159 // Consume until there is no more.
161 int err = read(sock, junk, sizeof(junk));
171 printf("Server closed connection.\n");
178 printf("From server: '%s'\n", junk);
182 if (pos < buf.size()) {
183 // Now write as much as we can.
184 err = write(sock, buf.data() + pos, buf.size() - pos);
191 // Uh-oh. Buffer full for some reason?
196 } while (pos < buf.size());
208 if (connection_callback) {
209 connection_callback(false);