123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- /*
- * SPDX-FileCopyrightText: 2019 Helmut Pozimski <helmut@pozimski.eu>
- *
- * SPDX-License-Identifier: GPL-2.0-only
- */
- #include <signal.h>
- #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 <sys/time.h>
- #include <syslog.h>
- #include "tcpserver.h"
- #include "wavfile.h"
- #define BUF_SIZE 1558
- #define MAX_PATH_LEN 255
- typedef struct {
- uint32_t sample_rate;
- uint32_t bits;
- } sync_information;
- typedef struct {
- char ack[4];
- sync_information sync;
- } sync_ack;
- /* global variables */
- char filepath[MAX_PATH_LEN + 30];
- uint8_t file_closed = -1;
- wavfile * file;
- int sock;
- /*
- * Function: signal_handler
- * ------------------------
- * handles TERM and INT to ensure an orderly shutdown
- *
- * signal: the number of the signal sent
- */
- static void signal_handler(int signal) {
- syslog(LOG_INFO, "signal %d received, shutting down\n", signal);
- if (!file_closed) {
- wavfile_close(file);
- }
- tcpserver_stop(sock);
- exit(EXIT_SUCCESS);
- }
- /*
- * 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, bytes_received, conn;
- struct sockaddr_in client;
- unsigned int namelen;
- sync_information sync;
- uint8_t buffer[BUF_SIZE];
- sync_ack ack_packet;
- 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;
- }
- struct sigaction action;
- action.sa_handler = signal_handler;
- sigaction(SIGTERM, &action,NULL);
- sigaction(SIGINT, &action,NULL);
- openlog("tpr", LOG_CONS | LOG_PID, LOG_DAEMON);
- if ((sock = tcpserver_start(ip_address, port)) < 0 ) {
- syslog(LOG_ERR, "Failed to start TCP server\n");
- return EXIT_FAILURE;
- }
- namelen = sizeof(client);
- while (1) {
- conn = accept(sock, (struct sockaddr *)&client, &namelen);
- if (conn == -1) {
- continue;
- }
- struct timeval tv;
- tv.tv_sec = 3;
- tv.tv_usec = 0;
- setsockopt(conn, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
- recv(conn, &sync, sizeof(sync), 0);
- if (sync.sample_rate < 8000 || sync.sample_rate > 48000) {
- syslog(LOG_ERR, "Invalid sample rate received\n");
- continue;
- }
- construct_file_path(directory, filepath);
- syslog(LOG_INFO, "opening file at: %s\n", filepath);
- file = wavfile_create(filepath, 1, sync.sample_rate, sync.bits);
- file_closed = 0;
- strncpy(ack_packet.ack,"ACK", 4);
- if (file == NULL) {
- syslog(LOG_ERR, "Error creating new file\n");
- close(conn);
- continue;
- }
- ack_packet.sync = sync;
- send(conn, &ack_packet, sizeof(ack_packet), 0);
- while ((bytes_received = recv(conn, buffer, BUF_SIZE, 0)) != -1) {
- wavfile_append_data(file, buffer, bytes_received);
- }
- syslog(LOG_INFO, "closing file: %s\n", filepath);
- wavfile_close(file);
- close(conn);
- file_closed = 1;
- }
- return EXIT_SUCCESS;
- }
|