169 lines
3.7 KiB
C
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();
|
|
}
|
|
/*---------------------------------------------------------------------------*/
|