Contiki 2.6

params.c

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 */