00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 #include <stdio.h>
00033 #include <string.h>
00034 
00035 #include <io.h>
00036 #include <signal.h>
00037 
00038 #include "contiki.h"
00039 
00040 #include "dev/cc2420.h"
00041 #include "dev/ds2411.h"
00042 #include "dev/leds.h"
00043 #include "dev/serial-line.h"
00044 #include "dev/slip.h"
00045 #include "dev/uart1.h"
00046 #include "dev/watchdog.h"
00047 #include "dev/xmem.h"
00048 #include "lib/random.h"
00049 #include "net/netstack.h"
00050 #include "net/mac/frame802154.h"
00051 
00052 #if WITH_UIP6
00053 #include "net/uip-ds6.h"
00054 #endif 
00055 
00056 #include "net/rime.h"
00057 
00058 #include "node-id.h"
00059 #include "cfs-coffee-arch.h"
00060 #include "cfs/cfs-coffee.h"
00061 #include "sys/autostart.h"
00062 #include "sys/profile.h"
00063 
00064 #if UIP_CONF_ROUTER
00065 
00066 #ifndef UIP_ROUTER_MODULE
00067 #ifdef UIP_CONF_ROUTER_MODULE
00068 #define UIP_ROUTER_MODULE UIP_CONF_ROUTER_MODULE
00069 #else 
00070 #define UIP_ROUTER_MODULE rimeroute
00071 #endif 
00072 #endif 
00073 
00074 extern const struct uip_router UIP_ROUTER_MODULE;
00075 #endif 
00076 
00077 #if DCOSYNCH_CONF_ENABLED
00078 static struct timer mgt_timer;
00079 #endif
00080 extern int msp430_dco_required;
00081 
00082 #ifndef WITH_UIP
00083 #define WITH_UIP 0
00084 #endif
00085 
00086 #if WITH_UIP
00087 #include "net/uip.h"
00088 #include "net/uip-fw.h"
00089 #include "net/uip-fw-drv.h"
00090 #include "net/uip-over-mesh.h"
00091 static struct uip_fw_netif slipif =
00092   {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
00093 static struct uip_fw_netif meshif =
00094   {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
00095 
00096 #endif 
00097 
00098 #define UIP_OVER_MESH_CHANNEL 8
00099 #if WITH_UIP
00100 static uint8_t is_gateway;
00101 #endif 
00102 
00103 #ifdef EXPERIMENT_SETUP
00104 #include "experiment-setup.h"
00105 #endif
00106 
00107 void init_platform(void);
00108 
00109 
00110 #if 0
00111 int
00112 force_float_inclusion()
00113 {
00114   extern int __fixsfsi;
00115   extern int __floatsisf;
00116   extern int __mulsf3;
00117   extern int __subsf3;
00118 
00119   return __fixsfsi + __floatsisf + __mulsf3 + __subsf3;
00120 }
00121 #endif
00122 
00123 void uip_log(char *msg) { puts(msg); }
00124 
00125 #ifndef RF_CHANNEL
00126 #define RF_CHANNEL              26
00127 #endif
00128 
00129 #if 0
00130 void
00131 force_inclusion(int d1, int d2)
00132 {
00133   snprintf(NULL, 0, "%d", d1 % d2);
00134 }
00135 #endif
00136 
00137 static void
00138 set_rime_addr(void)
00139 {
00140   rimeaddr_t addr;
00141   int i;
00142 
00143   memset(&addr, 0, sizeof(rimeaddr_t));
00144 #if UIP_CONF_IPV6
00145   memcpy(addr.u8, ds2411_id, sizeof(addr.u8));
00146 #else
00147   if(node_id == 0) {
00148     for(i = 0; i < sizeof(rimeaddr_t); ++i) {
00149       addr.u8[i] = ds2411_id[7 - i];
00150     }
00151   } else {
00152     addr.u8[0] = node_id & 0xff;
00153     addr.u8[1] = node_id >> 8;
00154   }
00155 #endif
00156   rimeaddr_set_node_addr(&addr);
00157   printf("Rime started with address ");
00158   for(i = 0; i < sizeof(addr.u8) - 1; i++) {
00159     printf("%d.", addr.u8[i]);
00160   }
00161   printf("%d\n", addr.u8[i]);
00162 }
00163 
00164 static void
00165 print_processes(struct process * const processes[])
00166 {
00167   
00168   printf("Starting");
00169   while(*processes != NULL) {
00170     printf(" '%s'", (*processes)->name);
00171     processes++;
00172   }
00173   putchar('\n');
00174 }
00175 
00176 #if WITH_UIP
00177 static void
00178 set_gateway(void)
00179 {
00180   if(!is_gateway) {
00181     leds_on(LEDS_RED);
00182     printf("%d.%d: making myself the IP network gateway.\n\n",
00183            rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]);
00184     printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
00185            uip_ipaddr_to_quad(&uip_hostaddr));
00186     uip_over_mesh_set_gateway(&rimeaddr_node_addr);
00187     uip_over_mesh_make_announced_gateway();
00188     is_gateway = 1;
00189   }
00190 }
00191 #endif 
00192 
00193 #if WITH_TINYOS_AUTO_IDS
00194 uint16_t TOS_NODE_ID = 0x1234; 
00195 uint16_t TOS_LOCAL_ADDRESS = 0x1234; 
00196 #endif 
00197 int
00198 main(int argc, char **argv)
00199 {
00200   
00201 
00202 
00203   msp430_cpu_init();
00204   clock_init();
00205   leds_init();
00206   leds_on(LEDS_RED);
00207 
00208 
00209   uart1_init(BAUD2UBR(115200)); 
00210 #if WITH_UIP
00211   slip_arch_init(BAUD2UBR(115200));
00212 #endif 
00213 
00214   leds_on(LEDS_GREEN);
00215   ds2411_init();
00216 
00217   
00218 
00219 
00220   ds2411_id[2] &= 0xfe;
00221 
00222   leds_on(LEDS_BLUE);
00223   xmem_init();
00224 
00225   leds_off(LEDS_RED);
00226   rtimer_init();
00227   
00228 
00229 
00230 
00231   
00232 #if WITH_TINYOS_AUTO_IDS
00233   node_id = TOS_NODE_ID;
00234 #else 
00235   
00236   node_id_restore();
00237 #endif 
00238 
00239   
00240 #ifdef IEEE_802154_MAC_ADDRESS
00241   {
00242     uint8_t ieee[] = IEEE_802154_MAC_ADDRESS;
00243     memcpy(ds2411_id, ieee, sizeof(uip_lladdr.addr));
00244     ds2411_id[7] = node_id & 0xff;
00245   }
00246 #endif
00247 
00248   random_init(ds2411_id[0] + node_id);
00249   
00250   leds_off(LEDS_BLUE);
00251   
00252 
00253 
00254   process_init();
00255   process_start(&etimer_process, NULL);
00256 
00257   ctimer_init();
00258 
00259   init_platform();
00260 
00261   set_rime_addr();
00262   
00263   cc2420_init();
00264   {
00265     uint8_t longaddr[8];
00266     uint16_t shortaddr;
00267     
00268     shortaddr = (rimeaddr_node_addr.u8[0] << 8) +
00269       rimeaddr_node_addr.u8[1];
00270     memset(longaddr, 0, sizeof(longaddr));
00271     rimeaddr_copy((rimeaddr_t *)&longaddr, &rimeaddr_node_addr);
00272     printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ",
00273            longaddr[0], longaddr[1], longaddr[2], longaddr[3],
00274            longaddr[4], longaddr[5], longaddr[6], longaddr[7]);
00275     
00276     cc2420_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr);
00277   }
00278   cc2420_set_channel(RF_CHANNEL);
00279 
00280   printf(CONTIKI_VERSION_STRING " started. ");
00281   if(node_id > 0) {
00282     printf("Node id is set to %u.\n", node_id);
00283   } else {
00284     printf("Node id is not set.\n");
00285   }
00286 
00287   
00288 
00289 
00290 
00291 #if WITH_UIP6
00292   memcpy(&uip_lladdr.addr, ds2411_id, sizeof(uip_lladdr.addr));
00293   
00294 
00295 
00296 
00297   
00298   queuebuf_init();
00299   NETSTACK_RDC.init();
00300   NETSTACK_MAC.init();
00301   NETSTACK_NETWORK.init();
00302 
00303   printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00304          NETSTACK_MAC.name, NETSTACK_RDC.name,
00305          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0 ? 1:
00306                          NETSTACK_RDC.channel_check_interval()),
00307          RF_CHANNEL);
00308 
00309   process_start(&tcpip_process, NULL);
00310 
00311   printf("Tentative link-local IPv6 address ");
00312   {
00313     uip_ds6_addr_t *lladdr;
00314     int i;
00315     lladdr = uip_ds6_get_link_local(-1);
00316     for(i = 0; i < 7; ++i) {
00317       printf("%02x%02x:", lladdr->ipaddr.u8[i * 2],
00318              lladdr->ipaddr.u8[i * 2 + 1]);
00319     }
00320     printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
00321   }
00322 
00323   if(!UIP_CONF_IPV6_RPL) {
00324     uip_ipaddr_t ipaddr;
00325     int i;
00326     uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0);
00327     uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
00328     uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
00329     printf("Tentative global IPv6 address ");
00330     for(i = 0; i < 7; ++i) {
00331       printf("%02x%02x:",
00332              ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]);
00333     }
00334     printf("%02x%02x\n",
00335            ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]);
00336   }
00337 
00338 #else 
00339 
00340   NETSTACK_RDC.init();
00341   NETSTACK_MAC.init();
00342   NETSTACK_NETWORK.init();
00343 
00344   printf("%s %s, channel check rate %lu Hz, radio channel %u\n",
00345          NETSTACK_MAC.name, NETSTACK_RDC.name,
00346          CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1:
00347                          NETSTACK_RDC.channel_check_interval()),
00348          RF_CHANNEL);
00349 #endif 
00350 
00351 #if !WITH_UIP && !WITH_UIP6
00352   uart1_set_input(serial_line_input_byte);
00353   serial_line_init();
00354 #endif
00355 
00356 #if PROFILE_CONF_ON
00357   profile_init();
00358 #endif 
00359 
00360   leds_off(LEDS_GREEN);
00361 
00362 #if TIMESYNCH_CONF_ENABLED
00363   timesynch_init();
00364   timesynch_set_authority_level((rimeaddr_node_addr.u8[0] << 4) + 16);
00365 #endif 
00366 
00367 #if WITH_UIP
00368   process_start(&tcpip_process, NULL);
00369   process_start(&uip_fw_process, NULL); 
00370   process_start(&slip_process, NULL);
00371 
00372   slip_set_input_callback(set_gateway);
00373 
00374   {
00375     uip_ipaddr_t hostaddr, netmask;
00376 
00377     uip_init();
00378 
00379     uip_ipaddr(&hostaddr, 172,16,
00380                rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]);
00381     uip_ipaddr(&netmask, 255,255,0,0);
00382     uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
00383 
00384     uip_sethostaddr(&hostaddr);
00385     uip_setnetmask(&netmask);
00386     uip_over_mesh_set_net(&hostaddr, &netmask);
00387     
00388     uip_over_mesh_set_gateway_netif(&slipif);
00389     uip_fw_default(&meshif);
00390     uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
00391     printf("uIP started with IP address %d.%d.%d.%d\n",
00392            uip_ipaddr_to_quad(&hostaddr));
00393   }
00394 #endif 
00395 
00396   energest_init();
00397   ENERGEST_ON(ENERGEST_TYPE_CPU);
00398 
00399   watchdog_start();
00400 
00401   print_processes(autostart_processes);
00402   autostart_start(autostart_processes);
00403 
00404   
00405 
00406 
00407 #if DCOSYNCH_CONF_ENABLED
00408   timer_set(&mgt_timer, DCOSYNCH_PERIOD * CLOCK_SECOND);
00409 #endif
00410 
00411   
00412   while(1) {
00413     int r;
00414 #if PROFILE_CONF_ON
00415     profile_episode_start();
00416 #endif 
00417     do {
00418       
00419       watchdog_periodic();
00420       r = process_run();
00421     } while(r > 0);
00422 #if PROFILE_CONF_ON
00423     profile_episode_end();
00424 #endif 
00425 
00426     
00427 
00428 
00429     int s = splhigh();          
00430     
00431     if(process_nevents() != 0 || uart1_active()) {
00432       splx(s);                  
00433     } else {
00434       static unsigned long irq_energest = 0;
00435 
00436 #if DCOSYNCH_CONF_ENABLED
00437       
00438       if(timer_expired(&mgt_timer)) {
00439         watchdog_periodic();
00440         timer_reset(&mgt_timer);
00441         msp430_sync_dco();
00442 #if CC2420_CONF_SFD_TIMESTAMPS
00443         cc2420_arch_sfd_init();
00444 #endif 
00445       }
00446 #endif
00447       
00448       
00449       ENERGEST_OFF(ENERGEST_TYPE_CPU);
00450       ENERGEST_ON(ENERGEST_TYPE_LPM);
00451       
00452 
00453 
00454       energest_type_set(ENERGEST_TYPE_IRQ, irq_energest);
00455       watchdog_stop();
00456       
00457       if (msp430_dco_required) {
00458         _BIS_SR(GIE | CPUOFF); 
00459       } else {
00460         _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); 
00461 
00462 
00463 
00464 
00465 
00466       }
00467       
00468 
00469       dint();
00470       irq_energest = energest_type_time(ENERGEST_TYPE_IRQ);
00471       eint();
00472       watchdog_start();
00473       ENERGEST_OFF(ENERGEST_TYPE_LPM);
00474       ENERGEST_ON(ENERGEST_TYPE_CPU);
00475     }
00476   }
00477 
00478   return 0;
00479 }
00480 
00481 #if LOG_CONF_ENABLED
00482 void
00483 log_message(char *m1, char *m2)
00484 {
00485   printf("%s%s\n", m1, m2);
00486 }
00487 #endif