Contiki-Inga 3.x
params.c
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  * This file is part of the Contiki operating system.
30  *
31  */
32 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
33 
34 #define DEBUG 1
35 #if DEBUG
36 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
37 #else
38 #define PRINTD(...)
39 #endif
40 
41 #include "contiki.h"
42 #include <avr/pgmspace.h>
43 #include <avr/eeprom.h>
44 #include <stdio.h>
45 #include <string.h>
46 
47 #if AVR_WEBSERVER
48 //#include "httpd-fs.h"
49 //#include "httpd-cgi.h"
50 #endif
51 
52 #include "contiki-net.h"
53 #include "params.h"
54 
55 #if CONTIKI_CONF_RANDOM_MAC
56 extern uint8_t rng_get_uint8(void);
57 static void
58 generate_new_eui64(uint8_t eui64[8]) {
59  eui64[0] = 0x02;
60  eui64[1] = rng_get_uint8();
61  eui64[2] = rng_get_uint8();
62  eui64[3] = 0xFF;
63  eui64[4] = 0xFE;
64  eui64[5] = rng_get_uint8();
65  eui64[6] = rng_get_uint8();
66  eui64[7] = rng_get_uint8();
67 }
68 #endif
69 
70 #if AVR_WEBSERVER
71 /* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */
72 extern uint8_t default_mac_address[8];
73 extern uint8_t default_server_name[16];
74 extern uint8_t default_domain_name[30];
75 #else
76 const uint8_t default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR;
77 const uint8_t default_server_name[] PROGMEM = PARAMS_SERVERNAME;
78 const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME;
79 #endif
80 
81 #if PARAMETER_STORAGE==0
82 /* 0 Hard coded, minmal program and eeprom usage. */
83 uint8_t
84 params_get_eui64(uint8_t *eui64) {
85 #if CONTIKI_CONF_RANDOM_MAC
86  PRINTD("Generating random EUI64 MAC\n");
87  generate_new_eui64(eui64);
88  return 1;
89 #else
90  uint8_t i;
91  for (i=0;i<sizeof(default_mac_address);i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);
92  return 0;
93 #endif
94 }
95 #elif PARAMETER_STORAGE==1
96 /* 1 Stored in fixed eeprom locations, rewritten from flash if corrupt.
97  * They can be manually changed and kept over program reflash.
98  * The channel and bit complement are used to check EEMEM integrity,
99  * If corrupt all values will be rewritten with the default flash values.
100  * To make this work, get the channel before anything else.
101  */
102 #if !AVR_WEBSERVER
103 uint8_t eemem_mac_address[] EEMEM = PARAMS_EUI64ADDR;
104 uint8_t eemem_server_name[] EEMEM = PARAMS_SERVERNAME;
105 uint8_t eemem_domain_name[] EEMEM = PARAMS_DOMAINNAME;
106 #endif /*AVR_WEBSERVER */
107 
108 uint16_t eemem_nodeid EEMEM = PARAMS_NODEID;
109 uint8_t eemem_channel[2] EEMEM = {PARAMS_CHANNEL, ~PARAMS_CHANNEL};
110 uint16_t eemem_panid EEMEM = PARAMS_PANID;
111 uint16_t eemem_panaddr EEMEM = PARAMS_PANADDR;
112 uint8_t eemem_txpower EEMEM = PARAMS_TXPOWER;
113 
114 #if CONTIKI_CONF_RANDOM_MAC
115 static uint8_t randomeui64;
116 #endif
117  uint8_t i,buffer[32];
118 uint8_t
119 params_get_channel(void) {
120  uint8_t x[2];
121  *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel);
122 /* Don't return an invalid channel number */
123  if( (x[0]<11) || (x[0] > 26)) x[1]=x[0];
124 /* Do exclusive or test on the two values read */
125  if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit
126 /* Verification fails, rewrite everything */
127  // uint8_t i,buffer[32];
128  PRINTD("EEPROM is corrupt, rewriting with defaults.\n");
129 #if CONTIKI_CONF_RANDOM_MAC
130  PRINTD("Generating random EUI64 MAC\n");
131  generate_new_eui64(&buffer);
132  randomeui64=1;
133 #else
134  for (i=0;i<sizeof(default_mac_address);i++) buffer[i] = pgm_read_byte_near(default_mac_address+i);
135 #endif
136 /* eeprom_write_block should not be interrupted */
137  cli();
138  eeprom_write_block(&buffer, &eemem_mac_address, sizeof(eemem_mac_address));
139  eeprom_read_block (&buffer, &eemem_mac_address, sizeof(rimeaddr_t));
140  for (i=0;i<sizeof(default_server_name);i++) buffer[i] = pgm_read_byte_near(default_server_name+i);
141  eeprom_write_block(&buffer, &eemem_server_name, sizeof(eemem_server_name));
142  for (i=0;i<sizeof(default_domain_name);i++) buffer[i] = pgm_read_byte_near(default_domain_name+i);
143  eeprom_write_block(&buffer, &eemem_domain_name, sizeof(eemem_domain_name));
144  eeprom_write_word(&eemem_panid , PARAMS_PANID);
145  eeprom_write_word(&eemem_panaddr, PARAMS_PANADDR);
146  eeprom_write_byte(&eemem_txpower, PARAMS_TXPOWER);
147  eeprom_write_word(&eemem_nodeid, PARAMS_NODEID);
148  x[0] = PARAMS_CHANNEL;
149  x[1]= ~x[0];
150  eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x);
151  sei();
152  }
153 /* Always returns a valid channel */
154  return x[0];
155 }
156 uint8_t
157 params_get_eui64(uint8_t *eui64) {
158  cli();
159  eeprom_read_block ((void *)eui64, &eemem_mac_address, sizeof(linkaddr_t));
160  sei();
161 #if CONTIKI_CONF_RANDOM_MAC
162  return randomeui64;
163 #else
164  return 0;
165 #endif
166 }
167 uint16_t
168 params_get_panid(void) {
169  return eeprom_read_word(&eemem_panid);
170 }
171 uint16_t
172 params_get_panaddr(void) {
173  return eeprom_read_word (&eemem_panaddr);
174 }
175 uint8_t
176 params_get_txpower(void)
177 {
178  return eeprom_read_byte(&eemem_txpower);
179 }
180 
181 #else /* CONTIKI_CONF_SETTINGS_MANAGER */
182 
183 uint8_t
184 params_get_channel() {
185  uint8_t x;
186  size_t size = 1;
187  if (settings_get(SETTINGS_KEY_CHANNEL, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
188  PRINTD("<-Get RF channel %u\n",x);
189  } else {
190  x = PARAMS_CHANNEL;
191  if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) {
192  PRINTD("->Set EEPROM RF channel to %d\n",x);
193  }
194  }
195  return x;
196 }
197 uint8_t
198 params_get_eui64(uint8_t *eui64) {
199  size_t size = sizeof(linkaddr_t);
200  if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)eui64, &size) == SETTINGS_STATUS_OK) {
201  PRINTD("<-Get EUI64 MAC\n");
202  return 0;
203  }
204 #if CONTIKI_CONF_RANDOM_MAC
205  PRINTD("Generating random EUI64 MAC\n");
206  generate_new_eui64(eui64);
207 #else
208  {uint8_t i;for (i=0;i<8;i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);} //test this
209 #endif
210  if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)eui64,8) == SETTINGS_STATUS_OK) {
211  PRINTD("->Set EEPROM MAC address\n");
212  }
213 #if CONTIKI_CONF_RANDOM_MAC
214  return 1;
215 #else
216  return 0;
217 #endif
218 }
219 uint16_t
220 params_get_panid(void) {
221  uint16_t x;
222  size_t size = 2;
223  if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
224  PRINTD("<-Get PAN ID of %04x\n",x);
225  } else {
226  x=PARAMS_PANID;
227  if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) {
228  PRINTD("->Set EEPROM PAN ID to %04x\n",x);
229  }
230  }
231  return x;
232 }
233 uint16_t
234 params_get_panaddr(void) {
235  uint16_t x;
236  size_t size = 2;
237  if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
238  PRINTD("<-Get PAN address of %04x\n",x);
239  } else {
240  x=PARAMS_PANADDR;
241  if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) {
242  PRINTD("->Set EEPROM PAN address to %04x\n",x);
243  }
244  }
245  return x;
246 }
247 uint8_t
248 params_get_txpower(void) {
249  uint8_t x;
250  size_t size = 1;
251  if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) {
252  PRINTD("<-Get tx power of %d (0=max)\n",x);
253  } else {
254  x=PARAMS_TXPOWER;
255  if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) {
256  PRINTD("->Set EEPROM tx power of %d (0=max)\n",x);
257  }
258  }
259  return x;
260 }
261 #endif /* CONTIKI_CONF_SETTINGS_MANAGER */