mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-07-30 16:29:15 +02:00
ipc test for fm95
This commit is contained in:
+4
-4
@@ -44,13 +44,13 @@ foreach(SRC_FILE ${SRC_FILES})
|
|||||||
target_compile_options(${EXEC_NAME} PRIVATE -O2 -Wall -Wextra -Werror -Wno-unused-parameter)
|
target_compile_options(${EXEC_NAME} PRIVATE -O2 -Wall -Wextra -Werror -Wno-unused-parameter)
|
||||||
|
|
||||||
if(EXEC_NAME STREQUAL "fm95")
|
if(EXEC_NAME STREQUAL "fm95")
|
||||||
target_link_libraries(${EXEC_NAME} PRIVATE libfmfilter libfmmodulation libfmdsp libfmio pulse pulse-simple m liquid inih)
|
target_link_libraries(${EXEC_NAME} PRIVATE libfmfilter libfmmodulation libfmdsp libfmio pulse pulse-simple m liquid inih pthread)
|
||||||
elseif(EXEC_NAME STREQUAL "chimer95")
|
elseif(EXEC_NAME STREQUAL "chimer95")
|
||||||
target_link_libraries(${EXEC_NAME} PRIVATE libfmdsp inih m libfmio pulse pulse-simple liquid)
|
target_link_libraries(${EXEC_NAME} PRIVATE libfmdsp inih m libfmio pulse pulse-simple liquid pthread)
|
||||||
elseif(EXEC_NAME STREQUAL "sca95")
|
elseif(EXEC_NAME STREQUAL "sca95")
|
||||||
target_link_libraries(${EXEC_NAME} PRIVATE libfmmodulation inih m libfmio pulse pulse-simple libfmdsp liquid)
|
target_link_libraries(${EXEC_NAME} PRIVATE libfmmodulation inih m libfmio pulse pulse-simple libfmdsp liquid pthread)
|
||||||
elseif(EXEC_NAME STREQUAL "vban95")
|
elseif(EXEC_NAME STREQUAL "vban95")
|
||||||
target_link_libraries(${EXEC_NAME} PRIVATE libfmio pulse pulse-simple liquid)
|
target_link_libraries(${EXEC_NAME} PRIVATE libfmio pulse pulse-simple liquid pthread)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "How do I link this? ${EXEC_NAME}")
|
message(FATAL_ERROR "How do I link this? ${EXEC_NAME}")
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#include "ipc.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
|
static int make_server_socket(const char *path)
|
||||||
|
{
|
||||||
|
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) { perror("ipc: socket"); return -1; }
|
||||||
|
|
||||||
|
unlink(path);
|
||||||
|
|
||||||
|
struct sockaddr_un addr = { .sun_family = AF_UNIX };
|
||||||
|
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
|
||||||
|
|
||||||
|
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
|
perror("ipc: bind"); close(fd); return -1;
|
||||||
|
}
|
||||||
|
if (listen(fd, IPC_BACKLOG) < 0) {
|
||||||
|
perror("ipc: listen"); close(fd); return -1;
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *listener_thread(void *arg) {
|
||||||
|
ipc_ctx_t *ctx = (ipc_ctx_t *)arg;
|
||||||
|
|
||||||
|
while (ctx->running) {
|
||||||
|
struct sockaddr_un peer;
|
||||||
|
socklen_t peer_len = sizeof(peer);
|
||||||
|
|
||||||
|
int client_fd = accept(ctx->server_fd,
|
||||||
|
(struct sockaddr *)&peer, &peer_len);
|
||||||
|
if (client_fd < 0) {
|
||||||
|
if (errno == EINVAL || errno == EBADF) break; /* shutting down */
|
||||||
|
if (errno == EINTR) continue;
|
||||||
|
perror("ipc: accept");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[ipc] new client fd=%d\n", client_fd);
|
||||||
|
|
||||||
|
int *fd_ptr = malloc(sizeof(int));
|
||||||
|
if (!fd_ptr) { close(client_fd); continue; }
|
||||||
|
*fd_ptr = client_fd;
|
||||||
|
|
||||||
|
pthread_t tid;
|
||||||
|
if (pthread_create(&tid, NULL, ctx->handler, fd_ptr) != 0) {
|
||||||
|
perror("ipc: pthread_create");
|
||||||
|
free(fd_ptr);
|
||||||
|
close(client_fd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pthread_detach(tid);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[ipc] listener exiting\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_ipc(ipc_ctx_t *ctx, ipc_client_fn handler, const char* socket_path) {
|
||||||
|
ctx->handler = handler;
|
||||||
|
ctx->running = 1;
|
||||||
|
ctx->server_fd = make_server_socket(socket_path);
|
||||||
|
ctx->socket_path = strdup(socket_path);
|
||||||
|
if (ctx->server_fd < 0) return -1;
|
||||||
|
|
||||||
|
pthread_t tid;
|
||||||
|
if (pthread_create(&tid, NULL, listener_thread, ctx) != 0) {
|
||||||
|
perror("ipc: pthread_create");
|
||||||
|
close(ctx->server_fd);
|
||||||
|
unlink(socket_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store tid so destroy_ipc can join it */
|
||||||
|
ctx->_tid = tid;
|
||||||
|
|
||||||
|
printf("[ipc] listening on %s\n", socket_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_ipc(ipc_ctx_t *ctx) {
|
||||||
|
ctx->running = 0;
|
||||||
|
shutdown(ctx->server_fd, SHUT_RDWR); /* unblock accept() */
|
||||||
|
close(ctx->server_fd);
|
||||||
|
unlink(ctx->socket_path);
|
||||||
|
pthread_join(ctx->_tid, NULL);
|
||||||
|
printf("[ipc] shut down\n");
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define IPC_SOCKET_PATH "/tmp/ipc_demo.sock"
|
||||||
|
#define IPC_BACKLOG 1
|
||||||
|
|
||||||
|
typedef void *(*ipc_client_fn)(void *client_fd_ptr);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int server_fd;
|
||||||
|
volatile int running;
|
||||||
|
ipc_client_fn handler;
|
||||||
|
pthread_t _tid; /* internal — do not touch */
|
||||||
|
const char* socket_path;
|
||||||
|
} ipc_ctx_t;
|
||||||
|
int create_ipc(ipc_ctx_t *ctx, ipc_client_fn handler, const char* socket_path);
|
||||||
|
void destroy_ipc(ipc_ctx_t *ctx);
|
||||||
+31
@@ -17,6 +17,7 @@
|
|||||||
#define BUFFER_SIZE 4998 // This defines how many samples to process at a time, because the loop here is this: get signal -> process signal -> output signal, and when we get signal we actually get BUFFER_SIZE of them
|
#define BUFFER_SIZE 4998 // This defines how many samples to process at a time, because the loop here is this: get signal -> process signal -> output signal, and when we get signal we actually get BUFFER_SIZE of them
|
||||||
|
|
||||||
#include "../io/audio.h"
|
#include "../io/audio.h"
|
||||||
|
#include "../io/ipc.h"
|
||||||
|
|
||||||
static volatile sig_atomic_t to_run = 1;
|
static volatile sig_atomic_t to_run = 1;
|
||||||
static volatile sig_atomic_t to_reload = 0;
|
static volatile sig_atomic_t to_reload = 0;
|
||||||
@@ -456,9 +457,38 @@ void init_runtime(FM95_Runtime* runtime, const FM95_Config config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BUF_SIZE 256
|
||||||
|
static void *handle_client(void *arg) {
|
||||||
|
int fd = *(int *)arg;
|
||||||
|
free(arg);
|
||||||
|
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
ssize_t n;
|
||||||
|
|
||||||
|
while ((n = recv(fd, buf, sizeof(buf) - 1, 0)) > 0) {
|
||||||
|
buf[n] = '\0';
|
||||||
|
printf("[client fd=%d] %s\n", fd, buf);
|
||||||
|
|
||||||
|
char reply[BUF_SIZE];
|
||||||
|
snprintf(reply, sizeof(reply), "ECHO: %s", buf);
|
||||||
|
send(fd, reply, strlen(reply), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[client fd=%d] disconnected\n", fd);
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
printf("fm95 (an FM Processor by radio95) version 2.5\n");
|
printf("fm95 (an FM Processor by radio95) version 2.5\n");
|
||||||
|
|
||||||
|
ipc_ctx_t ctx = NULL;
|
||||||
|
if(create_ipc(&ctx, handle_client, "/etc/fm95/ctl.socket") < 0) {
|
||||||
|
printf("Could not create IPC.\n");
|
||||||
|
ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FM95_Config config = {
|
FM95_Config config = {
|
||||||
.volumes = {
|
.volumes = {
|
||||||
.pilot = 0.09f,
|
.pilot = 0.09f,
|
||||||
@@ -573,5 +603,6 @@ int main(int argc, char **argv) {
|
|||||||
cleanup_audio_runtime(&runtime, config.options);
|
cleanup_audio_runtime(&runtime, config.options);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if(ctx != NULL) destroy_ipc(&ctx);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user