linuxOS_AP06/app/lvgl_demo/rk_demo/rockit/audio_server.c
2025-06-03 12:28:32 +08:00

285 lines
5.7 KiB
C

#include <arpa/inet.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "audio_in.h"
#include "audio_out.h"
#include "audio_server.h"
#include "rk_defines.h"
#include "rk_debug.h"
#include "rk_mpi_sys.h"
struct audio_server
{
int fd;
int remote_client;
int state;
void *client;
pthread_t tid;
};
static int ao_read(void *arg, char *buf, int len)
{
struct audio_server *server = (struct audio_server *)arg;
int num = 0;
int _len = len;
if (!buf)
{
RK_LOGE("buf is NULL");
return 0;
}
while (_len && (server->state == STATE_RUNNING))
{
num = read(server->remote_client,
buf + (len - _len), _len);
if (num <= 0)
return 0;
_len -= num;
}
if (server->state != STATE_RUNNING)
return 0;
return len;
}
static int audio_server_init(void)
{
struct sockaddr_in saddr;
int fd;
int ret;
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
printf("new socket failed");
return fd;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons(9999);
ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret < 0)
{
printf("bind socket failed");
close(fd);
return ret;
}
return fd;
}
static void *audio_server(void *arg)
{
struct audio_server *server = (struct audio_server *)arg;
char clientIP[16];
unsigned short clientPort;
struct sockaddr_in clientaddr;
int len;
int cfd;
int ret;
server->state = STATE_RUNNING;
while (server->state == STATE_RUNNING)
{
printf("start listening...\n");
ret = listen(server->fd, 8);
if (ret == -1)
{
printf("listen error\n");
server->state = STATE_ERROR;
break;
}
len = sizeof(clientaddr);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
cfd = accept(server->fd, (struct sockaddr *)&clientaddr, &len);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (cfd == -1)
{
printf("accept error\n");
continue;
}
server->remote_client = cfd;
inet_ntop(AF_INET, &clientaddr.sin_addr.s_addr, clientIP, sizeof(clientIP));
clientPort = ntohs(clientaddr.sin_port);
printf("client ip is %s, port is %d\n", clientIP, clientPort);
if (audio_server_connect(server, clientIP) < 0)
{
printf("connect to %s error\n", clientIP);
goto ao_err;
}
ret = ao_init();
if (ret == -1)
{
printf("ao init error\n");
goto ao_err;
}
server->state = STATE_RUNNING;
while (server->state == STATE_RUNNING)
{
if (ao_push(ao_read, server) == -1)
{
printf("ao push failed\n");
break;
}
}
ao_deinit();
ao_err:
close(cfd);
if (server->client)
audio_client_del(server->client);
server->client = NULL;
server->remote_client = -1;
if (server->state == STATE_PAUSE)
server->state = STATE_RUNNING;
}
close(server->fd);
server->fd = -1;
if (server->state != STATE_ERROR)
server->state = STATE_IDLE;
printf("audio server exit\n");
return NULL;
}
int audio_server_state(void *arg)
{
struct audio_server *server = (struct audio_server *)arg;
if (!server || !server->client)
return STATE_IDLE;
return audio_client_state(server->client);
}
int audio_server_connect(void *arg, const char *ip)
{
struct audio_server *server = (struct audio_server *)arg;
if (!server)
{
printf("%s null ptr\n", __func__);
return -1;
}
if (server->client)
printf("server is connected\n");
else
server->client = audio_client_new(ip);
return 0;
}
int audio_server_connected(void *arg)
{
struct audio_server *server = (struct audio_server *)arg;
if (!server)
{
printf("%s null ptr\n", __func__);
return -1;
}
return server->client != NULL;
}
int audio_server_disconnect(void *arg)
{
struct audio_server *server = (struct audio_server *)arg;
if (!server)
{
printf("%s null ptr\n", __func__);
return -1;
}
if (server->state != STATE_RUNNING)
{
printf("%s wrong state %d\n", __func__, server->state);
return -1;
}
server->state = STATE_PAUSE;
}
int audio_server_del(void *arg)
{
struct audio_server *server = (struct audio_server *)arg;
if (!server || !server->tid)
{
printf("%s %p error\n", __func__, server);
return -1;
}
server->state = STATE_EXIT;
pthread_cancel(server->tid);
pthread_join(server->tid, NULL);
if (server->fd != -1)
{
close(server->fd);
server->fd = -1;
}
free(server);
return 0;
}
void *audio_server_new(void)
{
struct audio_server *server;
pthread_t tid;
int fd;
int ret;
server = calloc(1, sizeof(*server));
if (!server)
{
printf("audio server calloc failed %d\n", sizeof(*server));
return NULL;
}
fd = audio_server_init();
if (fd < 0)
{
printf("audio server init failed %d\n", fd);
ret = fd;
goto fd_err;
}
server->fd = fd;
ret = pthread_create(&server->tid, NULL, audio_server, server);
if (ret < 0)
{
printf("audio server start failed %d\n", ret);
goto t_err;
}
return server;
t_err:
close(fd);
fd_err:
free(server);
return NULL;
}