#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <malloc.h>
#include <pthread.h>
#include <fcntl.h>
#include <errno.h>
#include <rtdm/ipc.h>
pthread_t rt1, rt2, nrt;
#define XDDP_PORT_LABEL "xddp-demo"
static const char *msg[] = {
"Surfing With The Alien",
"Lords of Karma",
"Banana Mango",
"Psycho Monkey",
"Luminous Flesh Giants",
"Moroccan Sunset",
"Satch Boogie",
"Flying In A Blue Dream",
"Ride",
"Summer Song",
"Speed Of Light",
"Crystal Planet",
"Raspberry Jam Delta-V",
"Champagne?",
"Clouds Race Across The Sky",
"Engines Of Creation"
};
static void fail(const char *reason)
{
perror(reason);
exit(EXIT_FAILURE);
}
static void *realtime_thread1(void *arg)
{
char buf[128];
int ret, s;
if (s < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
strcpy(plabel.
label, XDDP_PORT_LABEL);
&plabel, sizeof(plabel));
if (ret)
fail("setsockopt");
memset(&saddr, 0, sizeof(saddr));
ret = bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret)
fail("bind");
for (;;) {
ret = recvfrom(s, buf, sizeof(buf), 0, NULL, 0);
if (ret <= 0)
fail("recvfrom");
printf("%s: \"%.*s\" relayed by peer\n", __FUNCTION__, ret, buf);
}
return NULL;
}
static void *realtime_thread2(void *arg)
{
int ret, s, n = 0, len;
struct timespec ts;
struct timeval tv;
socklen_t addrlen;
if (s < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
tv.tv_sec = 1;
tv.tv_usec = 0;
&tv, sizeof(tv));
if (ret)
fail("setsockopt");
strcpy(plabel.
label, XDDP_PORT_LABEL);
&plabel, sizeof(plabel));
if (ret)
fail("setsockopt");
memset(&saddr, 0, sizeof(saddr));
ret = connect(s, (struct sockaddr *)&saddr, sizeof(saddr));
if (ret)
fail("connect");
addrlen = sizeof(saddr);
ret = getpeername(s, (struct sockaddr *)&saddr, &addrlen);
if (ret || addrlen != sizeof(saddr))
fail("getpeername");
printf("%s: NRT peer is reading from /dev/rtp%d\n",
__FUNCTION__, saddr.sipc_port);
for (;;) {
len = strlen(msg[n]);
ret = sendto(s, msg[n], len, 0, NULL, 0);
if (ret != len)
fail("sendto");
printf("%s: sent %d bytes, \"%.*s\"\n",
__FUNCTION__, ret, ret, msg[n]);
n = (n + 1) % (sizeof(msg) / sizeof(msg[0]));
ts.tv_sec = 0;
ts.tv_nsec = 500000000;
}
return NULL;
}
static void *regular_thread(void *arg)
{
char buf[128], *devname;
int fd, ret;
if (asprintf(&devname,
"/proc/xenomai/registry/rtipc/xddp/%s",
XDDP_PORT_LABEL) < 0)
fail("asprintf");
fd = open(devname, O_RDWR);
free(devname);
if (fd < 0)
fail("open");
for (;;) {
ret = read(fd, buf, sizeof(buf));
if (ret <= 0)
fail("read");
ret = write(fd, buf, ret);
if (ret <= 0)
fail("write");
}
return NULL;
}
int main(int argc, char **argv)
{
struct sched_param rtparam = { .sched_priority = 42 };
pthread_attr_t rtattr, regattr;
sigset_t set;
int sig;
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
sigaddset(&set, SIGHUP);
pthread_sigmask(SIG_BLOCK, &set, NULL);
pthread_attr_init(&rtattr);
pthread_attr_setdetachstate(&rtattr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(&rtattr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&rtattr, SCHED_FIFO);
pthread_attr_setschedparam(&rtattr, &rtparam);
if (errno)
fail("pthread_create");
if (errno)
fail("pthread_create");
pthread_attr_init(®attr);
pthread_attr_setdetachstate(®attr, PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(®attr, PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(®attr, SCHED_OTHER);
if (errno)
fail("pthread_create");
sigwait(&set, &sig);
pthread_cancel(rt1);
pthread_cancel(rt2);
pthread_cancel(nrt);
return 0;
}