about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorlatex <latex@disroot.org>2023-02-11 02:01:21 +0100
committerlatex <latex@disroot.org>2023-02-11 02:01:21 +0100
commit82ca959ff701832e96c869161adc5e179c2201dd (patch)
tree3a819f5b26cfd3703a229eaf2ea187c3fa60a0ef
parent79c59f93b7461082cf4aec3025257560fc788c69 (diff)
downloadlibumumble-master.tar.gz
restructure include and fix makefiles HEAD master
* restructed include/ to have a umumble folder
* fix the makefile to use the new include structure
* tests makefile now builds inside root build folder
* added TODO list for shit I gotta do
* laid groundwork for packet parsing/packing: mumble_packet_gen_header
-rw-r--r--.gitignore1
-rw-r--r--Makefile8
-rw-r--r--TODO3
-rw-r--r--config.mk1
-rw-r--r--include/umumble/constants.h78
-rw-r--r--include/umumble/umumble.h (renamed from include/libumumble.h)20
-rw-r--r--src/connection.c14
-rw-r--r--src/ctx.c4
-rw-r--r--src/message.c15
-rw-r--r--src/proto/MumbleTCP.proto (renamed from src/Mumble.proto)2
-rw-r--r--src/proto/MumbleUDP.proto85
-rw-r--r--tests/Makefile3
-rw-r--r--tests/test.c2
13 files changed, 206 insertions, 30 deletions
diff --git a/.gitignore b/.gitignore
index 76adb92..a6fe2e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 build/
-tests/build/
 *.a
 *.so
 *.pb.c
diff --git a/Makefile b/Makefile
index 0e60318..fc0e340 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,7 @@ SRC += $(NANOPB_DIR)/pb_common.c
 PROTO = $(shell find src/ -type f -name '*.proto')
 OBJ = $(PROTO:%.proto=$(BUILD_DIR)/%.pb.c.o)
 OBJ += $(SRC:%=$(BUILD_DIR)/%.o)
-H = include/libumumble.h
+INCLUDE = $(shell find include/)
 
 .PHONY: all static shared tests clean install-static install-shared install
 
@@ -31,16 +31,16 @@ $(BUILD_DIR)/%.c.o: %.c
 	mkdir -p '$(@D)'
 	$(CC) -c -o $@ $(INCLUDES) $(CFLAGS) $<
 
