housekeeping 2
This commit is contained in:
parent
e11c8b5c48
commit
2bd21ee138
2
client.c
2
client.c
|
@ -6,12 +6,14 @@
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/uinput.h>
|
#include <linux/uinput.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
1
hid.c
1
hid.c
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
2
hid.h
2
hid.h
|
@ -3,7 +3,7 @@
|
||||||
#define HID_H_
|
#define HID_H_
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
|
|
||||||
#include <linux/input.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef uint64_t uniq_t;
|
typedef uint64_t uniq_t;
|
||||||
|
|
351
json.c
351
json.c
|
@ -4,21 +4,16 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static JSONError jerrno = NoError;
|
static JSONError jerrno = NoError;
|
||||||
static size_t jerr_index = 0;
|
static size_t jerr_index = 0;
|
||||||
|
|
||||||
const char * json_strerr() {
|
const char *json_strerr() { return JSONErrorMessage[jerrno]; }
|
||||||
return JSONErrorMessage[jerrno];
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t json_err_loc() {
|
size_t json_err_loc() { return jerr_index; }
|
||||||
return jerr_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shorthand to set jerno and return -1;
|
// Shorthand to set jerno and return -1;
|
||||||
static inline int set_jerrno(JSONError err) {
|
static inline int set_jerrno(JSONError err) {
|
||||||
|
@ -26,7 +21,7 @@ static inline int set_jerrno(JSONError err) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
static inline size_t align_8(size_t n) { return (((n - 1) >> 3) + 1) << 3; }
|
static inline size_t align_8(size_t n) { return (((n - 1) >> 3) + 1) << 3; }
|
||||||
static inline bool is_whitespace(char c) { return c == ' ' || c == '\t' || c == '\n'; }
|
static inline bool is_whitespace(char c) { return c == ' ' || c == '\t' || c == '\n'; }
|
||||||
|
|
||||||
static int json_parse_value(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
static int json_parse_value(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
||||||
const uint8_t *dst_end);
|
const uint8_t *dst_end);
|
||||||
|
@ -272,22 +267,24 @@ static int json_parse_boolean(const char **buf, const char *buf_end, uint8_t **r
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONHeader *header = (JSONHeader *)(*dst);
|
JSONHeader *header = (JSONHeader *)(*dst);
|
||||||
uint64_t *value = (uint64_t *)((*dst) + sizeof(JSONHeader));
|
uint64_t *value = (uint64_t *)((*dst) + sizeof(JSONHeader));
|
||||||
*dst += sizeof(JSONHeader) + 8;
|
*dst += sizeof(JSONHeader) + 8;
|
||||||
|
|
||||||
header->type = (uint32_t)Boolean;
|
header->type = (uint32_t)Boolean;
|
||||||
header->len = 8;
|
header->len = 8;
|
||||||
|
|
||||||
if(**buf == 't') {
|
if (**buf == 't') {
|
||||||
if(*buf + 4 > buf_end) return set_jerrno(SrcOverflow);
|
if (*buf + 4 > buf_end)
|
||||||
if(strncmp(*buf, "true", 4) != 0) {
|
return set_jerrno(SrcOverflow);
|
||||||
|
if (strncmp(*buf, "true", 4) != 0) {
|
||||||
return set_jerrno(BadKeyword);
|
return set_jerrno(BadKeyword);
|
||||||
}
|
}
|
||||||
*buf += 4;
|
*buf += 4;
|
||||||
*value = 1;
|
*value = 1;
|
||||||
} else if(**buf == 'f') {
|
} else if (**buf == 'f') {
|
||||||
if(*buf + 5 > buf_end) return set_jerrno(SrcOverflow);
|
if (*buf + 5 > buf_end)
|
||||||
if(strncmp(*buf, "false", 5) != 0) {
|
return set_jerrno(SrcOverflow);
|
||||||
|
if (strncmp(*buf, "false", 5) != 0) {
|
||||||
return set_jerrno(BadKeyword);
|
return set_jerrno(BadKeyword);
|
||||||
}
|
}
|
||||||
*buf += 5;
|
*buf += 5;
|
||||||
|
@ -300,7 +297,7 @@ static int json_parse_boolean(const char **buf, const char *buf_end, uint8_t **r
|
||||||
|
|
||||||
// *dst must be 8 aligned
|
// *dst must be 8 aligned
|
||||||
static int json_parse_null(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
static int json_parse_null(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
||||||
const uint8_t *dst_end) {
|
const uint8_t *dst_end) {
|
||||||
|
|
||||||
if (*dst + sizeof(JSONHeader) >= dst_end) {
|
if (*dst + sizeof(JSONHeader) >= dst_end) {
|
||||||
return set_jerrno(DstOverflow);
|
return set_jerrno(DstOverflow);
|
||||||
|
@ -312,8 +309,9 @@ static int json_parse_null(const char **buf, const char *buf_end, uint8_t **rest
|
||||||
header->type = (uint32_t)Null;
|
header->type = (uint32_t)Null;
|
||||||
header->len = 0;
|
header->len = 0;
|
||||||
|
|
||||||
if(*buf + 4 > buf_end) return set_jerrno(SrcOverflow);
|
if (*buf + 4 > buf_end)
|
||||||
if(strncmp(*buf, "null", 4) != 0) {
|
return set_jerrno(SrcOverflow);
|
||||||
|
if (strncmp(*buf, "null", 4) != 0) {
|
||||||
return set_jerrno(BadKeyword);
|
return set_jerrno(BadKeyword);
|
||||||
}
|
}
|
||||||
*buf += 4;
|
*buf += 4;
|
||||||
|
@ -322,7 +320,7 @@ static int json_parse_null(const char **buf, const char *buf_end, uint8_t **rest
|
||||||
|
|
||||||
// *dst must be 8 aligned
|
// *dst must be 8 aligned
|
||||||
static int json_parse_array(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
static int json_parse_array(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
||||||
const uint8_t *dst_end) {
|
const uint8_t *dst_end) {
|
||||||
|
|
||||||
if (*dst + sizeof(JSONHeader) >= dst_end) {
|
if (*dst + sizeof(JSONHeader) >= dst_end) {
|
||||||
return set_jerrno(DstOverflow);
|
return set_jerrno(DstOverflow);
|
||||||
|
@ -330,25 +328,30 @@ static int json_parse_array(const char **buf, const char *buf_end, uint8_t **res
|
||||||
|
|
||||||
JSONHeader *header = (JSONHeader *)(*dst);
|
JSONHeader *header = (JSONHeader *)(*dst);
|
||||||
*dst += sizeof(JSONHeader);
|
*dst += sizeof(JSONHeader);
|
||||||
uint8_t * dst_arr_start = *dst;
|
uint8_t *dst_arr_start = *dst;
|
||||||
|
|
||||||
header->type = (uint32_t)Array;
|
header->type = (uint32_t)Array;
|
||||||
|
|
||||||
(*buf)++; // Skip [
|
(*buf)++; // Skip [
|
||||||
// skip initial whitespace
|
// skip initial whitespace
|
||||||
for(; *buf < buf_end && is_whitespace(**buf); (*buf)++);
|
for (; *buf < buf_end && is_whitespace(**buf); (*buf)++)
|
||||||
if(*buf == buf_end) return set_jerrno(SrcOverflow);
|
;
|
||||||
if(**buf == ']') {
|
if (*buf == buf_end)
|
||||||
|
return set_jerrno(SrcOverflow);
|
||||||
|
if (**buf == ']') {
|
||||||
header->len = 0;
|
header->len = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
while(1) {
|
while (1) {
|
||||||
if (json_parse_value(buf, buf_end, dst, dst_end) != 0) return -1;
|
if (json_parse_value(buf, buf_end, dst, dst_end) != 0)
|
||||||
for(; *buf < buf_end && is_whitespace(**buf); (*buf)++);
|
return -1;
|
||||||
if (*buf == buf_end) return set_jerrno(SrcOverflow);
|
for (; *buf < buf_end && is_whitespace(**buf); (*buf)++)
|
||||||
if(**buf == ',') {
|
;
|
||||||
|
if (*buf == buf_end)
|
||||||
|
return set_jerrno(SrcOverflow);
|
||||||
|
if (**buf == ',') {
|
||||||
(*buf)++;
|
(*buf)++;
|
||||||
} else if(**buf == ']') {
|
} else if (**buf == ']') {
|
||||||
(*buf)++;
|
(*buf)++;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -361,7 +364,7 @@ static int json_parse_array(const char **buf, const char *buf_end, uint8_t **res
|
||||||
|
|
||||||
// *dst must be 8 aligned
|
// *dst must be 8 aligned
|
||||||
static int json_parse_object(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
static int json_parse_object(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
||||||
const uint8_t *dst_end) {
|
const uint8_t *dst_end) {
|
||||||
|
|
||||||
if (*dst + sizeof(JSONHeader) >= dst_end) {
|
if (*dst + sizeof(JSONHeader) >= dst_end) {
|
||||||
return set_jerrno(DstOverflow);
|
return set_jerrno(DstOverflow);
|
||||||
|
@ -369,41 +372,51 @@ static int json_parse_object(const char **buf, const char *buf_end, uint8_t **re
|
||||||
|
|
||||||
JSONHeader *header = (JSONHeader *)(*dst);
|
JSONHeader *header = (JSONHeader *)(*dst);
|
||||||
*dst += sizeof(JSONHeader);
|
*dst += sizeof(JSONHeader);
|
||||||
uint8_t * dst_obj_start = *dst;
|
uint8_t *dst_obj_start = *dst;
|
||||||
|
|
||||||
header->type = (uint32_t)Object;
|
header->type = (uint32_t)Object;
|
||||||
|
|
||||||
(*buf)++; // Skip {
|
(*buf)++; // Skip {
|
||||||
|
|
||||||
for(; *buf < buf_end && is_whitespace(**buf); (*buf)++);
|
for (; *buf < buf_end && is_whitespace(**buf); (*buf)++)
|
||||||
if(*buf == buf_end) return set_jerrno(SrcOverflow);
|
;
|
||||||
if(**buf == '}') {
|
if (*buf == buf_end)
|
||||||
|
return set_jerrno(SrcOverflow);
|
||||||
|
if (**buf == '}') {
|
||||||
header->len = 0;
|
header->len = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(1) {
|
while (1) {
|
||||||
// Skip whitespace before key
|
// Skip whitespace before key
|
||||||
for(; *buf < buf_end && is_whitespace(**buf); (*buf)++);
|
for (; *buf < buf_end && is_whitespace(**buf); (*buf)++)
|
||||||
|
;
|
||||||
// Parse key
|
// Parse key
|
||||||
if (json_parse_string(buf, buf_end, dst, dst_end) != 0) return -1;
|
if (json_parse_string(buf, buf_end, dst, dst_end) != 0)
|
||||||
|
return -1;
|
||||||
// Skip whitespace after key
|
// Skip whitespace after key
|
||||||
for(; *buf < buf_end && is_whitespace(**buf); (*buf)++);
|
for (; *buf < buf_end && is_whitespace(**buf); (*buf)++)
|
||||||
|
;
|
||||||
// There should be at least one char
|
// There should be at least one char
|
||||||
if(*buf == buf_end) return set_jerrno(SrcOverflow);
|
if (*buf == buf_end)
|
||||||
|
return set_jerrno(SrcOverflow);
|
||||||
// There should be a colon
|
// There should be a colon
|
||||||
if(**buf != ':') return set_jerrno(ObjectBadChar);
|
if (**buf != ':')
|
||||||
|
return set_jerrno(ObjectBadChar);
|
||||||
// Skip colon
|
// Skip colon
|
||||||
(*buf)++;
|
(*buf)++;
|
||||||
// Parse value (takes char of whitespace)
|
// Parse value (takes char of whitespace)
|
||||||
if (json_parse_value(buf, buf_end, dst, dst_end) != 0) return -1;
|
if (json_parse_value(buf, buf_end, dst, dst_end) != 0)
|
||||||
|
return -1;
|
||||||
// Skip whitespace after value
|
// Skip whitespace after value
|
||||||
for(; *buf < buf_end && is_whitespace(**buf); (*buf)++);
|
for (; *buf < buf_end && is_whitespace(**buf); (*buf)++)
|
||||||
|
;
|
||||||
// There should be at least one char (} or ,)
|
// There should be at least one char (} or ,)
|
||||||
if (*buf == buf_end) return set_jerrno(SrcOverflow);
|
if (*buf == buf_end)
|
||||||
if(**buf == ',') {
|
return set_jerrno(SrcOverflow);
|
||||||
|
if (**buf == ',') {
|
||||||
(*buf)++;
|
(*buf)++;
|
||||||
} else if(**buf == '}') {
|
} else if (**buf == '}') {
|
||||||
(*buf)++;
|
(*buf)++;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -418,7 +431,8 @@ static int json_parse_object(const char **buf, const char *buf_end, uint8_t **re
|
||||||
static int json_parse_value(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
static int json_parse_value(const char **buf, const char *buf_end, uint8_t **restrict dst,
|
||||||
const uint8_t *dst_end) {
|
const uint8_t *dst_end) {
|
||||||
for (; *buf < buf_end; (*buf)++) {
|
for (; *buf < buf_end; (*buf)++) {
|
||||||
if(is_whitespace(**buf)) continue;
|
if (is_whitespace(**buf))
|
||||||
|
continue;
|
||||||
|
|
||||||
switch (**buf) {
|
switch (**buf) {
|
||||||
case '"':
|
case '"':
|
||||||
|
@ -453,82 +467,76 @@ static int json_parse_value(const char **buf, const char *buf_end, uint8_t **res
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int json_parse(const char * src, size_t src_len, uint8_t * dst, size_t dst_len) {
|
int json_parse(const char *src, size_t src_len, uint8_t *dst, size_t dst_len) {
|
||||||
memset(dst, 0, dst_len);
|
memset(dst, 0, dst_len);
|
||||||
const char * buf = src;
|
const char *buf = src;
|
||||||
const char * buf_end = src + src_len;
|
const char *buf_end = src + src_len;
|
||||||
uint8_t * dst_end = dst + dst_len;
|
uint8_t *dst_end = dst + dst_len;
|
||||||
int rc = json_parse_value(&buf, buf_end, &dst, dst_end);
|
int rc = json_parse_value(&buf, buf_end, &dst, dst_end);
|
||||||
jerr_index = buf - src;
|
jerr_index = buf - src;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void json_print_value(uint8_t ** buf) {
|
void json_print_value(uint8_t **buf) {
|
||||||
JSONHeader * header = (JSONHeader*) *buf;
|
JSONHeader *header = (JSONHeader *)*buf;
|
||||||
*buf += sizeof(header);
|
*buf += sizeof(header);
|
||||||
switch(header->type) {
|
switch (header->type) {
|
||||||
case String:
|
case String:
|
||||||
printf("\"%.*s\"", header->len, *buf);
|
printf("\"%.*s\"", header->len, *buf);
|
||||||
*buf += align_8(header->len);
|
*buf += align_8(header->len);
|
||||||
break;
|
break;
|
||||||
case Number:
|
case Number:
|
||||||
printf("%lf", *(double *)*buf);
|
printf("%lf", *(double *)*buf);
|
||||||
*buf += sizeof(double);
|
*buf += sizeof(double);
|
||||||
break;
|
break;
|
||||||
case Boolean:
|
case Boolean: {
|
||||||
{
|
uint64_t value = *(uint64_t *)*buf;
|
||||||
uint64_t value = *(uint64_t*)*buf;
|
if (value == 1) {
|
||||||
if(value == 1) {
|
printf("true");
|
||||||
printf("true");
|
} else if (value == 0) {
|
||||||
} else if(value == 0) {
|
printf("false");
|
||||||
printf("false");
|
} else {
|
||||||
} else {
|
printf("(boolean) garbage");
|
||||||
printf("(boolean) garbage");
|
}
|
||||||
}
|
*buf += 8;
|
||||||
*buf += 8;
|
} break;
|
||||||
|
case Null:
|
||||||
|
printf("null");
|
||||||
|
break;
|
||||||
|
case Array: {
|
||||||
|
uint8_t *end = *buf + header->len;
|
||||||
|
printf("[");
|
||||||
|
while (1) {
|
||||||
|
json_print_value(buf);
|
||||||
|
if (*buf < end) {
|
||||||
|
printf(", ");
|
||||||
|
} else {
|
||||||
|
printf("]");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case Null:
|
} break;
|
||||||
printf("null");
|
case Object: {
|
||||||
break;
|
uint8_t *end = *buf + header->len;
|
||||||
case Array:
|
printf("{");
|
||||||
{
|
while (1) {
|
||||||
uint8_t * end = *buf + header->len;
|
json_print_value(buf);
|
||||||
printf("[");
|
printf(":");
|
||||||
while(1) {
|
json_print_value(buf);
|
||||||
json_print_value(buf);
|
if (*buf < end) {
|
||||||
if(*buf < end) {
|
printf(",");
|
||||||
printf(", ");
|
} else {
|
||||||
} else {
|
printf("}");
|
||||||
printf("]");
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case Object:
|
} break;
|
||||||
{
|
|
||||||
uint8_t * end = *buf + header->len;
|
|
||||||
printf("{");
|
|
||||||
while(1) {
|
|
||||||
json_print_value(buf);
|
|
||||||
printf(":");
|
|
||||||
json_print_value(buf);
|
|
||||||
if(*buf < end) {
|
|
||||||
printf(",");
|
|
||||||
} else {
|
|
||||||
printf("}");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Test {
|
struct Test {
|
||||||
double a;
|
double a;
|
||||||
char * b;
|
char *b;
|
||||||
};
|
};
|
||||||
|
|
||||||
const JSONAdapter TestAdapter[] = {
|
const JSONAdapter TestAdapter[] = {
|
||||||
|
@ -536,79 +544,74 @@ const JSONAdapter TestAdapter[] = {
|
||||||
{".b", String, offsetof(struct Test, b)},
|
{".b", String, offsetof(struct Test, b)},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void json_adapt_set(uint8_t * buf, JSONAdapter * adapters, size_t adapter_count, void * ptr, char * path) {
|
static void json_adapt_set(uint8_t *buf, JSONAdapter *adapters, size_t adapter_count, void *ptr, char *path) {
|
||||||
JSONHeader * header = (JSONHeader *)buf;
|
JSONHeader *header = (JSONHeader *)buf;
|
||||||
for(int i = 0; i < adapter_count; i++) {
|
for (int i = 0; i < adapter_count; i++) {
|
||||||
if(strcmp(path, adapters[i].path) == 0 && header->type == adapters[i].type) {
|
if (strcmp(path, adapters[i].path) == 0 && header->type == adapters[i].type) {
|
||||||
void * p = ptr + adapters[i].offset;
|
void *p = ptr + adapters[i].offset;
|
||||||
switch(header->type) {
|
switch (header->type) {
|
||||||
case String:
|
case String: {
|
||||||
{
|
char *v = malloc(header->len + 1);
|
||||||
char * v = malloc(header->len + 1);
|
strncpy(v, (char *)(buf + sizeof(JSONHeader)), header->len);
|
||||||
strncpy(v, (char *)(buf + sizeof(JSONHeader)), header->len);
|
v[header->len] = '\0';
|
||||||
v[header->len] = '\0';
|
*(char **)p = v;
|
||||||
*(char**)p = v;
|
} break;
|
||||||
}
|
case Number:
|
||||||
break;
|
*(double *)p = *(double *)(buf + sizeof(JSONHeader));
|
||||||
case Number:
|
break;
|
||||||
*(double*)p = *(double*)(buf + sizeof(JSONHeader));
|
case Boolean:
|
||||||
break;
|
*(bool *)p = *(uint64_t *)(buf + sizeof(JSONHeader)) == 1;
|
||||||
case Boolean:
|
break;
|
||||||
*(bool*)p = *(uint64_t*)(buf + sizeof(JSONHeader)) == 1;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_adapt_priv(uint8_t ** buf, JSONAdapter * adapters, size_t adapter_count, void * ptr, char * full_path, char * path) {
|
static void json_adapt_priv(uint8_t **buf, JSONAdapter *adapters, size_t adapter_count, void *ptr,
|
||||||
JSONHeader * header = (JSONHeader *)*buf;
|
char *full_path, char *path) {
|
||||||
|
JSONHeader *header = (JSONHeader *)*buf;
|
||||||
|
|
||||||
switch(header->type) {
|
switch (header->type) {
|
||||||
case String:
|
case String:
|
||||||
json_adapt_set(*buf, adapters, adapter_count, ptr, full_path);
|
json_adapt_set(*buf, adapters, adapter_count, ptr, full_path);
|
||||||
*buf += sizeof(JSONHeader) + align_8(header->len);
|
*buf += sizeof(JSONHeader) + align_8(header->len);
|
||||||
break;
|
break;
|
||||||
case Number:
|
case Number:
|
||||||
json_adapt_set(*buf, adapters, adapter_count, ptr, full_path);
|
json_adapt_set(*buf, adapters, adapter_count, ptr, full_path);
|
||||||
*buf += sizeof(JSONHeader) + sizeof(double);
|
*buf += sizeof(JSONHeader) + sizeof(double);
|
||||||
break;
|
break;
|
||||||
case Boolean:
|
case Boolean:
|
||||||
json_adapt_set(*buf, adapters, adapter_count, ptr, full_path);
|
json_adapt_set(*buf, adapters, adapter_count, ptr, full_path);
|
||||||
*buf += sizeof(JSONHeader) + 8;
|
*buf += sizeof(JSONHeader) + 8;
|
||||||
break;
|
break;
|
||||||
case Null:
|
case Null:
|
||||||
|
*buf += sizeof(JSONHeader);
|
||||||
|
break;
|
||||||
|
case Array: {
|
||||||
|
*buf += sizeof(JSONHeader);
|
||||||
|
uint8_t *end = *buf + header->len;
|
||||||
|
for (size_t index = 0; *buf < end; index++) {
|
||||||
|
int len = sprintf(path, ".%lu", index);
|
||||||
|
json_adapt_priv(buf, adapters, adapter_count, ptr, full_path, path + len);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case Object: {
|
||||||
|
*buf += sizeof(JSONHeader);
|
||||||
|
uint8_t *end = *buf + header->len;
|
||||||
|
while (*buf < end) {
|
||||||
|
JSONHeader *key_header = (JSONHeader *)*buf;
|
||||||
*buf += sizeof(JSONHeader);
|
*buf += sizeof(JSONHeader);
|
||||||
break;
|
|
||||||
case Array:
|
|
||||||
{
|
|
||||||
*buf += sizeof(JSONHeader);
|
|
||||||
uint8_t * end = *buf + header->len;
|
|
||||||
for(size_t index = 0; *buf < end; index++) {
|
|
||||||
int len = sprintf(path, ".%lu", index);
|
|
||||||
json_adapt_priv(buf, adapters, adapter_count, ptr, full_path, path + len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Object:
|
|
||||||
{
|
|
||||||
*buf += sizeof(JSONHeader);
|
|
||||||
uint8_t * end = *buf + header->len;
|
|
||||||
while(*buf < end) {
|
|
||||||
JSONHeader * key_header = (JSONHeader*)*buf;
|
|
||||||
*buf += sizeof(JSONHeader);
|
|
||||||
|
|
||||||
int len = sprintf(path, ".%.*s", key_header->len, *buf);
|
int len = sprintf(path, ".%.*s", key_header->len, *buf);
|
||||||
*buf += align_8(key_header->len);
|
*buf += align_8(key_header->len);
|
||||||
|
|
||||||
json_adapt_priv(buf, adapters, adapter_count, ptr, full_path, path + len);
|
json_adapt_priv(buf, adapters, adapter_count, ptr, full_path, path + len);
|
||||||
}
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void json_adapt(uint8_t * buf, JSONAdapter * adapters, size_t adapter_count, void * ptr) {
|
void json_adapt(uint8_t *buf, JSONAdapter *adapters, size_t adapter_count, void *ptr) {
|
||||||
char path[512] = ".";
|
char path[512] = ".";
|
||||||
json_adapt_priv(&buf, adapters, adapter_count, ptr, path, path);
|
json_adapt_priv(&buf, adapters, adapter_count, ptr, path, path);
|
||||||
}
|
}
|
||||||
|
|
19
json.h
19
json.h
|
@ -1,10 +1,9 @@
|
||||||
// vi:ft=c
|
// vi:ft=c
|
||||||
#ifndef JSON_H_
|
#ifndef JSON_H_
|
||||||
#define JSON_H_
|
#define JSON_H_
|
||||||
#include <stdint.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct __attribute__((packed, aligned(8))) {
|
typedef struct __attribute__((packed, aligned(8))) {
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
|
@ -39,7 +38,7 @@ typedef enum {
|
||||||
} JSONError;
|
} JSONError;
|
||||||
|
|
||||||
#ifdef JSON_C_
|
#ifdef JSON_C_
|
||||||
static const char * JSONErrorMessage[JERRORNO_MAX + 1] = {
|
static const char *JSONErrorMessage[JERRORNO_MAX + 1] = {
|
||||||
"No error",
|
"No error",
|
||||||
"Destination buffer is not big enough",
|
"Destination buffer is not big enough",
|
||||||
"Source buffer overflowed before parsing finished",
|
"Source buffer overflowed before parsing finished",
|
||||||
|
@ -50,19 +49,19 @@ static const char * JSONErrorMessage[JERRORNO_MAX + 1] = {
|
||||||
"Illegal escape in string",
|
"Illegal escape in string",
|
||||||
"Unexpected character in number",
|
"Unexpected character in number",
|
||||||
"Unexpected character in object",
|
"Unexpected character in object",
|
||||||
"?"
|
"?",
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char * path;
|
char *path;
|
||||||
JSONType type;
|
JSONType type;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
} JSONAdapter;
|
} JSONAdapter;
|
||||||
|
|
||||||
void json_adapt(uint8_t * buf, JSONAdapter * adapters, size_t adapter_count, void * ptr);
|
void json_adapt(uint8_t *buf, JSONAdapter *adapters, size_t adapter_count, void *ptr);
|
||||||
int json_parse(const char * src, size_t src_len, uint8_t * dst, size_t dst_len);
|
int json_parse(const char *src, size_t src_len, uint8_t *dst, size_t dst_len);
|
||||||
const char * json_strerr();
|
const char *json_strerr();
|
||||||
size_t json_err_loc();
|
size_t json_err_loc();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
10
net.c
10
net.c
|
@ -13,7 +13,7 @@ Message msg_device_info() {
|
||||||
|
|
||||||
// Deserialize the message in buf, buf must be at least 4 aligned. Returns -1 on error, otherwise returns 0
|
// Deserialize the message in buf, buf must be at least 4 aligned. Returns -1 on error, otherwise returns 0
|
||||||
// and writes result to dst
|
// and writes result to dst
|
||||||
int msg_deserialize(const uint8_t *buf, size_t len, Message * restrict dst) {
|
int msg_deserialize(const uint8_t *buf, size_t len, Message *restrict dst) {
|
||||||
// Decrement len so that it becomes the len of the data without the code.
|
// Decrement len so that it becomes the len of the data without the code.
|
||||||
if (len-- < 1)
|
if (len-- < 1)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -118,7 +118,7 @@ int msg_deserialize(const uint8_t *buf, size_t len, Message * restrict dst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Serialize the message msg in buf, buf must be at least 4 aligned. Returns -1 on error (buf not big enough);
|
// Serialize the message msg in buf, buf must be at least 4 aligned. Returns -1 on error (buf not big enough);
|
||||||
int msg_serialize(uint8_t * restrict buf, size_t len, const Message *msg) {
|
int msg_serialize(uint8_t *restrict buf, size_t len, const Message *msg) {
|
||||||
// If len is 0 we can't serialize any message
|
// If len is 0 we can't serialize any message
|
||||||
if (len-- == 0)
|
if (len-- == 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -134,9 +134,9 @@ int msg_serialize(uint8_t * restrict buf, size_t len, const Message *msg) {
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// We begin 4 aligned
|
// We begin 4 aligned
|
||||||
buf[0] = (uint8_t)msg->code;
|
buf[0] = (uint8_t)msg->code;
|
||||||
// buf + 2: a byte for code and a byte for padding
|
// buf + 2: a byte for code and a byte for padding
|
||||||
buf16 = (uint16_t *)(buf + 2);
|
buf16 = (uint16_t *)(buf + 2);
|
||||||
// 2 aligned here
|
// 2 aligned here
|
||||||
buf16[0] = abs;
|
buf16[0] = abs;
|
||||||
buf16[1] = rel;
|
buf16[1] = rel;
|
||||||
|
@ -177,7 +177,7 @@ int msg_serialize(uint8_t * restrict buf, size_t len, const Message *msg) {
|
||||||
if (len < MSS_DEVICE_REPORT(abs, rel, key))
|
if (len < MSS_DEVICE_REPORT(abs, rel, key))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
buf[0] = (uint8_t)msg->code;
|
buf[0] = (uint8_t)msg->code;
|
||||||
// buf + 2: a byte for code and a byte for padding
|
// buf + 2: a byte for code and a byte for padding
|
||||||
buf16 = (uint16_t *)(buf + 2);
|
buf16 = (uint16_t *)(buf + 2);
|
||||||
buf16[0] = abs;
|
buf16[0] = abs;
|
||||||
|
|
6
net.h
6
net.h
|
@ -1,7 +1,7 @@
|
||||||
// vi:ft=c
|
// vi:ft=c
|
||||||
#ifndef NET_H_
|
#ifndef NET_H_
|
||||||
#define NET_H_
|
#define NET_H_
|
||||||
#include <linux/input.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ typedef union {
|
||||||
MessageControllerState controller_state;
|
MessageControllerState controller_state;
|
||||||
} Message;
|
} Message;
|
||||||
|
|
||||||
int msg_deserialize(const uint8_t *buf, size_t len, Message * restrict dst);
|
int msg_deserialize(const uint8_t *buf, size_t len, Message *restrict dst);
|
||||||
int msg_serialize(uint8_t * restrict buf, size_t len, const Message *msg);
|
int msg_serialize(uint8_t *restrict buf, size_t len, const Message *msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
7
server.c
7
server.c
|
@ -2,6 +2,7 @@
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
|
@ -40,14 +41,14 @@ void *server_handle_conn(void *args_) {
|
||||||
printf("ERR(server_handle_conn): Setting idle retry interval\n");
|
printf("ERR(server_handle_conn): Setting idle retry interval\n");
|
||||||
|
|
||||||
uint8_t buf[2048] __attribute__((aligned(4))) = {};
|
uint8_t buf[2048] __attribute__((aligned(4))) = {};
|
||||||
PhysicalDevice dev = get_device();
|
PhysicalDevice dev = get_device();
|
||||||
printf("CONN(%u): got device '%s'\n", args->id, dev.name);
|
printf("CONN(%u): got device '%s'\n", args->id, dev.name);
|
||||||
|
|
||||||
char *closing_message = "";
|
char *closing_message = "";
|
||||||
|
|
||||||
int len = msg_serialize(buf, 2048, (Message *)&dev.device_info);
|
int len = msg_serialize(buf, 2048, (Message *)&dev.device_info);
|
||||||
if(len > 0) {
|
if (len > 0) {
|
||||||
if(write(args->socket, buf, len) == -1) {
|
if (write(args->socket, buf, len) == -1) {
|
||||||
perror("SERVER: Couldn't send device info, ");
|
perror("SERVER: Couldn't send device info, ");
|
||||||
closing_message = "Socket error";
|
closing_message = "Socket error";
|
||||||
goto conn_end;
|
goto conn_end;
|
||||||
|
|
Loading…
Reference in New Issue