ソースを参照

add main loop to accept connections and write out wave files

Helmut Pozimski 4 年 前
コミット
a604ea7007
2 ファイル変更125 行追加4 行削除
  1. 4 4
      Makefile
  2. 121 0
      src/main.c

+ 4 - 4
Makefile

@@ -1,11 +1,11 @@
 CC ?= gcc
-CFLAGS ::= $(CFLAGS) -std=c99 -Wall -pedantic
-DEPS = src/wavfile.h
+CFLAGS ::= $(CFLAGS) -std=c99 -O2 -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wall -pedantic
+DEPS = src/wavfile.h src/tcpserver.h
 
 build/%.o: src/%.c $(DEPS)
 	$(CC) -c -o $@ $< $(CFLAGS)
-all: build/wavfile.o build/test.o
-	$(CC) -o build/test build/wavfile.o build/test.o
+all: build/wavfile.o build/main.o build/tcpserver.o
+	$(CC) -o build/test build/wavfile.o build/main.o build/tcpserver.o
 
 .PHONY: clean
 clean:

+ 121 - 0
src/main.c

@@ -0,0 +1,121 @@
+/*
+ * SPDX-FileCopyrightText: 2019 Helmut Pozimski <helmut@pozimski.eu>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <time.h>
+
+#include "tcpserver.h"
+#include "wavfile.h"
+
+#define BUF_SIZE 1558
+
+typedef struct {
+	uint32_t sample_rate;
+	uint32_t bits;
+} sync_information;
+
+/*
+ * Function: construct_file_path
+ * ----------------------------------------
+ *     Constructs the file path to write a new file to
+ * 
+ * directory: directory in which the file should be placed
+ * file_path: pointer to the buffer to write the file path to
+ */
+static void construct_file_path(char * directory, char * file_path) {
+	time_t cur_time;
+	struct tm local_time;
+	char timebuffer[12];
+    	cur_time = time(NULL);
+	local_time = (*localtime(&cur_time));
+	strncpy(file_path, "", 1);
+	strncat(file_path, directory, 255);
+	strncat(file_path, "/", 2);
+	sprintf(timebuffer, "%d", local_time.tm_year +1900);
+	strncat(file_path, timebuffer, 12);
+	sprintf(timebuffer, "%d", local_time.tm_mon +1);
+	strncat(file_path, timebuffer, 12);
+	sprintf(timebuffer, "%d", local_time.tm_mday);
+	strncat(file_path, timebuffer, 12);
+	sprintf(timebuffer, "%d", local_time.tm_hour);
+	strncat(file_path, timebuffer, 12);
+	sprintf(timebuffer, "%d", local_time.tm_min);
+	strncat(file_path, timebuffer, 12);
+	sprintf(timebuffer, "%d", local_time.tm_sec);
+	strncat(file_path, timebuffer, 12);
+	strncat(file_path, "-recording.wav", 15);
+}
+
+
+int main(int argc, char **argv) {
+	char * ip_address = NULL;
+	char * directory = NULL;
+	uint16_t port = 0;
+	int opt, sock, conn, bytes_received;
+	struct sockaddr_in client;
+	unsigned int namelen;
+	sync_information sync;
+	uint8_t buffer[BUF_SIZE];
+	wavfile * file;
+	char * file_path;
+	while ((opt = getopt(argc, argv, "i:p:d:")) != -1) {
+		switch(opt) {
+			case 'i':
+				ip_address = optarg;
+				break;
+			case 'p':
+				port = strtoul(optarg, NULL, 10);
+				break;
+			case 'd':
+				directory = optarg;
+				break;
+		}
+	}
+	if (port == 0 || ip_address == NULL || directory == NULL) {
+		printf("Usage: %s -i IPV4_ADDRESS -p PORT -d DIRECTORY\n", argv[0]);
+		return EXIT_SUCCESS;
+	}
+	if ((sock = tcpserver_start(ip_address, port)) < 0 ) {
+		printf("Failed to start TCP server\n");
+		return EXIT_FAILURE;
+	}
+	file_path = malloc(strlen(directory) + 1 + 29);
+	if (file_path == NULL) {
+		printf("Error allocating memory for file path\n");
+		return EXIT_FAILURE;
+	}
+	namelen = sizeof(client);
+	while (1) {
+		conn = accept(sock, (struct sockaddr *)&client, &namelen);
+		if (conn == -1) {
+			continue;
+		}
+		recv(conn, &sync, sizeof(sync), 0);
+		if (sync.sample_rate < 8000 || sync.sample_rate > 48000) {
+			printf("Invalid sample rate received\n");
+			continue;
+		}
+		construct_file_path(directory, file_path);
+		printf("Current file path: %s\n", file_path);
+		file = wavfile_create(file_path, 1, sync.sample_rate, sync.bits);
+		if (file == NULL) {
+			printf("Error creating new file\n");
+			close(conn);
+			continue;
+		}
+		while ((bytes_received = recv(conn, buffer, BUF_SIZE, 0)) != 0) {
+			wavfile_append_data(file, buffer, bytes_received);		
+		}
+		wavfile_close(file);
+	}
+	return EXIT_SUCCESS;
+}