diff --git a/examples/slip-radio/slip-net.c b/examples/slip-radio/slip-net.c index e1efbf4cf..edf219106 100644 --- a/examples/slip-radio/slip-net.c +++ b/examples/slip-radio/slip-net.c @@ -64,7 +64,7 @@ slipnet_input(void) packetbuf_datalen(), i); for(i = 0; i < uip_len; i++) { - LOG_DBG("%02x", (unsigned char)uip_buf[i]); + LOG_DBG_("%02x", (unsigned char)uip_buf[i]); if((i & 15) == 15) { LOG_DBG_("\n"); } else if((i & 7) == 7) { diff --git a/examples/slip-radio/slip-radio.c b/examples/slip-radio/slip-radio.c index 53a0324bc..65f0bde43 100644 --- a/examples/slip-radio/slip-radio.c +++ b/examples/slip-radio/slip-radio.c @@ -166,6 +166,25 @@ slip_radio_cmd_handler(const uint8_t *data, int len) packet_pos = 0; } + return 1; + } else if(data[1] == 'V') { + int type = ((uint16_t)data[2] << 8) | data[3]; + int value = ((uint16_t)data[4] << 8) | data[5]; + int param = type; /* packetutils_to_radio_param(type); */ + if(param < 0) { + printf("radio: unknown parameter %d (can not set to %d)\n", type, value); + } else { + if(param == RADIO_PARAM_RX_MODE) { + printf("radio: setting rxmode to 0x%x\n", value); + } else if(param == RADIO_PARAM_PAN_ID) { + printf("radio: setting pan id to 0x%04x\n", value); + } else if(param == RADIO_PARAM_CHANNEL) { + printf("radio: setting channel: %u\n", value); + } else { + printf("radio: setting param %d to %d (0x%02x)\n", param, value, value); + } + NETSTACK_RADIO.set_value(param, value); + } return 1; } } else if(uip_buf[0] == '?') { @@ -180,6 +199,25 @@ slip_radio_cmd_handler(const uint8_t *data, int len) uip_len = 10; cmd_send(uip_buf, uip_len); return 1; + } else if(data[1] == 'V') { + /* ask the radio about the specific parameter and send it back... */ + int type = ((uint16_t)data[2] << 8) | data[3]; + int value; + int param = type; /* packetutils_to_radio_param(type); */ + if(param < 0) { + printf("radio: unknown parameter %d\n", type); + } + + NETSTACK_RADIO.get_value(param, &value); + + uip_buf[0] = '!'; + uip_buf[1] = 'V'; + uip_buf[2] = type >> 8; + uip_buf[3] = type & 0xff; + uip_buf[4] = value >> 8; + uip_buf[5] = value & 0xff; + uip_len = 6; + cmd_send(uip_buf, uip_len); } } return 0; diff --git a/os/net/mac/framer/nullframer.c b/os/net/mac/framer/nullframer.c index 3df8f6ea1..019ed2209 100644 --- a/os/net/mac/framer/nullframer.c +++ b/os/net/mac/framer/nullframer.c @@ -36,7 +36,27 @@ * Joakim Eriksson */ #include "net/mac/framer/framer.h" +#include "net/packetbuf.h" +#ifdef NULLFRAMER_CONF_PARSE_802154 +#define NULLFRAMER_PARSE_802154 NULLFRAMER_CONF_PARSE_802154 +#else +/* defaults to parsing of the 802154 header as that is used for Slip-Radio */ +#define NULLFRAMER_PARSE_802154 1 +#endif + +/*---------------------------------------------------------------------------*/ +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + return 1; +} /*---------------------------------------------------------------------------*/ static int hdr_length(void) @@ -55,6 +75,21 @@ create(void) static int parse(void) { +#if NULLFRAMER_PARSE_802154 + frame802154_t frame; + int len; + len = packetbuf_datalen(); + if(frame802154_parse(packetbuf_dataptr(), len, &frame)) { + if(frame.fcf.dest_addr_mode) { + if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) { + packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr); + } + } + packetbuf_set_addr(PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr); + packetbuf_set_attr(PACKETBUF_ATTR_MAC_SEQNO, frame.seq); + return 0; + } +#endif return 0; } /*---------------------------------------------------------------------------*/ diff --git a/os/services/rpl-border-router/native/Makefile.native b/os/services/rpl-border-router/native/Makefile.native index 62f7221a0..f4c2fb5b9 100644 --- a/os/services/rpl-border-router/native/Makefile.native +++ b/os/services/rpl-border-router/native/Makefile.native @@ -1,8 +1,10 @@ MODULES += os/services/slip-cmd +MODULES += os/services/shell MAKE_MAC = MAKE_MAC_OTHER MAKE_NET = MAKE_NET_IPV6 + PREFIX ?= fd00::1/64 connect-router: border-router.native sudo ./border-router.native $(PREFIX) diff --git a/os/services/rpl-border-router/native/border-router-cmds.c b/os/services/rpl-border-router/native/border-router-cmds.c index 75788a920..a32ac6dd6 100644 --- a/os/services/rpl-border-router/native/border-router-cmds.c +++ b/os/services/rpl-border-router/native/border-router-cmds.c @@ -43,6 +43,7 @@ #include "rpl.h" #include "net/ipv6/uiplib.h" #include +#include "shell.h" #define DEBUG DEBUG_NONE #include "net/ipv6/uip-debug.h" @@ -54,6 +55,56 @@ void nbr_print_stat(void); /*---------------------------------------------------------------------------*/ PROCESS(border_router_cmd_process, "Border router cmd process"); +/*---------------------------------------------------------------------------*/ +static const uint8_t * +hextoi(const uint8_t *buf, int len, int *v) +{ + *v = 0; + for(; len > 0; len--, buf++) { + if(*buf >= '0' && *buf <= '9') { + *v = (*v << 4) + ((*buf - '0') & 0xf); + } else if(*buf >= 'a' && *buf <= 'f') { + *v = (*v << 4) + ((*buf - 'a' + 10) & 0xf); + } else if(*buf >= 'A' && *buf <= 'F') { + *v = (*v << 4) + ((*buf - 'A' + 10) & 0xf); + } else { + break; + } + } + return buf; +} +/*---------------------------------------------------------------------------*/ +static const uint8_t * +dectoi(const uint8_t *buf, int len, int *v) +{ + int negative = 0; + *v = 0; + if(len <= 0) { + return buf; + } + if(*buf == '$') { + return hextoi(buf + 1, len - 1, v); + } + if(*buf == '0' && *(buf + 1) == 'x' && len > 2) { + return hextoi(buf + 2, len - 2, v); + } + if(*buf == '-') { + negative = 1; + buf++; + } + for(; len > 0; len--, buf++) { + if(*buf < '0' || *buf > '9') { + break; + } + *v = (*v * 10) + ((*buf - '0') & 0xf); + } + if(negative) { + *v = - *v; + } + return buf; +} +/*---------------------------------------------------------------------------*/ + /*---------------------------------------------------------------------------*/ /* TODO: the below code needs some way of identifying from where the command */ /* comes. In this case it can be from stdin or from SLIP. */ @@ -64,35 +115,64 @@ border_router_cmd_handler(const uint8_t *data, int len) /* handle global repair, etc here */ if(data[0] == '!') { PRINTF("Got configuration message of type %c\n", data[1]); - if(data[1] == 'G' && command_context == CMD_CONTEXT_STDIO) { - /* This is supposed to be from stdin */ - printf("Performing Global Repair...\n"); + if(command_context == CMD_CONTEXT_STDIO) { + switch(data[1]) { + case 'G': + /* This is supposed to be from stdin */ + printf("Performing Global Repair...\n"); #if UIP_CONF_IPV6_RPL_LITE - rpl_global_repair(); + rpl_global_repair(); #else - rpl_repair_root(RPL_DEFAULT_INSTANCE); + rpl_repair_root(RPL_DEFAULT_INSTANCE); #endif - return 1; - } else if(data[1] == 'M' && command_context == CMD_CONTEXT_RADIO) { + return 1; + case 'C': { + /* send on a set-param thing! */ + uint8_t set_param[] = {'!', 'V', 0, RADIO_PARAM_CHANNEL, 0, 0 }; + int channel = -1; + dectoi(&data[2], len - 2, &channel); + if(channel >= 0) { + set_param[5] = channel & 0xff; + write_to_slip(set_param, sizeof(set_param)); + } + return 1; + } + case 'P': { + /* send on a set-param thing! */ + uint8_t set_param[] = {'!', 'V', 0, RADIO_PARAM_PAN_ID, 0, 0 }; + int pan_id; + dectoi(&data[2], len - 2, &pan_id); + set_param[4] = (pan_id >> 8) & 0xff; + set_param[5] = pan_id & 0xff; + write_to_slip(set_param, sizeof(set_param)); + return 1; + } + default: + return 0; + } + } else if(command_context == CMD_CONTEXT_RADIO) { /* We need to know that this is from the slip-radio here. */ - PRINTF("Setting MAC address\n"); - border_router_set_mac(&data[2]); - return 1; - } else if(data[1] == 'C' && command_context == CMD_CONTEXT_RADIO) { - /* We need to know that this is from the slip-radio here. */ - printf("Channel is:%d\n", data[2]); - return 1; - } else if(data[1] == 'R' && command_context == CMD_CONTEXT_RADIO) { - /* We need to know that this is from the slip-radio here. */ - PRINTF("Packet data report for sid:%d st:%d tx:%d\n", - data[2], data[3], data[4]); - packet_sent(data[2], data[3], data[4]); - return 1; - } else if(data[1] == 'D' && command_context == CMD_CONTEXT_RADIO) { - /* We need to know that this is from the slip-radio here... */ - PRINTF("Sensor data received\n"); - border_router_set_sensors((const char *)&data[2], len - 2); - return 1; + switch(data[1]) { + case 'M': + PRINTF("Setting MAC address\n"); + border_router_set_mac(&data[2]); + return 1; + case 'V': + if(data[3] == RADIO_PARAM_CHANNEL) { + printf("Channel is %d\n", data[5]); + } + if(data[3] == RADIO_PARAM_PAN_ID) { + printf("PAN_ID is 0x%04x\n", (data[4] << 8) + data[5]); + } + return 1; + case 'R': + PRINTF("Packet data report for sid:%d st:%d tx:%d\n", + data[2], data[3], data[4]); + packet_sent(data[2], data[3], data[4]); + return 1; + default: + return 0; + } } } else if(data[0] == '?') { PRINTF("Got request message of type %c\n", data[1]); @@ -110,8 +190,14 @@ border_router_cmd_handler(const uint8_t *data, int len) cmd_send(buf, 18); return 1; } else if(data[1] == 'C' && command_context == CMD_CONTEXT_STDIO) { - /* send on! */ - write_to_slip(data, len); + /* send on a set-param thing! */ + uint8_t set_param[] = {'?', 'V', 0, RADIO_PARAM_CHANNEL}; + write_to_slip(set_param, sizeof(set_param)); + return 1; + } else if(data[1] == 'P' && command_context == CMD_CONTEXT_STDIO) { + /* send on a set-param thing! */ + uint8_t set_param[] = {'?', 'V', 0, RADIO_PARAM_PAN_ID}; + write_to_slip(set_param, sizeof(set_param)); return 1; } else if(data[1] == 'S') { border_router_print_stat(); @@ -132,17 +218,34 @@ border_router_cmd_output(const uint8_t *data, int data_len) printf("\n"); } /*---------------------------------------------------------------------------*/ +static void +serial_shell_output(const char *str) +{ + printf("%s", str); +} +/*---------------------------------------------------------------------------*/ + PROCESS_THREAD(border_router_cmd_process, ev, data) { + static struct pt shell_input_pt; PROCESS_BEGIN(); PRINTF("Started br-cmd process\n"); + + shell_init(); + while(1) { PROCESS_YIELD(); if(ev == serial_line_event_message && data != NULL) { - PRINTF("Got serial data!!! %s of len: %d\n", + PRINTF("Got serial data!!! %s of len: %lu\n", (char *)data, strlen((char *)data)); command_context = CMD_CONTEXT_STDIO; - cmd_input(data, strlen((char *)data)); + if(cmd_input(data, strlen((char *)data))) { + /* Commnand executed - all is fine */ + } else { + /* did not find command - run shell and see if ... */ + // FOR SERIAL RADIO cmd_send((uint8_t *)"EUnknown command", 16); + PROCESS_PT_SPAWN(&shell_input_pt, shell_input(&shell_input_pt, serial_shell_output, data)); + } } } PROCESS_END(); diff --git a/os/services/rpl-border-router/native/border-router-mac.c b/os/services/rpl-border-router/native/border-router-mac.c index 7b002183e..bcfb829b7 100644 --- a/os/services/rpl-border-router/native/border-router-mac.c +++ b/os/services/rpl-border-router/native/border-router-mac.c @@ -63,7 +63,7 @@ struct tx_callback { struct packetbuf_attr attrs[PACKETBUF_NUM_ATTRS]; struct packetbuf_addr addrs[PACKETBUF_NUM_ADDRS]; }; - +/*---------------------------------------------------------------------------*/ static struct tx_callback callbacks[MAX_CALLBACKS]; /*---------------------------------------------------------------------------*/ void @@ -111,6 +111,10 @@ send_packet(mac_callback_t sent, void *ptr) /* ack or not ? */ packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1); + /* Will make it send only DATA packets... for now */ + packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME); + /* printf("Sending packet of type: %s \n", get_frame_type(packetbuf_attr(PACKETBUF_ATTR_FRAME_TYPE))); */ + if(NETSTACK_FRAMER.create() < 0) { /* Failed to allocate space for headers */ PRINTF("br-rdc: send failed, too large header\n"); diff --git a/os/services/slip-cmd/cmd.c b/os/services/slip-cmd/cmd.c index a2853efd2..c821fe77c 100644 --- a/os/services/slip-cmd/cmd.c +++ b/os/services/slip-cmd/cmd.c @@ -48,19 +48,18 @@ void CMD_OUTPUT(const uint8_t *data, int data_len); extern const cmd_handler_t cmd_handlers[]; /*---------------------------------------------------------------------------*/ -void +int cmd_input(const uint8_t *data, int data_len) { int i; for(i = 0; cmd_handlers[i] != NULL; i++) { if(cmd_handlers[i](data, data_len)) { /* Command has been handled */ - return; + return 1; } } - /* Unknown command */ - cmd_send((uint8_t *)"EUnknown command", 16); + return 0; } /*---------------------------------------------------------------------------*/ void diff --git a/os/services/slip-cmd/cmd.h b/os/services/slip-cmd/cmd.h index d363ac933..c3282b536 100644 --- a/os/services/slip-cmd/cmd.h +++ b/os/services/slip-cmd/cmd.h @@ -47,7 +47,7 @@ typedef int (* cmd_handler_t)(const uint8_t *data, int len); #define CMD_HANDLERS(...) \ const cmd_handler_t cmd_handlers[] = {__VA_ARGS__, NULL} -void cmd_input(const uint8_t *data, int data_len); +int cmd_input(const uint8_t *data, int data_len); void cmd_send(const uint8_t *data, int data_len); #endif /* CMD_H_ */