From dc9df45dc6578704a367ab6a72842f65b1190f77 Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Thu, 2 May 2024 00:00:34 -0400 Subject: default listen and accept impl --- include/osm/bind.h | 11 ++++++ include/osm/device.h | 14 ++++++- include/osm/discover.h | 1 + include/osm/protocol.h | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ src/bind.c | 62 +++++++++++++++++++++++++++--- src/discover.c | 29 ++++++++++++-- src/protocol.c | 4 ++ 7 files changed, 214 insertions(+), 9 deletions(-) create mode 100644 include/osm/protocol.h create mode 100644 src/protocol.c diff --git a/include/osm/bind.h b/include/osm/bind.h index e1627c6..d56533c 100644 --- a/include/osm/bind.h +++ b/include/osm/bind.h @@ -1,6 +1,9 @@ #ifndef OSM_BIND_H #define OSM_BIND_H +#include +#include + /** * Bind to the next available onboard socket in the given directory * sock_dir - The directory containing osm sockets (or null for the default) @@ -14,4 +17,12 @@ int osm_bind_local(int sockfd, const char *sock_dir); */ int osm_open_onboard(char *sock_dir); +/** + * Listen for socket connections and return the new + * file descriptors to the callback function for processing + * sockfd - the socket file descriptor + * callback - the callback function which will be provided with the new file descriptor + */ +Vector osm_listen_and_accept(int sockfd, thrd_start_t callback); + #endif diff --git a/include/osm/device.h b/include/osm/device.h index 51a4ff2..edf9c12 100644 --- a/include/osm/device.h +++ b/include/osm/device.h @@ -3,8 +3,20 @@ #include +/* + * Define connection types + */ +#define OSM_CT_FILE 0 +#define OSM_CT_TCP 1 + +/** + * Device context: can be used to interact with an underlying device + */ typedef struct { - + char *name; + unsigned int conn_type; + char *address; + Vector inputs, outputs; } OSMDevice; #endif diff --git a/include/osm/discover.h b/include/osm/discover.h index 68bda60..cab24aa 100644 --- a/include/osm/discover.h +++ b/include/osm/discover.h @@ -2,6 +2,7 @@ #define OSM_DISCOVER_H #include +#include Vector osm_discover_onboard(char *sock_dir); diff --git a/include/osm/protocol.h b/include/osm/protocol.h new file mode 100644 index 0000000..29eb6cc --- /dev/null +++ b/include/osm/protocol.h @@ -0,0 +1,102 @@ +#ifndef OSM_PROTOCOL_H +#define OSM_PROTOCOL_H + +#include + +// The types used in connections + +/* + * Before signatures can be validated, we need to get + * a public verification key, along with the firendly + * name and type of device. + * + * These are those initial connection frames. + */ + +/// The magic number for init frames +extern const char OSM_MAGIC_INIT[4]; +/// The magic number for normal frames +extern const char OSM_MAGIC_FRAME[4]; + +/** + * The init frame from the controller + * includes the uuid of the sender and the public + * key the sender will use to sign messages (up to 4096 bytes) + * + * The paired device will send one back at the end of the pairing + * process. In the end frame, the pubkey is encrypted by the pairing code. + */ +typedef struct { + uint8_t magic[4]; + uint8_t uuid[8]; + uint8_t keytype; + uint16_t keylen; + uint8_t pubkey[4096]; +} OSMInitFrame; + +/** + * Represents the format of the pairing code type that the + * initializing device will give the user. + */ +typedef struct { + uint8_t magic[4]; + uint8_t uuid[8]; + +} OSMInitPairfmt; + + +/** + * All OSM messages are at most 2048 bytes long and include a gpg signature at + * the start of the data to validate the sender. The signature length is determined based on + * the signing key of the sender. + */ +typedef struct { + uint8_t magic[4]; // magic number + uint8_t uuid[8]; // device that this message is from + uint8_t sub_uuid[8]; // sub device that this message is from + uint8_t frame_type; // type of frame + uint8_t data[2048]; // message data +} OSMFrame; + +/* + * Once the data has been validated, it is one of the following frame types + */ + +/// Result of previously sent frame, with information requested (if any) +#define OSM_FT_RES 0 +/// Set a sensor/config value on the device +#define OSM_FT_SET 1 +/// Get a sensor/config value from the device +#define OSM_FT_GET 2 +/// Send data +#define OSM_FT_DAT 3 +/// Setup new stream (value out to device FROM THIS MACHINE) +#define OSM_FT_SVO 4 +/// Setup new stream (value in from device TO THIS MACHINE) +#define OSM_FT_SVI 5 +/// Close stream +#define OSM_FT_SCL 6 + +/** + * Result of a sent frame + */ +typedef struct { + uint8_t res_type; // the type of frame sent + uint8_t a; +} OSMResFrame; + +typedef struct { + uint8_t num_set; + uint8_t pairs[2047]; +} OSMSetFrame; + +typedef struct { + uint8_t control_id[8]; // The ID of the control we are setting the value on + uint8_t val_type; // The data type of the value (or 0 for future data frames) + uint8_t value[8]; // The new value for the control, or the data frame number we will next use +} OSMSetControl; + + + +#endif + diff --git a/src/bind.c b/src/bind.c index 786624c..7392db3 100644 --- a/src/bind.c +++ b/src/bind.c @@ -1,12 +1,16 @@ #include "osm/bind.h" +#include "osm/utils.h" #include #include +#include #include #include #include +#include + #define MAX_ID 0xFFFF @@ -122,9 +126,8 @@ int osm_bind_local(int sockfd, const char *sock_dir) int osm_open_onboard(char *sock_dir) { int sockfd = socket(AF_LOCAL, SOCK_SEQPACKET, 0); - if (sockfd < 0) + if (sockfd == -1) { - perror("socket"); return sockfd; } @@ -140,14 +143,63 @@ int osm_open_onboard(char *sock_dir) if (bound != 0) { - perror("bind"); close(sockfd); - return bound; + return -1; } - + + listen(sockfd, 3); return sockfd; } +/** + * Listen for and return connections for a socket + * return - a vector containing all the threads which this function started + */ +Vector osm_listen_and_accept(int sockfd, thrd_start_t callback) +{ + Vector out = vect_init(sizeof(thrd_t)); + thrd_t thread; + + while(1) + { + // Try to accept a connection + errno = 0; + int fd = accept(sockfd, NULL, NULL); + if (fd == -1) + { + if (errno != ECONNABORTED && errno != EINTR) + { + break; + } + else + continue; + } + + // Create and store the connection thread + errno = 0; + int ret = thrd_create(&thread, callback, (void*)(uintptr_t)fd); + if(ret == thrd_success) + { + vect_push(&out, &thread); + } + else + { + if (ret == thrd_error) + { + perror("Error creating thread"); + } + else if (ret == thrd_nomem) + { + fprintf(stderr, "Thread out of memory. Shutting down.\n"); + } + break; + } + + } + + return out; +} + /** * Bind a new network socket * Should only be called by one process on the machine. diff --git a/src/discover.c b/src/discover.c index 1d8259a..53eef73 100644 --- a/src/discover.c +++ b/src/discover.c @@ -1,8 +1,31 @@ -#include "osm/discover.h" +#include "osm/utils.h" -Vector osm_discover_onboard(char *sock_fd) +#include +#include +#include +#include + +Vector osm_discover_onboard(char *sock_dir) { - Vector out = {0}; + Vector out = vect_init(sizeof(char)); + + DIR *d = opendir(sock_dir); + if (d) + { + struct dirent *dir; + while((dir = readdir(d)) != NULL) + { + if (dir->d_type == DT_SOCK) + { + } + } + errno = 0; + closedir(d); + } + else + { + perror("opendir"); + } return out; } diff --git a/src/protocol.c b/src/protocol.c new file mode 100644 index 0000000..b2254cb --- /dev/null +++ b/src/protocol.c @@ -0,0 +1,4 @@ +#include "osm/protocol.h" + +const char OSM_MAGIC_INIT[4] = "OSmI"; +const char OSM_MAGIC_FRAME[4] = "OSmF"; -- cgit v1.2.3