Contiki-NG
Loading...
Searching...
No Matches
border-router-cmds.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011, Swedish Institute of Computer Science.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30/**
31 * \file
32 * Sets up some commands for the border router
33 * \author
34 * Niclas Finne <nfi@sics.se>
35 * Joakim Eriksson <joakime@sics.se>
36 */
37
38#include "contiki.h"
39#include "cmd.h"
40#include "border-router.h"
41#include "border-router-cmds.h"
42#include "border-router-cbor.h"
43#include "dev/radio.h"
44#include "dev/serial-line.h"
45#include "net/routing/routing.h"
46#include "net/ipv6/uiplib.h"
47#include <string.h>
48#include "shell.h"
49#include <stdio.h>
50
51/*---------------------------------------------------------------------------*/
52/* Log configuration */
53#include "sys/log.h"
54#define LOG_MODULE "BR"
55#define LOG_LEVEL LOG_LEVEL_NONE
56
57uint8_t command_context;
58
59void packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx);
60void nbr_print_stat(void);
61
62/*---------------------------------------------------------------------------*/
63PROCESS(border_router_cmd_process, "Border router cmd process");
64/*---------------------------------------------------------------------------*/
65static int
66hextoi(const uint8_t *buf, int len)
67{
68 int v = 0;
69 for(; len > 0; len--, buf++) {
70 if(*buf >= '0' && *buf <= '9') {
71 v = (v << 4) + ((*buf - '0') & 0xf);
72 } else if(*buf >= 'a' && *buf <= 'f') {
73 v = (v << 4) + ((*buf - 'a' + 10) & 0xf);
74 } else if(*buf >= 'A' && *buf <= 'F') {
75 v = (v << 4) + ((*buf - 'A' + 10) & 0xf);
76 } else {
77 break;
78 }
79 }
80 return v;
81}
82/*---------------------------------------------------------------------------*/
83static int
84dectoi(const uint8_t *buf, int len)
85{
86 int negative = 0;
87 if(len <= 0) {
88 return 0;
89 }
90 if(*buf == '$') {
91 return hextoi(buf + 1, len - 1);
92 }
93 if(*buf == '0' && *(buf + 1) == 'x' && len > 2) {
94 return hextoi(buf + 2, len - 2);
95 }
96 if(*buf == '-') {
97 negative = 1;
98 buf++;
99 }
100 int v = 0;
101 for(; len > 0; len--, buf++) {
102 if(*buf < '0' || *buf > '9') {
103 break;
104 }
105 v = (v * 10) + ((*buf - '0') & 0xf);
106 }
107 return negative ? -v : v;
108}
109/*---------------------------------------------------------------------------*/
110
111/*---------------------------------------------------------------------------*/
112/* TODO: the below code needs some way of identifying from where the command */
113/* comes. In this case it can be from stdin or from SLIP. */
114/*---------------------------------------------------------------------------*/
115int
116border_router_cmd_handler(const uint8_t *data, int len)
117{
118 /* handle global repair, etc here */
119 if(data[0] == '!') {
120 LOG_DBG("Got configuration message of type %c\n", data[1]);
121 if(command_context == CMD_CONTEXT_STDIO) {
122 switch(data[1]) {
123 case 'G':
124 /* This is supposed to be from stdin */
125 printf("Performing Global Repair...\n");
126 NETSTACK_ROUTING.global_repair("Command");
127 return 1;
128 case 'C': {
129 int channel = dectoi(&data[2], len - 2);
130#if BORDER_ROUTER_SERIAL_RADIO
132#else
133 uint8_t set_param[] = {'!', 'V', 0, RADIO_PARAM_CHANNEL, 0, 0 };
134 set_param[5] = channel & 0xff;
135 write_to_slip(set_param, sizeof(set_param));
136#endif
137 return 1;
138 }
139 case 'P': {
140 int pan_id = dectoi(&data[2], len - 2);
141#if BORDER_ROUTER_SERIAL_RADIO
143#else
144 uint8_t set_param[] = {'!', 'V', 0, RADIO_PARAM_PAN_ID, 0, 0 };
145 set_param[4] = (pan_id >> 8) & 0xff;
146 set_param[5] = pan_id & 0xff;
147 write_to_slip(set_param, sizeof(set_param));
148#endif
149 return 1;
150 }
151 default:
152 return 0;
153 }
154 } else if(command_context == CMD_CONTEXT_RADIO) {
155 /* We need to know that this is from the slip-radio here. */
156 switch(data[1]) {
157 case 'M':
158 LOG_DBG("Setting MAC address\n");
159 border_router_set_mac(&data[2]);
160 return 1;
161 case 'V':
162 if(data[3] == RADIO_PARAM_CHANNEL) {
163 printf("Channel is %d\n", data[5]);
164 }
165 if(data[3] == RADIO_PARAM_PAN_ID) {
166 printf("PAN_ID is 0x%04x\n", (data[4] << 8) + data[5]);
167 }
168 return 1;
169 case 'R':
170 LOG_DBG("Packet data report for sid:%d st:%d tx:%d\n",
171 data[2], data[3], data[4]);
172 packet_sent(data[2], data[3], data[4]);
173 return 1;
174 default:
175 return 0;
176 }
177 }
178 } else if(data[0] == '?') {
179 LOG_DBG("Got request message of type %c\n", data[1]);
180 if(data[1] == 'M' && command_context == CMD_CONTEXT_STDIO) {
181 uint8_t buf[20];
182 char *hexchar = "0123456789abcdef";
183 int j;
184 /* this is just a test so far... just to see if it works */
185 buf[0] = '!';
186 buf[1] = 'M';
187 for(j = 0; j < UIP_LLADDR_LEN; j++) {
188 buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4];
189 buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15];
190 }
191 cmd_send(buf, 18);
192 return 1;
193 } else if(data[1] == 'C' && command_context == CMD_CONTEXT_STDIO) {
194 /* send on a set-param thing! */
195 uint8_t set_param[] = {'?', 'V', 0, RADIO_PARAM_CHANNEL};
196 write_to_slip(set_param, sizeof(set_param));
197 return 1;
198 } else if(data[1] == 'P' && command_context == CMD_CONTEXT_STDIO) {
199 /* send on a set-param thing! */
200 uint8_t set_param[] = {'?', 'V', 0, RADIO_PARAM_PAN_ID};
201 write_to_slip(set_param, sizeof(set_param));
202 return 1;
203 } else if(data[1] == 'S') {
204 border_router_print_stat();
205 return 1;
206 }
207 }
208 return 0;
209}
210/*---------------------------------------------------------------------------*/
211void
212border_router_cmd_output(const uint8_t *data, int data_len)
213{
214 int i;
215 printf("CMD output: ");
216 for(i = 0; i < data_len; i++) {
217 printf("%c", data[i]);
218 }
219 printf("\n");
220}
221/*---------------------------------------------------------------------------*/
222static void
223serial_shell_output(const char *str)
224{
225 printf("%s", str);
226}
227/*---------------------------------------------------------------------------*/
228void
230{
231 /* avoid starting the normal serial-shell */
232}
233/*---------------------------------------------------------------------------*/
234
235PROCESS_THREAD(border_router_cmd_process, ev, data)
236{
237 static struct pt shell_input_pt;
239
240 shell_init();
241
242 while(1) {
244 if(ev == serial_line_event_message && data != NULL) {
245 LOG_DBG("Got serial data!!! %s of len: %zd\n",
246 (char *)data, strlen((char *)data));
247 command_context = CMD_CONTEXT_STDIO;
248 if(!cmd_input(data, strlen((char *)data))) {
249 /* did not find command - run shell and see if ... */
250 PROCESS_PT_SPAWN(&shell_input_pt,
251 shell_input(&shell_input_pt, serial_shell_output,
252 data));
253 }
254 }
255 }
256 PROCESS_END();
257}
258/*---------------------------------------------------------------------------*/
CBOR-over-SLIP protocol for talking to the serialradio firmware (examples/serialradio) from the nativ...
void br_cbor_send_set_param(uint8_t msg_id, uint16_t param, int32_t value)
Set a radio parameter on the serial radio (SET_PARAM).
void serial_shell_init(void)
Initializes Serial Shell module.
Sets up some commands for the border router.
Border router header file.
Simple command handler.
#define PROCESS(name, strname)
Declare a process.
Definition process.h:309
#define PROCESS_PT_SPAWN(pt, thread)
Spawn a protothread from the process.
Definition process.h:213
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition process.h:122
#define PROCESS_END()
Define the end of a process.
Definition process.h:133
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition process.h:275
#define PROCESS_YIELD()
Yield the currently running process.
Definition process.h:166
@ RADIO_PARAM_CHANNEL
Channel used for radio communication.
Definition radio.h:134
@ RADIO_PARAM_PAN_ID
The personal area network identifier (PAN ID), which is used by the h/w frame filtering functionality...
Definition radio.h:150
void shell_init(void)
Initializes Shell module.
Definition shell.c:123
char shell_input(struct pt *pt, shell_output_func output, const char *cmd)
A protothread that is spawned by a Shell driver when receiving a new line.
Definition shell.c:88
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
uip_lladdr_t uip_lladdr
Host L2 address.
Definition uip6.c:107
#define UIP_LLADDR_LEN
802.15.4 address
Definition uip.h:145
Header file for the logging system.
Header file for the radio API.
Routing driver header file.
Generic serial I/O process header filer.
Main header file for the Contiki shell.
Header file for the IP address manipulation library.