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