Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2011, Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * This file is part of the Contiki operating system. 00030 * 00031 */ 00032 #define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00033 00034 #define DEBUG 1 00035 #if DEBUG 00036 #define PRINTD(FORMAT,args...) printf_P(PSTR(FORMAT),##args) 00037 #else 00038 #define PRINTD(...) 00039 #endif 00040 00041 #include "contiki.h" 00042 #include <avr/pgmspace.h> 00043 #include <avr/eeprom.h> 00044 #include <stdio.h> 00045 #include <string.h> 00046 00047 #if AVR_WEBSERVER 00048 //#include "httpd-fs.h" 00049 //#include "httpd-cgi.h" 00050 #endif 00051 00052 #include "contiki-net.h" 00053 #include "params.h" 00054 00055 #if WITH_NODE_ID 00056 uint16_t node_id; 00057 #endif 00058 00059 #if CONTIKI_CONF_RANDOM_MAC 00060 extern uint8_t rng_get_uint8(void); 00061 static void 00062 generate_new_eui64(uint8_t eui64[8]) { 00063 eui64[0] = 0x02; 00064 eui64[1] = rng_get_uint8(); 00065 eui64[2] = rng_get_uint8(); 00066 eui64[3] = 0xFF; 00067 eui64[4] = 0xFE; 00068 eui64[5] = rng_get_uint8(); 00069 eui64[6] = rng_get_uint8(); 00070 eui64[7] = rng_get_uint8(); 00071 } 00072 #endif 00073 00074 #if AVR_WEBSERVER 00075 /* Webserver builds can set these in httpd-fsdata.c via makefsdata.h */ 00076 extern uint8_t default_mac_address[8]; 00077 extern uint8_t default_server_name[16]; 00078 extern uint8_t default_domain_name[30]; 00079 #else 00080 const uint8_t default_mac_address[8] PROGMEM = PARAMS_EUI64ADDR; 00081 const uint8_t default_server_name[] PROGMEM = PARAMS_SERVERNAME; 00082 const uint8_t default_domain_name[] PROGMEM = PARAMS_DOMAINNAME; 00083 #endif 00084 00085 #if PARAMETER_STORAGE==0 00086 /* 0 Hard coded, minmal program and eeprom usage. */ 00087 uint8_t 00088 params_get_eui64(uint8_t *eui64) { 00089 #if CONTIKI_CONF_RANDOM_MAC 00090 PRINTD("Generating random EUI64 MAC\n"); 00091 generate_new_eui64(eui64); 00092 return 1; 00093 #else 00094 uint8_t i; 00095 for (i=0;i<sizeof(default_mac_address);i++) eui64[i] = pgm_read_byte_near(default_mac_address+i); 00096 return 0; 00097 #endif 00098 } 00099 #elif PARAMETER_STORAGE==1 00100 /* 1 Stored in fixed eeprom locations, rewritten from flash if corrupt. 00101 * They can be manually changed and kept over program reflash. 00102 * The channel and bit complement are used to check EEMEM integrity, 00103 * If corrupt all values will be rewritten with the default flash values. 00104 * To make this work, get the channel before anything else. 00105 */ 00106 #if !AVR_WEBSERVER 00107 uint8_t eemem_mac_address[] EEMEM = PARAMS_EUI64ADDR; 00108 uint8_t eemem_server_name[] EEMEM = PARAMS_SERVERNAME; 00109 uint8_t eemem_domain_name[] EEMEM = PARAMS_DOMAINNAME; 00110 #endif /*AVR_WEBSERVER */ 00111 00112 uint16_t eemem_nodeid EEMEM = PARAMS_NODEID; 00113 uint8_t eemem_channel[2] EEMEM = {PARAMS_CHANNEL, ~PARAMS_CHANNEL}; 00114 uint16_t eemem_panid EEMEM = PARAMS_PANID; 00115 uint16_t eemem_panaddr EEMEM = PARAMS_PANADDR; 00116 uint8_t eemem_txpower EEMEM = PARAMS_TXPOWER; 00117 00118 #if CONTIKI_CONF_RANDOM_MAC 00119 static uint8_t randomeui64; 00120 #endif 00121 00122 uint8_t 00123 params_get_channel(void) { 00124 uint8_t x[2]; 00125 *(uint16_t *)x = eeprom_read_word ((uint16_t *)&eemem_channel); 00126 /* Don't return an invalid channel number */ 00127 if( (x[0]<11) || (x[0] > 26)) x[1]=x[0]; 00128 /* Do exclusive or test on the two values read */ 00129 if((uint8_t)x[0]!=(uint8_t)~x[1]) {//~x[1] can promote comparison to 16 bit 00130 /* Verification fails, rewrite everything */ 00131 uint8_t i,buffer[32]; 00132 PRINTD("EEPROM is corrupt, rewriting with defaults.\n"); 00133 #if CONTIKI_CONF_RANDOM_MAC 00134 PRINTD("Generating random EUI64 MAC\n"); 00135 generate_new_eui64(&buffer); 00136 randomeui64=1; 00137 #else 00138 for (i=0;i<sizeof(default_mac_address);i++) buffer[i] = pgm_read_byte_near(default_mac_address+i); 00139 #endif 00140 /* eeprom_write_block should not be interrupted */ 00141 cli(); 00142 eeprom_write_block(&buffer, &eemem_mac_address, sizeof(eemem_mac_address)); 00143 for (i=0;i<sizeof(default_server_name);i++) buffer[i] = pgm_read_byte_near(default_server_name+i); 00144 eeprom_write_block(&buffer, &eemem_server_name, sizeof(eemem_server_name)); 00145 for (i=0;i<sizeof(default_domain_name);i++) buffer[i] = pgm_read_byte_near(default_domain_name+i); 00146 eeprom_write_block(&buffer, &eemem_domain_name, sizeof(eemem_domain_name)); 00147 eeprom_write_word(&eemem_panid , PARAMS_PANID); 00148 eeprom_write_word(&eemem_panaddr, PARAMS_PANADDR); 00149 eeprom_write_byte(&eemem_txpower, PARAMS_TXPOWER); 00150 eeprom_write_word(&eemem_nodeid, PARAMS_NODEID); 00151 x[0] = PARAMS_CHANNEL; 00152 x[1]= ~x[0]; 00153 eeprom_write_word((uint16_t *)&eemem_channel, *(uint16_t *)x); 00154 sei(); 00155 } 00156 /* Always returns a valid channel */ 00157 return x[0]; 00158 } 00159 uint8_t 00160 params_get_eui64(uint8_t *eui64) { 00161 cli(); 00162 eeprom_read_block ((void *)eui64, &eemem_mac_address, sizeof(rimeaddr_t)); 00163 sei(); 00164 #if CONTIKI_CONF_RANDOM_MAC 00165 return randomeui64; 00166 #else 00167 return 0; 00168 #endif 00169 } 00170 uint16_t 00171 params_get_panid(void) { 00172 return eeprom_read_word(&eemem_panid); 00173 } 00174 uint16_t 00175 params_get_panaddr(void) { 00176 return eeprom_read_word (&eemem_panaddr); 00177 } 00178 uint8_t 00179 params_get_txpower(void) 00180 { 00181 return eeprom_read_byte(&eemem_txpower); 00182 } 00183 00184 #else /* CONTIKI_CONF_SETTINGS_MANAGER */ 00185 00186 uint8_t 00187 params_get_channel() { 00188 uint8_t x; 00189 size_t size = 1; 00190 if (settings_get(SETTINGS_KEY_CHANNEL, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { 00191 PRINTD("<-Get RF channel %u\n",x); 00192 } else { 00193 x = PARAMS_CHANNEL; 00194 if (settings_add_uint8(SETTINGS_KEY_CHANNEL,x ) == SETTINGS_STATUS_OK) { 00195 PRINTD("->Set EEPROM RF channel to %d\n",x); 00196 } 00197 } 00198 return x; 00199 } 00200 uint8_t 00201 params_get_eui64(uint8_t *eui64) { 00202 size_t size = sizeof(rimeaddr_t); 00203 if(settings_get(SETTINGS_KEY_EUI64, 0, (unsigned char*)eui64, &size) == SETTINGS_STATUS_OK) { 00204 PRINTD("<-Get EUI64 MAC\n"); 00205 return 0; 00206 } 00207 #if CONTIKI_CONF_RANDOM_MAC 00208 PRINTD("Generating random EUI64 MAC\n"); 00209 generate_new_eui64(eui64); 00210 #else 00211 {uint8_t i;for (i=0;i<8;i++) eui64[i] = pgm_read_byte_near(default_mac_address+i);} //test this 00212 #endif 00213 if (settings_add(SETTINGS_KEY_EUI64,(unsigned char*)eui64,8) == SETTINGS_STATUS_OK) { 00214 PRINTD("->Set EEPROM MAC address\n"); 00215 } 00216 #if CONTIKI_CONF_RANDOM_MAC 00217 return 1; 00218 #else 00219 return 0; 00220 #endif 00221 } 00222 uint16_t 00223 params_get_panid(void) { 00224 uint16_t x; 00225 size_t size = 2; 00226 if (settings_get(SETTINGS_KEY_PAN_ID, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { 00227 PRINTD("<-Get PAN ID of %04x\n",x); 00228 } else { 00229 x=PARAMS_PANID; 00230 if (settings_add_uint16(SETTINGS_KEY_PAN_ID,x)==SETTINGS_STATUS_OK) { 00231 PRINTD("->Set EEPROM PAN ID to %04x\n",x); 00232 } 00233 } 00234 return x; 00235 } 00236 uint16_t 00237 params_get_panaddr(void) { 00238 uint16_t x; 00239 size_t size = 2; 00240 if (settings_get(SETTINGS_KEY_PAN_ADDR, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { 00241 PRINTD("<-Get PAN address of %04x\n",x); 00242 } else { 00243 x=PARAMS_PANADDR; 00244 if (settings_add_uint16(SETTINGS_KEY_PAN_ADDR,x)==SETTINGS_STATUS_OK) { 00245 PRINTD("->Set EEPROM PAN address to %04x\n",x); 00246 } 00247 } 00248 return x; 00249 } 00250 uint8_t 00251 params_get_txpower(void) { 00252 uint8_t x; 00253 size_t size = 1; 00254 if (settings_get(SETTINGS_KEY_TXPOWER, 0,(unsigned char*)&x, &size) == SETTINGS_STATUS_OK) { 00255 PRINTD("<-Get tx power of %d (0=max)\n",x); 00256 } else { 00257 x=PARAMS_TXPOWER; 00258 if (settings_add_uint8(SETTINGS_KEY_TXPOWER,x)==SETTINGS_STATUS_OK) { 00259 PRINTD("->Set EEPROM tx power of %d (0=max)\n",x); 00260 } 00261 } 00262 return x; 00263 } 00264 #endif /* CONTIKI_CONF_SETTINGS_MANAGER */