-tests:
+tests: $(SNAME)
 	$(MAKE) -C tests
 
 clean:
 	rm -rf $(SNAME) $(DNAME) $(BUILD_DIR) src/*.pb.h src/*.pb.c
 	$(MAKE) -C tests clean
 
-install-header: $(H)
+install-header: $(INCLUDE)
 	install -d $(DESTDIR)$(INCLUDEDIR)
-	install -m 644 $^ $(DESTDIR)$(INCLUDEDIR)
+	cp -Rv include/. $(DESTDIR)$(INCLUDEDIR)
 
 install-static: $(SNAME)
 	install -d $(DESTDIR)$(LIBDIR)
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..3120da8
--- /dev/null
+++ b/TODO
@@ -0,0 +1,3 @@
+- Implement packet creation/send/recv
+- Implement callbacks
+- Implement SRV record lookup
diff --git a/config.mk b/config.mk
index 8a70d53..2525823 100644
--- a/config.mk
+++ b/config.mk
@@ -5,6 +5,7 @@ INCLUDEDIR = $(PREFIX)/include
 LIBDIR = $(PREFIX)/lib
 
 BUILD_DIR = build
+BUILD_DIR_TESTS = ../build/tests
 NAME = libumumble
 SNAME = $(NAME).a
 DNAME = $(NAME).so
diff --git a/include/umumble/constants.h b/include/umumble/constants.h
new file mode 100644
index 0000000..5dfded4
--- /dev/null
+++ b/include/umumble/constants.h
@@ -0,0 +1,78 @@
+#ifndef UMUMBLE_CONSTANTS_H
+#define UMUMBLE_CONSTANTS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+enum mumble_tcp_packet_type {
+	MUMBLE_TCP_PACKET_Version,
+	MUMBLE_TCP_PACKET_UDPTunnel,
+	MUMBLE_TCP_PACKET_Authenticate,
+	MUMBLE_TCP_PACKET_Ping,
+	MUMBLE_TCP_PACKET_Reject,
+	MUMBLE_TCP_PACKET_ServerSync,
+	MUMBLE_TCP_PACKET_ChannelRemove,
+	MUMBLE_TCP_PACKET_ChannelState,
+	MUMBLE_TCP_PACKET_UserRemove,
+	MUMBLE_TCP_PACKET_UserState,
+	MUMBLE_TCP_PACKET_BanList,
+	MUMBLE_TCP_PACKET_TextMessage,
+	MUMBLE_TCP_PACKET_PermissionDenied,
+	MUMBLE_TCP_PACKET_ACL,
+	MUMBLE_TCP_PACKET_QueryUsers,
+	MUMBLE_TCP_PACKET_CryptSetup,
+	MUMBLE_TCP_PACKET_ContextActionModify,
+	MUMBLE_TCP_PACKET_ContextAction,
+	MUMBLE_TCP_PACKET_UserList,
+	MUMBLE_TCP_PACKET_VoiceTarget,
+	MUMBLE_TCP_PACKET_PermissionQuery,
+	MUMBLE_TCP_PACKET_CodecVersion,
+	MUMBLE_TCP_PACKET_UserStats,
+	MUMBLE_TCP_PACKET_RequestBlob,
+	MUMBLE_TCP_PACKET_ServerConfig,
+	MUMBLE_TCP_PACKET_SuggestConfig,
+	MUMBLE_TCP_PACKET_PluginDataTransmission,
+};
+
+enum mumble_udp_packet_type {
+	MUMBLE_UDP_PACKET_Audio,
+	MUMBLE_UDP_PACKET_Ping
+};
+
+enum mumble_acl {
+	MUMBLE_ACL_None			= 0,
+	MUMBLE_ACL_Write		= 1,
+	MUMBLE_ACL_Traverse		= 1 << 1,
+	MUMBLE_ACL_Enter		= 1 << 2,
+	MUMBLE_ACL_Speak		= 1 << 3,
+	MUMBLE_ACL_MuteDeafen		= 1 << 4,
+	MUMBLE_ACL_Move			= 1 << 5,
+	MUMBLE_ACL_MakeChannel		= 1 << 6,
+	MUMBLE_ACL_LinkChannel		= 1 << 7,
+	MUMBLE_ACL_Whisper		= 1 << 8,
+	MUMBLE_ACL_TextMessage		= 1 << 9,
+	MUMBLE_ACL_MakeTempChannel	= 1 << 10,
+	MUMBLE_ACL_Listen		= 1 << 11,
+
+	// Root channel only
+	MUMBLE_ACL_Kick             = 1 << 16,
+	MUMBLE_ACL_Ban              = 1 << 17,
+	MUMBLE_ACL_Register         = 1 << 18,
+	MUMBLE_ACL_SelfRegister     = 1 << 19,
+	MUMBLE_ACL_ResetUserContent = 1 << 20
+};
+
+enum mumble_ctx_status {
+	MUMBLE_STATUS_UNINITIALIZED = 0,
+	MUMBLE_STATUS_READY,
+	MUMBLE_STATUS_CONNECTING,
+	MUMBLE_STATUS_CONNECTED,
+	MUMBLE_STATUS_DISCONNECTED
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* UMUMBLE_CONSTANTS_H */
diff --git a/include/libumumble.h b/include/umumble/umumble.h
index 43ba3ec..755be59 100644
--- a/include/libumumble.h
+++ b/include/umumble/umumble.h
@@ -1,23 +1,17 @@
-#ifndef LIBUMUMBLE_H
-#define LIBUMUMBLE_H
+#ifndef UMUMBLE_UMUMBLE_H
+#define UMUMBLE_UMUMBLE_H
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
+#include "constants.h"
+
 #include <uv.h>
 #include <tlsuv/tlsuv.h>
 
