Skip to content

Commit 379b802

Browse files
committed
Cleanup: Rewrite socket protocol
1 parent 2692a61 commit 379b802

File tree

1 file changed

+99
-63
lines changed

1 file changed

+99
-63
lines changed

src/rtapi/uspace_rtapi_main.cc

Lines changed: 99 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -292,66 +292,98 @@ static int do_debug_cmd(const std::string &value) {
292292
}
293293
}
294294

295-
struct ReadError : std::exception {};
296-
struct WriteError : std::exception {};
295+
static bool send_result(int fd, int result) {
296+
ssize_t res = send(fd, &result, sizeof(int), 0);
297+
return res == sizeof(int);
298+
}
297299

298-
static int read_number(int fd) {
299-
int r = 0, neg = 1;
300-
char ch;
300+
static bool recv_result(int fd, int *result) {
301+
ssize_t res = recv(fd, result, sizeof(int), 0);
302+
return res == sizeof(int);
303+
}
301304

302-
while (1) {
303-
int res = read(fd, &ch, 1);
304-
if (res != 1)
305-
return -1;
306-
if (ch == '-')
307-
neg = -1;
308-
else if (ch == ' ')
309-
return r * neg;
310-
else
311-
r = 10 * r + ch - '0';
312-
}
313-
}
314-
315-
static std::string read_string(int fd) {
316-
int len = read_number(fd);
317-
if (len < 0)
318-
throw ReadError();
319-
if (!len)
320-
return std::string();
321-
std::string str(len, 0);
322-
if (read(fd, str.data(), len) != len)
323-
throw ReadError();
324-
return str;
325-
}
326-
327-
static std::vector<std::string> read_strings(int fd) {
328-
std::vector<std::string> result;
329-
int count = read_number(fd);
330-
if (count < 0)
331-
return result;
332-
for (int i = 0; i < count; i++) {
333-
result.push_back(read_string(fd));
334-
}
335-
return result;
305+
static void set_uint16(std::vector<char> &buf, uint16_t value, size_t idx) {
306+
buf[idx] = 0xff & (value >> 0);
307+
buf[idx + 1] = 0xff & (value >> 8);
336308
}
337309

338-
static void write_number(std::string &buf, int num) {
339-
buf = buf + fmt::format("{} ", num);
310+
static uint16_t get_uint16(std::vector<char> &buf, size_t idx) {
311+
return ((uint16_t)buf[idx] << 0) | ((uint16_t)buf[idx + 1] << 8);
340312
}
341313

342-
static void write_string(std::string &buf, const std::string &s) {
343-
write_number(buf, s.size());
344-
buf += s;
314+
static bool recv_args(int fd, std::vector<std::string> &args) {
315+
//Get size
316+
uint16_t tmp;
317+
ssize_t res = recv(fd, &tmp, sizeof(uint16_t), 0);
318+
if (res != sizeof(uint16_t)) {
319+
return false;
320+
}
321+
size_t buff_size = tmp;
322+
323+
//Get data
324+
std::vector<char> buf(buff_size);
325+
res = recv(fd, buf.data(), buff_size, 0);
326+
if (res != (ssize_t)buff_size) {
327+
return false;
328+
}
329+
330+
//Deserialize
331+
size_t idx = 0;
332+
size_t n_args = get_uint16(buf, idx);
333+
idx += sizeof(uint16_t);
334+
for (size_t i = 0; i < n_args; i++) {
335+
size_t arg_size = get_uint16(buf, idx);
336+
idx += sizeof(uint16_t);
337+
args.push_back(std::string(buf.begin() + idx, buf.begin() + idx + arg_size));
338+
idx += arg_size;
339+
}
340+
if (idx + sizeof(uint16_t) != buff_size) {
341+
rtapi_print_msg(RTAPI_MSG_ERR, "rtapi_app: Bug recv_args: idx %li != buff_size %li\n", idx, buff_size);
342+
return false;
343+
}
344+
345+
return true;
345346
}
346347

347-
static void write_strings(int fd, const std::vector<std::string> &strings) {
348-
std::string buf;
349-
write_number(buf, strings.size());
350-
for (unsigned int i = 0; i < strings.size(); i++) {
351-
write_string(buf, strings[i]);
348+
static bool send_args(int fd, const std::vector<std::string> &args) {
349+
//Calculate size
350+
size_t buff_size = 0;
351+
buff_size += 2 * sizeof(uint16_t);
352+
for (size_t i = 0; i < args.size(); i++) {
353+
buff_size += sizeof(uint16_t);
354+
buff_size += args[i].size();
352355
}
353-
if (write(fd, buf.data(), buf.size()) != (ssize_t)buf.size())
354-
throw WriteError();
356+
357+
//This is the largest value set by set_int16()
358+
if (buff_size > std::numeric_limits<uint16_t>::max()) {
359+
rtapi_print_msg(RTAPI_MSG_ERR, "rtapi_app: Bug send_args: args to big, size = %li!\n", buff_size);
360+
return false;
361+
}
362+
363+
//Serialize
364+
std::vector<char> buf(buff_size);
365+
size_t idx = 0;
366+
set_uint16(buf, buff_size, idx);
367+
idx += sizeof(uint16_t);
368+
set_uint16(buf, args.size(), idx);
369+
idx += sizeof(uint16_t);
370+
for (size_t i = 0; i < args.size(); i++) {
371+
set_uint16(buf, args[i].size(), idx);
372+
idx += sizeof(uint16_t);
373+
buf.insert(buf.begin() + idx, args[i].begin(), args[i].end());
374+
idx += args[i].size();
375+
}
376+
if (idx != buff_size) {
377+
rtapi_print_msg(RTAPI_MSG_ERR, "rtapi_app: Bug send_args: idx %li != buff_size %li\n", idx, buff_size);
378+
return false;
379+
}
380+
381+
//Send
382+
ssize_t res = send(fd, buf.data(), buf.size(), 0);
383+
if (res != (ssize_t)buf.size()) {
384+
return false;
385+
}
386+
return true;
355387
}
356388

357389
static int handle_command(std::vector<std::string> args) {
@@ -380,14 +412,18 @@ static int handle_command(std::vector<std::string> args) {
380412
}
381413

382414
static int slave(int fd, const std::vector<std::string> &args) {
383-
try {
384-
write_strings(fd, args);
385-
} catch (WriteError &e) {
415+
if (!send_args(fd, args)) {
386416
rtapi_print_msg(RTAPI_MSG_ERR, "rtapi_app: failed to write to master: %s\n", strerror(errno));
417+
return -1;
387418
}
388419

389-
int result = read_number(fd);
390-
return result;
420+
int result = -1;
421+
if (!recv_result(fd, &result)) {
422+
rtapi_print_msg(RTAPI_MSG_ERR, "rtapi_app: failed to read from master: %s\n", strerror(errno));
423+
return -1;
424+
} else {
425+
return result;
426+
}
391427
}
392428

393429
static int callback(int fd) {
@@ -400,18 +436,18 @@ static int callback(int fd) {
400436
return -1;
401437
} else {
402438
int result;
403-
try {
404-
result = handle_command(read_strings(fd1));
405-
} catch (ReadError &e) {
439+
std::vector<std::string> args;
440+
if (!recv_args(fd1, args)) {
406441
rtapi_print_msg(RTAPI_MSG_ERR, "rtapi_app: failed to read from slave: %s\n", strerror(errno));
407442
close(fd1);
408443
return -1;
409444
}
410-
std::string buf;
411-
write_number(buf, result);
412-
if (write(fd1, buf.data(), buf.size()) != (ssize_t)buf.size()) {
445+
446+
result = handle_command(args);
447+
448+
if (!send_result(fd1, result)) {
413449
rtapi_print_msg(RTAPI_MSG_ERR, "rtapi_app: failed to write to slave: %s\n", strerror(errno));
414-
};
450+
}
415451
close(fd1);
416452
}
417453
return !force_exit && instance_count > 0;

0 commit comments

Comments
 (0)