2 * This file is part of the libsigrok project.
4 * Copyright (C) 2017 Kumar Abhishek <abhishek@theembeddedkitchen.net>
5 * Portions of the code are adopted from scpi_tcp.c and scpi.c
7 * Copyright (C) 2013 Martin Ling <martin-sigrok@earth.li>
8 * Copyright (C) 2013 poljar (Damir Jelić) <poljarinho@gmail.com>
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #define _WIN32_WINNT 0x0501
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
42 #include "beaglelogic.h"
44 static int beaglelogic_tcp_open(struct dev_context *devc) {
45 struct addrinfo hints;
46 struct addrinfo *results, *res;
49 memset(&hints, 0, sizeof(hints));
50 hints.ai_family = AF_UNSPEC;
51 hints.ai_socktype = SOCK_STREAM;
52 hints.ai_protocol = IPPROTO_TCP;
54 err = getaddrinfo(devc->address, devc->port, &hints, &results);
57 sr_err("Address lookup failed: %s:%s: %s", devc->address,
58 devc->port, gai_strerror(err));
62 for (res = results; res; res = res->ai_next) {
63 if ((devc->socket = socket(res->ai_family, res->ai_socktype,
64 res->ai_protocol)) < 0)
66 if (connect(devc->socket, res->ai_addr, res->ai_addrlen) != 0) {
74 freeaddrinfo(results);
76 if (devc->socket < 0) {
77 sr_err("Failed to connect to %s:%s: %s", devc->address,
78 devc->port, g_strerror(errno));
85 static int beaglelogic_tcp_send_cmd(struct dev_context *devc,
86 const char *format, ...) {
88 va_list args, args_copy;
91 va_start(args, format);
92 va_copy(args_copy, args);
93 len = vsnprintf(NULL, 0, format, args_copy);
96 buf = g_malloc0(len + 2);
97 vsprintf(buf, format, args);
100 if (buf[len - 1] != '\n')
103 out = send(devc->socket, buf, strlen(buf), 0);
106 sr_err("Send error: %s", g_strerror(errno));
110 if (out < (int)strlen(buf)) {
111 sr_dbg("Only sent %d/%d bytes of command: '%s'.", out,
115 sr_spew("Sent command: '%s'.", buf);
121 static int beaglelogic_tcp_read_data(struct dev_context *devc, char *buf,
125 len = recv(devc->socket, buf, maxlen, 0);
128 sr_err("Receive error: %s", g_strerror(errno));
135 static int beaglelogic_tcp_get_string(struct dev_context *devc, const char *cmd,
137 GString *response = g_string_sized_new(1024);
142 if (beaglelogic_tcp_send_cmd(devc, cmd) != SR_OK) {
147 timeout = g_get_monotonic_time() + devc->read_timeout;
148 len = beaglelogic_tcp_read_data(devc, response->str,
149 response->allocated_len);
152 g_string_free(response, TRUE);
157 g_string_set_size(response, len);
160 if (g_get_monotonic_time() > timeout) {
161 sr_err("Timed out waiting for response.");
162 g_string_free(response, TRUE);
163 return SR_ERR_TIMEOUT;
166 /* Remove trailing newline if present */
167 if (response->len >= 1 && response->str[response->len - 1] == '\n')
168 g_string_truncate(response, response->len - 1);
170 /* Remove trailing carriage return if present */
171 if (response->len >= 1 && response->str[response->len - 1] == '\r')
172 g_string_truncate(response, response->len - 1);
174 sr_spew("Got response: '%.70s', length %" G_GSIZE_FORMAT ".",
175 response->str, response->len);
177 *tcp_resp = g_string_free(response, FALSE);
181 static int beaglelogic_tcp_get_int(struct dev_context *devc,
182 const char *cmd, int *response) {
186 ret = beaglelogic_tcp_get_string(devc, cmd, &resp);
187 if (!resp && ret != SR_OK)
190 if (sr_atoi(resp, response) == SR_OK)
200 SR_PRIV int beaglelogic_tcp_detect(struct dev_context *devc) {
204 ret = beaglelogic_tcp_get_string(devc, "version", &resp);
205 if (ret == SR_OK && !g_ascii_strncasecmp(resp, "BeagleLogic", 11))
214 static int beaglelogic_open(struct dev_context *devc) {
215 return beaglelogic_tcp_open(devc);
218 static int beaglelogic_close(struct dev_context *devc) {
219 g_free(devc->address);
222 if (close(devc->socket) < 0)
228 static int beaglelogic_get_buffersize(struct dev_context *devc) {
229 return beaglelogic_tcp_get_int(devc, "memalloc",
230 (int *)&devc->buffersize);
233 static int beaglelogic_set_buffersize(struct dev_context *devc) {
237 beaglelogic_tcp_send_cmd(devc, "memalloc %lu", devc->buffersize);
238 ret = beaglelogic_tcp_get_string(devc, NULL, &resp);
239 if (ret == SR_OK && !g_ascii_strncasecmp(resp, "ok", 2))
248 static int beaglelogic_get_samplerate(struct dev_context *devc) {
250 err = beaglelogic_tcp_get_int(devc, "samplerate", &arg);
251 devc->cur_samplerate = arg;
255 static int beaglelogic_set_samplerate(struct dev_context *devc) {
259 beaglelogic_tcp_send_cmd(devc, "samplerate %lu",
260 (uint32_t)devc->cur_samplerate);
261 ret = beaglelogic_tcp_get_string(devc, NULL, &resp);
262 if (ret == SR_OK && !g_ascii_strncasecmp(resp, "ok", 2))
271 static int beaglelogic_get_sampleunit(struct dev_context *devc) {
272 return beaglelogic_tcp_get_int(devc, "sampleunit",
273 (int *)&devc->sampleunit);
276 static int beaglelogic_set_sampleunit(struct dev_context *devc) {
280 beaglelogic_tcp_send_cmd(devc, "sampleunit %lu", devc->sampleunit);
281 ret = beaglelogic_tcp_get_string(devc, NULL, &resp);
282 if (ret == SR_OK && !g_ascii_strncasecmp(resp, "ok", 2))
291 static int beaglelogic_get_triggerflags(struct dev_context *devc) {
292 return beaglelogic_tcp_get_int(devc, "triggerflags",
293 (int *)&devc->triggerflags);
296 static int beaglelogic_set_triggerflags(struct dev_context *devc) {
300 beaglelogic_tcp_send_cmd(devc, "triggerflags %lu", devc->triggerflags);
301 ret = beaglelogic_tcp_get_string(devc, NULL, &resp);
302 if (ret == SR_OK && !g_ascii_strncasecmp(resp, "ok", 2))
311 static int beaglelogic_get_lasterror(struct dev_context *devc) {
312 devc->last_error = 0;
316 static int beaglelogic_start(struct dev_context *devc) {
317 return beaglelogic_tcp_send_cmd(devc, "get");
320 static int beaglelogic_stop(struct dev_context *devc) {
321 return beaglelogic_tcp_send_cmd(devc, "close");
324 static int beaglelogic_get_bufunitsize(struct dev_context *devc) {
325 return beaglelogic_tcp_get_int(devc, "bufunitsize",
326 (int *)&devc->bufunitsize);
329 static int beaglelogic_set_bufunitsize(struct dev_context *devc) {
333 beaglelogic_tcp_send_cmd(devc, "bufunitsize %ld", devc->bufunitsize);
334 ret = beaglelogic_tcp_get_string(devc, NULL, &resp);
335 if (ret == SR_OK && !g_ascii_strncasecmp(resp, "ok", 2))
344 static int dummy(struct dev_context *devc) {
349 SR_PRIV const struct beaglelogic_ops beaglelogic_tcp_ops = {
350 .open = beaglelogic_open,
351 .close = beaglelogic_close,
352 .get_buffersize = beaglelogic_get_buffersize,
353 .set_buffersize = beaglelogic_set_buffersize,
354 .get_samplerate = beaglelogic_get_samplerate,
355 .set_samplerate = beaglelogic_set_samplerate,
356 .get_sampleunit = beaglelogic_get_sampleunit,
357 .set_sampleunit = beaglelogic_set_sampleunit,
358 .get_triggerflags = beaglelogic_get_triggerflags,
359 .set_triggerflags = beaglelogic_set_triggerflags,
360 .start = beaglelogic_start,
361 .stop = beaglelogic_stop,
362 .get_lasterror = beaglelogic_get_lasterror,
363 .get_bufunitsize = beaglelogic_get_bufunitsize,
364 .set_bufunitsize = beaglelogic_set_bufunitsize,