Something went wrong on our end
nodes.c 3.31 KiB
#include <sys/types.h>
#include <inttypes.h>
#include "nodes.h"
#include "commands.h"
#include "bitwise.h"
enum GetnodeData {
GN_DATA_SIZE
};
/* Creates data and metadata for a getnodes packet.
* Returns data size.
*/
ssize_t EncodeGetNodes(
struct metadata *m, /* Out */
uint8_t *data, /* Out */
size_t data_size, /* Data buffer max size */
const char * msg) /* Value is not used; only IDs */
{
m->msg_type = GETNODES_ID;
m->data_len = GN_DATA_SIZE;
return GN_DATA_SIZE;
}
enum AddnodeData {
AN_TYPE_ID_L,
AN_TYPE_ID_H,
AN_NAME,
AN_MIN_DATA_SIZE
};
/* Creates data and metadata for a addnode packet
* Returns data size.
*/
ssize_t EncodeAddNode(
struct metadata * m, /* data_len and msg_type will be populated*/
uint8_t * data, /* Output buffer */
size_t data_size, /* Max buffer size */
const char * msg) /* Message to encode */
{
m->msg_type = ADDNODE_ID;
if (data_size < AN_MIN_DATA_SIZE) {
return -1;
}
int16_t type;
char name[512];
sscanf(msg, "addnode %" SCNd16 "%s\n", &type, name);
data[AN_TYPE_ID_L] = LSByte16(type);
data[AN_TYPE_ID_H] = MSByte16(type);
memcpy(&data[AN_NAME], name, strlen(name) + 1); // We want to include the null byte
m->data_len = AN_MIN_DATA_SIZE + strlen(name);
return m->data_len;
}
enum ResponseGetnodesData {
RESP_GN_NUM_NODES_L,
RESP_GN_NUM_NODES_H,
RESP_GN_MIN_DATA_SIZE
};
/* Decode a metadata and data to populate a.
* Returns bytes written to msg, -1 on failure.
*/
int DecodeResponseGetNodes(
char * msg, /* Out */
size_t max_len, /* msg buffer max size */
const struct metadata *m, /* In */
const uint8_t * data) /* In */
{
/* See if we have the min. amount */
if (m->data_len < RESP_GN_MIN_DATA_SIZE) {
return -1;
}
if (m->msg_type != RESPNODES_ID) {
return -1;
}
uint16_t num_nodes = BytesTo16(data[RESP_GN_NUM_NODES_L], data[RESP_GN_NUM_NODES_H]);
/* resize the msg if necessary */
if (max_len < (m->data_len * 2)) {
max_len = max_len * 2;
msg = realloc(msg, sizeof(*msg) * max_len);
if (!msg) {
return -1;
}
}
int16_t val;
char name[512]; /* Corresponding to the maximum name len that the frontend will accept */
size_t i;
int msg_offset = 0;
int data_offset = RESP_GN_MIN_DATA_SIZE;
sprintf(msg, "getnodes %hu %n", num_nodes, &msg_offset);
msg += msg_offset;
for(i = 0; i < num_nodes * 3; ++i) {
if (i < num_nodes * 2) {
val = BytesTo16(data[data_offset], data[data_offset+1]);
data_offset += 2;
sprintf(msg, "%" PRId16 " %n", val, &msg_offset);
} else {
strncpy(name, (char *) &data[data_offset], 512);
data_offset += strlen(name) + 1;
sprintf(msg, "%s %n", name, &msg_offset);
}
msg += msg_offset;
}
return strlen(msg);
}
enum ResponseAddnodeData {
RESP_AN_BLOCK_ID_L,
RESP_AN_BLOCK_ID_H,
RESP_AN_DATA_SIZE
};
/* Decode a metadata and data to populate a controller.
* Returns bytes written to msg, -1 on failure.
*/
int DecodeResponseAddNode(
char * msg, /* Out */
size_t max_len, /* msg buffer max size */
const struct metadata *m, /* In */
const uint8_t * data) /* In */
{
if (m->data_len < RESP_AN_DATA_SIZE) {
return -1;
}
if (m->msg_type != RESPADDNODE_ID) {
return -1;
}
return sprintf(msg, "addnode %d",
BytesTo16(data[RESP_AN_BLOCK_ID_L], data[RESP_AN_BLOCK_ID_H]));
}