-enum mumble_ctx_status {
-	UNINITIALIZED = 0,
-	READY,
-	CONNECTING,
-	CONNECTED,
-	DISCONNECTED
-};
-
-typedef struct mumble_ctx {
-	enum mumble_ctx_status status;
+typedef struct mumble_ctx_s {
+	int status;
 	int error;
 	uv_loop_t uv_loop;
 	uv_getaddrinfo_t uv_resolver;
@@ -52,4 +46,4 @@ int mumble_run(mumble_ctx_t *ctx);
 }
 #endif /* __cplusplus */
 
-#endif /* LIBUMUMBLE_H */
+#endif /* UMUMBLE_UMUMBLE_H */
diff --git a/src/connection.c b/src/connection.c
index c484163..2c2bfbd 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -1,10 +1,10 @@
 #include <stdlib.h>
 #include <assert.h>
+#include <string.h>
 
-#include <libumumble.h>
+#include <umumble/umumble.h>
 #include <tlsuv/tlsuv.h>
 #include <uv.h>
-#include "Mumble.pb.h"
 
 void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) {
 	buf->base = malloc(suggested_size);
@@ -37,10 +37,10 @@ void on_read_cb(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf)
 	if (nread < 0) {
 		if (nread != UV_EOF) {
 			ctx->error = nread;
-			ctx->status = DISCONNECTED;
+			ctx->status = MUMBLE_STATUS_DISCONNECTED;
 		}
 		tlsuv_stream_close((tlsuv_stream_t *) client, on_close_cb);
-		ctx->status = DISCONNECTED;
+		ctx->status = MUMBLE_STATUS_DISCONNECTED;
 		free(buf->base);
 		free(client);
 		return;
@@ -62,11 +62,11 @@ void on_connect_cb(uv_connect_t *req, int status)
 
 	if (status < 0) {
 		ctx->error = status;
-		ctx->status = DISCONNECTED;
+		ctx->status = MUMBLE_STATUS_DISCONNECTED;
 		tlsuv_stream_close((tlsuv_stream_t *) req->handle, on_close_cb);
 		return;
 	}
-	ctx->status = CONNECTED;
+	ctx->status = MUMBLE_STATUS_CONNECTED;
 
 	tlsuv_stream_read(tls_stream, alloc_buffer, on_read_cb);
 
@@ -89,7 +89,7 @@ void on_resolve_cb(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res)
 	assert(status >= 0);
 	if (status < 0) {
 		ctx->error = status;
-		ctx->status = DISCONNECTED;
+		ctx->status = MUMBLE_STATUS_DISCONNECTED;
 		return;
 	}
 
diff --git a/src/ctx.c b/src/ctx.c
index 35864d1..2612ffb 100644
--- a/src/ctx.c
+++ b/src/ctx.c
@@ -1,7 +1,7 @@
 #include <assert.h>
 #include <string.h>
 
-#include <libumumble.h>
+#include <umumble/umumble.h>
 #include <uv.h>
 
 int mumble_ctx_init(mumble_ctx_t *ctx)
@@ -19,7 +19,7 @@ int mumble_ctx_init(mumble_ctx_t *ctx)
 	ctx->uv_connect_req.data = ctx;
 	ctx->uv_tcp_socket.data = ctx;
 
-	ctx->status = READY;
+	ctx->status = MUMBLE_STATUS_READY;
 	return 0;
 }
 
diff --git a/src/message.c b/src/message.c
new file mode 100644
index 0000000..8c066c2
--- /dev/null
+++ b/src/message.c
@@ -0,0 +1,15 @@
+#include <stdint.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+static void mumble_packet_gen_header(uint8_t *buf, uint16_t type, uint32_t len)
+{
+	uint16_t type_be;
+	uint32_t len_be;
+
+	type_be = htons(type);
+	len_be = htonl(len);
+
+	memcpy(buf, &type_be, 2);
+	memcpy(buf+2, &len_be, 4);
+}
diff --git a/src/Mumble.proto b/src/proto/MumbleTCP.proto
index c3a23f2..4a86e10 100644
--- a/src/Mumble.proto
+++ b/src/proto/MumbleTCP.proto
@@ -5,7 +5,7 @@
 
 syntax = "proto2";
 
-package MumbleProto;
+package MumbleTCP;
 
 option optimize_for = SPEED;
 
diff --git a/src/proto/MumbleUDP.proto b/src/proto/MumbleUDP.proto
new file mode 100644
index 0000000..4f27390
--- /dev/null
+++ b/src/proto/MumbleUDP.proto
@@ -0,0 +1,85 @@
+// Copyright 2022 The Mumble Developers. All rights reserved.
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file at the root of the
+// Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+syntax = "proto3";
+
+package MumbleUDP;
+
+option optimize_for = SPEED;
+
+message Audio {
+	oneof Header {
+		// When this audio is sent by the client to the server, this is set to the target of the audio data. This target
+		// is a number in the range [0, 2^{32} - 1], where 0 means "normal talking", 2^{5} - 1 means "server loopback"
+		// and all other targets are understood as shout/whisper targets that have previously been registered via a
+		// VoiceTarget message (via TCP).
+		uint32 target  = 1;
+		// When this audio is sent by the server to the client, this indicates the context in which the audio has been sent.
+		// 0: Normal speech
+		// 1: Shout to channel
+		// 2: Whisper to user
+		// 3: Received via channel listener
+		uint32 context = 2;
+	};
+
+	// The session of the client (sender) this audio was originally sent from. This field is not required when sending
+	// audio to the server, but will always be set when receiving audio from the server.
+	uint32 sender_session = 3;
+
+	// The number of the first contained audio frame (indicating the position of that frame in the overall audio stream)
+	uint64 frame_number = 4;
+
+	// The actual voice data payload in the Opus format.
+	bytes opus_data = 5;
+
+	// Optional positional data indicating the speaker's position in a virtual world (in meters). This "list" is really
+	// expected to be an array of size 3 containing the X, Y and Z coordinates of the position (in that order).
+	repeated float positional_data = 6;
+
+	// A volume adjustment determined by the server for this audio packet. It is up to the client to apply this adjustment to
+	// the resulting audio (or not). Note: A value of 0 means that this field is unset.
+	float volume_adjustment = 7;
+
+	// Note that we skip the field indices up to (including) 15 in order to have them available for future extensions of the
+	// protocol with fields that are encountered very often. The reason is that all field indices <= 15 require only a single
+	// byte of encoding overhead, whereas the once > 15 require (at least) two bytes. The reason lies in the Protobuf encoding
+	// scheme that uses 1 bit for a varint continuation flag, 3 bit to encode a field's type and the remaining 4 bit of the
+	// first byte are thus available for the field index. Therefore the first 2^4 = 16 field indices (aka values 0 to 15) can
+	// be encoded using only a single byte. For details see https://developers.google.com/protocol-buffers/docs/encoding
+
+	// A flag indicating whether this audio packet represents the end of transmission for the current audio stream
+	bool is_terminator = 16;
+}
+
+/**
+ * Ping message for checking UDP connectivity (and roundtrip ping) and potentially obtaining further server
+ * details (e.g. version).
+ */
+message Ping {
+	// Timestamp as encoded by the client. A server is not supposed to attempt to decode or modify this field. Therefore,
+	// clients may choose an arbitrary format for this timestamp (as long as it fits into a uint64 field).
+	uint64 timestamp = 1;
+
+	// A flag set by the sending client, if it wants to obtain additional information about the server.
+	bool request_extended_information = 2;
+
+
+	// Below are the fields for the "additional information" that are filled out by the server on request.
+
+	// The version of the server in the new version format.
+	// The new protobuf Ping packet introduced with 1.5 drops support for the legacy version format
+	// since both server and client have to support this new format.
+	// (See https://github.com/mumble-voip/mumble/issues/5827)
+	uint64 server_version_v2 = 3;
+
+	// The amount of users currently connected to the server
+	uint32 user_count = 4;
+
+	// The maximum amount of users permitted on this server
+	uint32 max_user_count = 5;
+
+	// The maximum bandwidth each user is allowed to use for sending audio to the server
+	uint32 max_bandwidth_per_user = 6;
+}
diff --git a/tests/Makefile b/tests/Makefile
index 95a146b..b6ee873 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,4 +1,5 @@
 include ../config.mk
+BUILD_DIR = $(BUILD_DIR_TESTS)
 INCLUDES = -I../include
 
 SRC = $(shell find -type f -name '*.c')
@@ -7,7 +8,7 @@ BIN = $(SRC:%.c=%)
 LDLIBS := -l:libumumble.a $(LDLIBS)
 LDFLAGS += -L..
 
-.PHONY: all
+.PHONY: all clean
 
 all: $(BIN)
 
diff --git a/tests/test.c b/tests/test.c
index 1c673a0..848ec38 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -1,4 +1,4 @@
-#include <libumumble.h>
+#include <umumble/umumble.h>
 
 int main(int argc, char *argv[])
 {