Skip to content

Commit

Permalink
Redo
Browse files Browse the repository at this point in the history
  • Loading branch information
dsp committed Mar 24, 2011
1 parent 2c312a8 commit 9f36689
Showing 1 changed file with 127 additions and 50 deletions.
177 changes: 127 additions & 50 deletions debugsrv.c
@@ -1,3 +1,5 @@
#define _GNU_SOURCE

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
Expand All @@ -7,6 +9,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>

#include <avahi-client/client.h>
#include <avahi-client/publish.h>
Expand All @@ -16,7 +19,8 @@

#define NAME "moodlamp"
#define SERVICE "_moodlamp._udp"
#define PORT 2323
#define UDP_PORT 2323
#define TCP_PORT 2324

AvahiEntryGroup *group = NULL;
AvahiSimplePoll *sp = NULL;
Expand Down Expand Up @@ -61,7 +65,7 @@ void entry_group_callback(AvahiEntryGroup * g, AvahiEntryGroupState state,
}

static
void create_service(AvahiClient * c)
void create_service(AvahiClient * c, const char * service, int port)
{
int ret;

Expand All @@ -77,9 +81,9 @@ void create_service(AvahiClient * c)
if (avahi_entry_group_is_empty(group)) {
/* Add the service for IPP */
if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC,
AVAHI_PROTO_INET6, 0,
name, SERVICE,
NULL, NULL, PORT,
AVAHI_PROTO_UNSPEC, 0,
name, service,
NULL, NULL, port,
NULL)) < 0) {

if (ret == AVAHI_ERR_COLLISION) {
Expand Down Expand Up @@ -109,7 +113,8 @@ void client_callback(AvahiClient * c, AvahiClientState s, void *userdata)
{
switch (s) {
case AVAHI_CLIENT_S_RUNNING:
create_service(c);
create_service(c, "_moodlamp._udp", UDP_PORT);
create_service(c, "_moodlamp._tcp", TCP_PORT);
break;
case AVAHI_CLIENT_FAILURE:
avahi_simple_poll_quit(sp);
Expand All @@ -134,69 +139,141 @@ static void fade(int b1, int b2, int b3, unsigned long ms)
fprintf(stderr, "fade to %02x %02x %02x in %ldms\n", b1, b2, b3, ms);
}

static int serv(void)
static void exec_command(char *command, ssize_t len, void *retbuf,
ssize_t *retlen)
{
unsigned short *numbs;

numbs = alloca(sizeof(unsigned short) * len);
memset(numbs, 0, len);
for (int i = 0; i < len && command[i] != '0'; i++) {
numbs[i] = command[i] & 0xFF;
}


if (numbs[0] == 'B') {
for (int i = 0; i < len-2; i++) {
numbs[i] = numbs[i+2];
}
}

switch (numbs[0]) {
case 'C':
set(numbs[1], numbs[2], numbs[3]);
break;
case 'F':
case 'M':
case 'T':
if (len >= 6) {
unsigned int time = 0;
time = numbs[4] << 8;
time += numbs[5] && 0xFF;
fade(numbs[1], numbs[2], numbs[3], time);
} else {
fprintf(stderr, "not a ASCII moodlamp command");
}
break;
case 'V':
break;
default:
fprintf(stderr, "not a ASCII moodlamp command\n");
}
}

static void handle_tcp(int sock) {
char command[6];
void * retbuf = NULL;
ssize_t retlen, s;
struct sockaddr_in6 caddr;
socklen_t caddrlen;

int fd = accept(sock, &caddr, &caddrlen);
if ((s = read(fd, command, 6)) < 0) {
fprintf(stderr, "not a ASCII moodlamp command\n");
return;
}

exec_command(command, strlen(command), retbuf, &retlen);
write(fd, command, retlen);
close(fd);
}

static void handle_udp(int sock)
{
int sock;
struct sockaddr_in6 addr;
size_t s;
char command[6];
struct sockaddr_in6 caddr;
socklen_t caddrlen;

sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (sock < 0) {
fprintf(stderr, "cannot create socket");
if ((s = recvfrom
(sock, command, 6, 0, (struct sockaddr *) &caddr,
&caddrlen)) < 4) {
fprintf(stderr, "not a ASCII moodlamp command");
return;
}
exec_command(command, s, NULL, NULL);
}

static int serv(void)
{
struct pollfd fds[2];
int udp_sock, tcp_sock;
struct sockaddr_in6 tcp_addr;
struct sockaddr_in6 udp_addr;

udp_sock = socket(AF_INET6, SOCK_DGRAM, 0);
tcp_sock = socket(AF_INET6, SOCK_STREAM, 0);

if (udp_sock < 0) {
fprintf(stderr, "cannot create udp socket");
return -1;
}

if (tcp_sock < 0) {
fprintf(stderr, "cannot create udp socket");
return -1;
}

memset(&addr, 0, sizeof(addr));
addr.sin6_port = htons(PORT);
addr.sin6_addr = in6addr_any;
memset(&udp_addr, 0, sizeof(udp_addr));
udp_addr.sin6_port = htons(UDP_PORT);
udp_addr.sin6_addr = in6addr_any;

memset(&tcp_addr, 0, sizeof(tcp_addr));
tcp_addr.sin6_port = htons(TCP_PORT);
tcp_addr.sin6_addr = in6addr_any;

if (bind(sock, (struct sockaddr *) &addr, sizeof(addr))) {
fprintf(stderr, "cannot bind");
if (bind(udp_sock, (struct sockaddr *) &udp_addr, sizeof(udp_addr))) {
fprintf(stderr, "cannot bind udp socket");
return -1;
}

while (1) {
char command[6];
int numbs[6];
ssize_t s;
if (bind(tcp_sock, (struct sockaddr *) &tcp_addr, sizeof(tcp_addr))) {
fprintf(stderr, "cannot bind tcp socket");
return -1;
}

memset(&command, 0, sizeof(command));
if ((s = recvfrom
(sock, &command, 6, 0, (struct sockaddr *) &caddr,
&caddrlen)) < 4) {
fds[0].fd = udp_sock;
fds[1].fd = tcp_sock;
fds[0].events = POLLIN | POLLPRI;
fds[1].events = POLLIN | POLLPRI;
fds[0].revents = 0;
fds[1].revents = 0;

fprintf(stderr, "not a ASCII moodlamp command");
listen(tcp_sock, 10);
while (1) {
if (poll(fds, 2, 1000) <= 0) {
continue;
}

for (int i = 0; i < 6; i++) {
numbs[i] = command[i] & 0xFF;
}

/* RECEIVED PACKET, LET'S SEE WHAT WE'VE GOT */
switch (command[0]) {
case 'C':
set(numbs[1], numbs[2], numbs[3]);
break;
case 'F':
case 'M':
case 'T':
if (s >= 6) {
unsigned long time = 0;
time = command[4] << 8;
time += command[5] && 0xFF;
fade(numbs[1], numbs[2], numbs[3], time);
} else {
fprintf(stderr, "not a ASCII moodlamp command");
fprintf(stderr, "socket ready\n");
for (int sockn = 0; sockn < 2; sockn++) {
if (fds[sockn].revents && fds[sockn].fd == tcp_sock) {
handle_tcp(tcp_sock);
} else if (fds[sockn].revents && fds[sockn].fd == udp_sock) {
handle_udp(udp_sock);
}
break;
default:
fprintf(stderr, "not a ASCII moodlamp command");
}
}

close(sock);
}

int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[])
Expand Down

0 comments on commit 9f36689

Please sign in to comment.