osd-contiki/apps/cmdd/cmdd.c
2006-06-17 23:01:48 +00:00

169 lines
3.7 KiB
C

#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
#include <string.h>
struct cmdd_state {
struct psock s;
char inputbuf[8];
struct timer timer;
int i;
char command;
};
#define COMMAND_NONE 0
#define COMMAND_PS 1
MEMB(conns, struct cmdd_state, 1);
PROCESS(cmdd_process, "Command server");
static struct uip_udp_conn *udpconn;
static char send_udp = 0;
static const char *prompt = "contiki> ";
/*---------------------------------------------------------------------------*/
static char * CC_FASTCALL
n(u16_t num, char *ptr)
{
u16_t d;
u8_t a, f;
if(num == 0) {
*ptr = '0';
return ptr + 1;
} else {
f = 0;
for(d = 10000; d >= 1; d /= 10) {
a = (num / d) % 10;
if(f == 1 || a > 0) {
*ptr = a + '0';
++ptr;
f = 1;
}
}
}
return ptr;
}
/*---------------------------------------------------------------------------*/
static unsigned short
ps_generate(void *state)
{
struct ek_proc *p = (struct ek_proc *)state;
char *ptr = (char *)uip_appdata;
ptr = n(EK_PROC_ID(p), ptr);
*ptr++ = ' ';
strncpy(ptr, p->name, 40);
ptr += strlen(p->name);
*ptr++ = '\n';
return ptr - (char *)uip_appdata;
}
/*---------------------------------------------------------------------------*/
static
PT_THREAD(handle_connection(struct cmdd_state *s))
{
PSOCK_BEGIN(&s->s);
while(1) {
PSOCK_SEND(&s->s, prompt, strlen(prompt));
PSOCK_WAIT_UNTIL(&s->s, PSOCK_NEWDATA(&s->s) ||
s->command != COMMAND_NONE);
if(PSOCK_NEWDATA(&s->s)) {
PSOCK_READTO(&s->s, '\n');
if(strncmp(s->inputbuf, "quit", 4) == 0) {
PSOCK_CLOSE_EXIT(&s->s);
memb_free(&conns, s);
tcp_markconn(uip_conn, NULL);
} else if(strncmp(s->inputbuf, "ps", 2) == 0) {
PSOCK_GENERATOR_SEND(&s->s, ps_generate, ek_procs);
for(s->i = 0; s->i < 40; s->i++) {
if(ek_process(s->i) != NULL) {
PSOCK_GENERATOR_SEND(&s->s, ps_generate, ek_process(s->i));
}
}
} else if(strncmp(s->inputbuf, "send", 4) == 0) {
send_udp = 1;
PSOCK_WAIT_UNTIL(&s->s, send_udp == 0);
} else {
PSOCK_SEND(&s->s, "?\n", 2);
}
} else {
switch(s->command) {
}
}
}
PSOCK_END(&s->s);
}
/*---------------------------------------------------------------------------*/
static void
appcall(void *state)
{
struct cmdd_state *s = (struct cmdd_state *)state;
if(uip_udpconnection()) {
if(send_udp) {
uip_udp_send(8);
send_udp = 0;
}
} else {
if(uip_closed() || uip_timedout() || uip_aborted()) {
if(state != NULL) {
memb_free(&conns, state);
}
} else if(uip_connected()) {
s = (struct cmdd_state *)memb_alloc(&conns);
if(s == NULL) {
uip_abort();
} else {
tcp_markconn(uip_conn, s);
PSOCK_INIT(&s->s, s->inputbuf, sizeof(s->inputbuf) - 1);
timer_set(&s->timer, CLOCK_SECOND * 60);
handle_connection(s);
}
} else if(s != NULL) {
if(uip_poll()) {
if(timer_expired(&s->timer)) {
memb_free(&conns, state);
uip_abort();
return;
}
}
timer_reset(&s->timer);
handle_connection(s);
} else {
uip_abort();
}
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(cmdd_process, ev, data)
{
u16_t ipaddr[2];
PROCESS_BEGIN();
tcp_listen(HTONS(6581));
memb_init(&conns);
uip_ipaddr(ipaddr, 255,255,255,255);
udpconn = udp_new(ipaddr, HTONS(6712), NULL);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
appcall(data);
} else if(ev == PROCESS_EVENT_EXIT) {
process_exit(&cmdd_process);
LOADER_UNLOAD();
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/