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 "dev/serial-line.h"
43#include "net/routing/routing.h"
44#include "net/ipv6/uiplib.h"
45#include <string.h>
46#include "shell.h"
47#include <stdio.h>
48
49/*---------------------------------------------------------------------------*/
50/* Log configuration */
51#include "sys/log.h"
52#define LOG_MODULE "BR"
53#define LOG_LEVEL LOG_LEVEL_NONE
54
55uint8_t command_context;
56
57void packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx);
58void nbr_print_stat(void);
59
60/*---------------------------------------------------------------------------*/
61PROCESS(border_router_cmd_process, "Border router cmd process");
62/*---------------------------------------------------------------------------*/
63static int
64hextoi(const uint8_t *buf, int len)
65{
66 int v = 0;
67 for(; len > 0; len--, buf++) {
68 if(*buf >= '0' && *buf <= '9') {
69 v = (v << 4) + ((*buf - '0') & 0xf);
70 } else if(*buf >= 'a' && *buf <= 'f') {
71 v = (v << 4) + ((*buf - 'a' + 10) & 0xf);
72 } else if(*buf >= 'A' && *buf <= 'F') {
73 v = (v << 4) + ((*buf - 'A' + 10) & 0xf);
74 } else {
75 break;
76 }
77 }
78 return v;
79}
80/*---------------------------------------------------------------------------*/
81static int
82dectoi(const uint8_t *buf, int len)
83{
84 int negative = 0;
85 if(len <= 0) {
86 return 0;
87 }
88 if(*buf == '$') {
89 return hextoi(buf + 1, len - 1);
90 }
91 if(*buf == '0' && *(buf + 1) == 'x' && len > 2) {
92 return hextoi(buf + 2, len - 2);
93 }
94 if(*buf == '-') {
95 negative = 1;
96 buf++;
97 }
98 int v = 0;
99 for(; len > 0; len--, buf++) {
100 if(*buf < '0' || *buf > '9') {
101 break;
102 }
103 v = (v * 10) + ((*buf - '0') & 0xf);
104 }
105 return negative ? -v : v;
106}
107/*---------------------------------------------------------------------------*/
108
109/*---------------------------------------------------------------------------*/
110/* TODO: the below code needs some way of identifying from where the command */
111/* comes. In this case it can be from stdin or from SLIP. */
112/*---------------------------------------------------------------------------*/
113int
114border_router_cmd_handler(const uint8_t *data, int len)
115{
116 /* handle global repair, etc here */
117 if(data[0] == '!') {
118 LOG_DBG("Got configuration message of type %c\n", data[1]);
119 if(command_context == CMD_CONTEXT_STDIO) {
120 switch(data[1]) {
121 case 'G':
122 /* This is supposed to be from stdin */
123 printf("Performing Global Repair...\n");
124 NETSTACK_ROUTING.global_repair("Command");
125 return 1;
126 case 'C': {
127 /* send on a set-param thing! */
128 uint8_t set_param[] = {'!', 'V', 0, RADIO_PARAM_CHANNEL, 0, 0 };
129 int channel = dectoi(&data[2], len - 2);
130 set_param[5] = channel & 0xff;
131 write_to_slip(set_param, sizeof(set_param));
132 return 1;
133 }
134 case 'P': {
135 /* send on a set-param thing! */
136 uint8_t set_param[] = {'!', 'V', 0, RADIO_PARAM_PAN_ID, 0, 0 };
137 int pan_id = dectoi(&data[2], len - 2);
138 set_param[4] = (pan_id >> 8) & 0xff;
139 set_param[5] = pan_id & 0xff;
140 write_to_slip(set_param, sizeof(set_param));
141 return 1;
142 }
143 default:
144 return 0;
145 }
146 } else if(command_context == CMD_CONTEXT_RADIO) {
147 /* We need to know that this is from the slip-radio here. */
148 switch(data[1]) {
149 case 'M':
150 LOG_DBG("Setting MAC address\n");
151 border_router_set_mac(&data[2]);
152 return 1;
153 case 'V':
154 if(data[3] == RADIO_PARAM_CHANNEL) {
155 printf("Channel is %d\n", data[5]);
156 }
157 if(data[3] == RADIO_PARAM_PAN_ID) {
158 printf("PAN_ID is 0x%04x\n", (data[4] << 8) + data[5]);
159 }
160 return 1;
161 case 'R':
162 LOG_DBG("Packet data report for sid:%d st:%d tx:%d\n",
163 data[2], data[3], data[4]);
164 packet_sent(data[2], data[3], data[4]);
165 return 1;
166 default:
167 return 0;
168 }
169 }
170 } else if(data[0] == '?') {
171 LOG_DBG("Got request message of type %c\n", data[1]);
172 if(data[1] == 'M' && command_context == CMD_CONTEXT_STDIO) {
173 uint8_t buf[20];
174 char *hexchar = "0123456789abcdef";
175 int j;
176 /* this is just a test so far... just to see if it works */
177 buf[0] = '!';
178 buf[1] = 'M';
179 for(j = 0; j < UIP_LLADDR_LEN; j++) {
180 buf[2 + j * 2] = hexchar[uip_lladdr.addr[j] >> 4];
181 buf[3 + j * 2] = hexchar[uip_lladdr.addr[j] & 15];
182 }
183 cmd_send(buf, 18);
184 return 1;
185 } else if(data[1] == 'C' && command_context == CMD_CONTEXT_STDIO) {
186 /* send on a set-param thing! */
187 uint8_t set_param[] = {'?', 'V', 0, RADIO_PARAM_CHANNEL};
188 write_to_slip(set_param, sizeof(set_param));
189 return 1;
190 } else if(data[1] == 'P' && command_context == CMD_CONTEXT_STDIO) {
191 /* send on a set-param thing! */
192 uint8_t set_param[] = {'?', 'V', 0, RADIO_PARAM_PAN_ID};
193 write_to_slip(set_param, sizeof(set_param));
194 return 1;
195 } else if(data[1] == 'S') {
196 border_router_print_stat();
197 return 1;
198 }
199 }
200 return 0;
201}
202/*---------------------------------------------------------------------------*/
203void
204border_router_cmd_output(const uint8_t *data, int data_len)
205{
206 int i;
207 printf("CMD output: ");
208 for(i = 0; i < data_len; i++) {
209 printf("%c", data[i]);
210 }
211 printf("\n");
212}
213/*---------------------------------------------------------------------------*/
214static void
215serial_shell_output(const char *str)
216{
217 printf("%s", str);
218}
219/*---------------------------------------------------------------------------*/
220
221PROCESS_THREAD(border_router_cmd_process, ev, data)
222{
223 static struct pt shell_input_pt;
225
226 shell_init();
227
228 while(1) {
230 if(ev == serial_line_event_message && data != NULL) {
231 LOG_DBG("Got serial data!!! %s of len: %zd\n",
232 (char *)data, strlen((char *)data));
233 command_context = CMD_CONTEXT_STDIO;
234 if(!cmd_input(data, strlen((char *)data))) {
235 /* did not find command - run shell and see if ... */
236 PROCESS_PT_SPAWN(&shell_input_pt,
237 shell_input(&shell_input_pt, serial_shell_output,
238 data));
239 }
240 }
241 }
242 PROCESS_END();
243}
244/*---------------------------------------------------------------------------*/
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:308
#define PROCESS_PT_SPAWN(pt, thread)
Spawn a protothread from the process.
Definition process.h:212
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition process.h:121
#define PROCESS_END()
Define the end of a process.
Definition process.h:132
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition process.h:274
#define PROCESS_YIELD()
Yield the currently running process.
Definition process.h:165
@ 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
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.
Routing driver header file.
Generic serial I/O process header filer.
Main header file for the Contiki shell.
void(* global_repair)(const char *str)
Triggers a global topology repair.
Definition routing.h:120
Header file for the IP address manipulation library.