summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2024-05-02 00:00:34 -0400
committerKyle Gunger <kgunger12@gmail.com>2024-05-02 00:00:34 -0400
commitdc9df45dc6578704a367ab6a72842f65b1190f77 (patch)
tree2ba683aed5e1ba2fa3e72fc9706ad66615cbc336
parentaab7fe08faf2aec394174b2ee9782988bfc7fa30 (diff)
default listen and accept impl
-rw-r--r--include/osm/bind.h11
-rw-r--r--include/osm/device.h14
-rw-r--r--include/osm/discover.h1
-rw-r--r--include/osm/protocol.h102
-rw-r--r--src/bind.c62
-rw-r--r--src/discover.c29
-rw-r--r--src/protocol.c4
7 files changed, 214 insertions, 9 deletions
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 <osm/utils.h>
+#include <threads.h>
+
/**
* 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 <osm/utils.h>
+/*
+ * 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 <osm/utils.h>
+#include <osm/device.h>
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 <stdint.h>
+
+// 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 <errno.h>
#include <stdio.h>
+#include <stdint.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <threads.h>
+
#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,15 +143,64 @@ 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 <stdio.h>
+#include <dirent.h>
+#include <stddef.h>
+#include <errno.h>
+
+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";