2019-05-31 14:55:11 +02:00
|
|
|
#include "device_msg.h"
|
2019-05-30 00:24:26 +02:00
|
|
|
|
2021-11-20 12:10:09 +01:00
|
|
|
#include <stdint.h>
|
2021-01-24 15:14:53 +01:00
|
|
|
#include <stdlib.h>
|
2019-05-30 00:24:26 +02:00
|
|
|
#include <string.h>
|
|
|
|
|
2022-08-03 15:13:16 +02:00
|
|
|
#include "util/binary.h"
|
2019-11-24 11:53:00 +01:00
|
|
|
#include "util/log.h"
|
2019-05-30 00:24:26 +02:00
|
|
|
|
|
|
|
ssize_t
|
2024-02-23 20:05:12 +01:00
|
|
|
sc_device_msg_deserialize(const uint8_t *buf, size_t len,
|
|
|
|
struct sc_device_msg *msg) {
|
2024-02-23 20:01:30 +01:00
|
|
|
if (!len) {
|
|
|
|
return 0; // no message
|
2019-05-30 00:24:26 +02:00
|
|
|
}
|
|
|
|
|
2019-05-31 14:55:11 +02:00
|
|
|
msg->type = buf[0];
|
|
|
|
switch (msg->type) {
|
|
|
|
case DEVICE_MSG_TYPE_CLIPBOARD: {
|
2024-02-23 20:01:30 +01:00
|
|
|
if (len < 5) {
|
|
|
|
// at least type + empty string length
|
|
|
|
return 0; // no complete message
|
|
|
|
}
|
2022-02-12 09:12:46 +01:00
|
|
|
size_t clipboard_len = sc_read32be(&buf[1]);
|
2020-06-04 21:42:09 +02:00
|
|
|
if (clipboard_len > len - 5) {
|
2024-02-23 20:01:30 +01:00
|
|
|
return 0; // no complete message
|
2019-05-30 00:24:26 +02:00
|
|
|
}
|
2021-01-24 15:14:53 +01:00
|
|
|
char *text = malloc(clipboard_len + 1);
|
2019-05-30 00:24:26 +02:00
|
|
|
if (!text) {
|
2021-11-24 22:06:11 +01:00
|
|
|
LOG_OOM();
|
2019-05-30 00:24:26 +02:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (clipboard_len) {
|
2020-06-04 21:42:09 +02:00
|
|
|
memcpy(text, &buf[5], clipboard_len);
|
2019-05-30 00:24:26 +02:00
|
|
|
}
|
|
|
|
text[clipboard_len] = '\0';
|
|
|
|
|
2019-05-31 14:55:11 +02:00
|
|
|
msg->clipboard.text = text;
|
2020-06-04 21:42:09 +02:00
|
|
|
return 5 + clipboard_len;
|
2019-05-30 00:24:26 +02:00
|
|
|
}
|
2021-11-20 12:10:09 +01:00
|
|
|
case DEVICE_MSG_TYPE_ACK_CLIPBOARD: {
|
2024-02-23 20:01:30 +01:00
|
|
|
if (len < 9) {
|
|
|
|
return 0; // no complete message
|
|
|
|
}
|
2022-02-12 09:12:46 +01:00
|
|
|
uint64_t sequence = sc_read64be(&buf[1]);
|
2021-11-20 12:10:09 +01:00
|
|
|
msg->ack_clipboard.sequence = sequence;
|
|
|
|
return 9;
|
|
|
|
}
|
2024-01-12 23:32:30 +08:00
|
|
|
case DEVICE_MSG_TYPE_UHID_OUTPUT: {
|
|
|
|
if (len < 5) {
|
|
|
|
// at least id + size
|
|
|
|
return 0; // not available
|
|
|
|
}
|
|
|
|
uint16_t id = sc_read16be(&buf[1]);
|
|
|
|
size_t size = sc_read16be(&buf[3]);
|
|
|
|
if (size < len - 5) {
|
|
|
|
return 0; // not available
|
|
|
|
}
|
|
|
|
uint8_t *data = malloc(size);
|
|
|
|
if (!data) {
|
|
|
|
LOG_OOM();
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (size) {
|
|
|
|
memcpy(data, &buf[5], size);
|
|
|
|
}
|
|
|
|
|
|
|
|
msg->uhid_output.id = id;
|
|
|
|
msg->uhid_output.size = size;
|
|
|
|
msg->uhid_output.data = data;
|
|
|
|
|
|
|
|
return 5 + size;
|
|
|
|
}
|
2019-05-30 00:24:26 +02:00
|
|
|
default:
|
2019-05-31 14:55:11 +02:00
|
|
|
LOGW("Unknown device message type: %d", (int) msg->type);
|
2019-05-30 00:24:26 +02:00
|
|
|
return -1; // error, we cannot recover
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2024-02-23 20:05:12 +01:00
|
|
|
sc_device_msg_destroy(struct sc_device_msg *msg) {
|
2024-01-12 23:32:30 +08:00
|
|
|
switch (msg->type) {
|
|
|
|
case DEVICE_MSG_TYPE_CLIPBOARD:
|
|
|
|
free(msg->clipboard.text);
|
|
|
|
break;
|
|
|
|
case DEVICE_MSG_TYPE_UHID_OUTPUT:
|
|
|
|
free(msg->uhid_output.data);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// nothing to do
|
|
|
|
break;
|
2019-05-30 00:24:26 +02:00
|
|
|
}
|
|
|
|
}
|