static uip_ipaddr_t * lookup(uip_ipaddr_t *destipaddr, uip_ipaddr_t *nexthop) { static rimeaddr_t rimeaddr; struct route_entry *route; int i; for(i = 1; i < sizeof(rimeaddr); i++) { rimeaddr.u8[i] = destipaddr->u8[sizeof(*destipaddr) - sizeof(rimeaddr) + i]; } rimeaddr.u8[0] = 0; PRINTF("rimeroute: looking up "); PRINT6ADDR(destipaddr); PRINTF(" with Rime address "); PRINTRIMEADDR((&rimeaddr)); PRINTF("\n"); route = route_lookup(&rimeaddr); if(route == NULL) { process_post(&rimeroute_process, rimeroute_event, &rimeaddr); return NULL; } uip_ip6addr(nexthop, 0xfe80, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_autoconf_set(nexthop, (uip_lladdr_t *)&route->nexthop); PRINTF("rimeroute: "); PRINT6ADDR(destipaddr); PRINTF(" can be reached via "); PRINT6ADDR(nexthop); PRINTF("\n"); return nexthop; }
/*---------------------------------------------------------------------------*/ void uip_netif_addr_add(uip_ipaddr_t *ipaddr, u8_t length, unsigned long vlifetime, uip_netif_type type) { /* check prefix has the right length if we are doing autoconf */ if((type == AUTOCONF) && (length != UIP_DEFAULT_PREFIX_LEN)) { UIP_LOG("Error: UNSUPPORTED PREFIX LENGTH"); return; } /* check if addr does not already exist and find a free entry */ for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; ++i) { if(uip_netif_physical_if.addresses[i].state == NOT_USED){ /* * Copying address * If we are doing autoconf, ipaddr is a prefix, we copy the 128 bits * of it, then overwrite the last 64 bits with the interface ID at * next if statement. * Otherwise ipaddr is an address, we just copy it */ uip_ipaddr_copy(&uip_netif_physical_if.addresses[i].ipaddr, ipaddr); if(type == AUTOCONF) { /* construct address from prefix and layer2 id */ uip_netif_addr_autoconf_set(&uip_netif_physical_if.addresses[i].ipaddr, &uip_lladdr); } /* setting state, type */ uip_netif_physical_if.addresses[i].state = TENTATIVE; uip_netif_physical_if.addresses[i].type = type; /* setting lifetime timer if lieftime is not infinite */ if(vlifetime != 0) { stimer_set(&(uip_netif_physical_if.addresses[i].vlifetime), vlifetime); uip_netif_physical_if.addresses[i].is_infinite = 0; } else { uip_netif_physical_if.addresses[i].is_infinite = 1; } PRINTF("Created new address"); PRINT6ADDR(&uip_netif_physical_if.addresses[i].ipaddr); PRINTF("for interface\n"); /* schedule DAD */ uip_netif_sched_dad(&uip_netif_physical_if.addresses[i]); return; } } /* If we did not find space, log */ UIP_LOG("ADDRESS LIST FULL"); return; }
/*---------------------------------------------------------------------------*/ static int send_packet(void) { const rimeaddr_t *addr; addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); PRINTF("rime-udp: Sending %d bytes to %d.%d\n", packetbuf_totlen(), addr->u8[RIMEADDR_SIZE-2], addr->u8[RIMEADDR_SIZE-1]); if(rimeaddr_cmp(&rimeaddr_null, addr)) { uip_udp_packet_send(broadcast_conn, packetbuf_hdrptr(), packetbuf_totlen()); } else { uip_ip6addr(&unicast_conn->ripaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_autoconf_set(&unicast_conn->ripaddr, (uip_lladdr_t *)addr); uip_udp_packet_send(unicast_conn, packetbuf_hdrptr(), packetbuf_totlen()); uip_create_unspecified(&unicast_conn->ripaddr); } return 1; }
/*---------------------------------------------------------------------------*/ void uip_netif_init(void) { /* INITIALIZE INTERFACE (default values for now) */ uip_netif_physical_if.link_mtu = UIP_LINK_MTU; uip_netif_physical_if.cur_hop_limit = UIP_TTL; uip_netif_physical_if.base_reachable_time = UIP_ND6_REACHABLE_TIME; uip_netif_physical_if.reachable_time = uip_netif_compute_reachable_time(); uip_netif_physical_if.retrans_timer = UIP_ND6_RETRANS_TIMER; uip_netif_physical_if.dup_addr_detect_transmit = 1; /* * STATELESS AUTOCONFIGURATION of the link local address. We set it to * infinite (this will become really true once DAD succeeds) */ uip_ip6addr(&(uip_netif_physical_if.addresses[0].ipaddr), 0xfe80,0,0,0,0,0,0,0); uip_netif_addr_autoconf_set(&(uip_netif_physical_if.addresses[0].ipaddr), &uip_lladdr); uip_netif_physical_if.addresses[0].state = TENTATIVE; uip_netif_physical_if.addresses[0].type = MANUAL; uip_netif_physical_if.addresses[0].is_infinite = 1; /* set all other addresses to NOT_USED initialy */ for(i = 1; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) uip_netif_physical_if.addresses[i].state = NOT_USED; uip_ip6addr_u8(&(uip_netif_physical_if.solicited_node_mcastaddr), 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, uip_lladdr.addr[UIP_LLADDR_LEN - 3], uip_lladdr.addr[UIP_LLADDR_LEN - 2], uip_lladdr.addr[UIP_LLADDR_LEN - 1]); /* Start DAD */ uip_netif_sched_dad(&(uip_netif_physical_if.addresses[0])); /* Find router (send rs to all-routers multicast group)) */ uip_netif_sched_send_rs(); /* Reset the timer */ etimer_set(&uip_netif_timer_periodic, CLOCK_SECOND); }
/*---------------------------------------------------------------------------*/ static void send_packet(mac_callback_t sent_callback, void *ptr) { const rimeaddr_t *addr; addr = packetbuf_addr(PACKETBUF_ADDR_RECEIVER); PRINTF("rime-udp: Sending %d bytes to %d.%d\n", packetbuf_totlen(), addr->u8[0], addr->u8[1]); if(rimeaddr_cmp(&rimeaddr_null, addr)) { uip_udp_packet_send(broadcast_conn, packetbuf_hdrptr(), packetbuf_totlen()); mac_call_sent_callback(sent_callback, ptr, MAC_TX_OK, 1); } else { uip_ip6addr(&unicast_conn->ripaddr, 0xfe80, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_autoconf_set(&unicast_conn->ripaddr, (uip_lladdr_t *)addr); uip_udp_packet_send(unicast_conn, packetbuf_hdrptr(), packetbuf_totlen()); uip_create_unspecified(&unicast_conn->ripaddr); } return; }
/*---------------------------------------------------------------------------*/ int main(void) { process_init(); procinit_init(); ctimer_init(); autostart_start(autostart_processes); #if !UIP_CONF_IPV6 uip_ipaddr_t addr; uip_ipaddr(&addr, 192,168,1,2); printf("IP Address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_sethostaddr(&addr); uip_ipaddr(&addr, 255,255,255,0); printf("Subnet Mask: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_setnetmask(&addr); uip_ipaddr(&addr, 192,168,1,1); printf("Def. Router: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&addr)); uip_setdraddr(&addr); #else { uip_ipaddr_t ipaddr; uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_autoconf_set(&ipaddr, &uip_lladdr); uip_netif_addr_add(&ipaddr, 16, 0, TENTATIVE); } #endif /* Make standard output unbuffered. */ setvbuf(stdout, (char *)NULL, _IONBF, 0); while(1) { fd_set fds; int n; struct timeval tv; n = process_run(); /* if(n > 0) { printf("%d processes in queue\n"); }*/ tv.tv_sec = 0; tv.tv_usec = 1; FD_ZERO(&fds); FD_SET(STDIN_FILENO, &fds); select(1, &fds, NULL, NULL, &tv); if(FD_ISSET(STDIN_FILENO, &fds)) { char c; if(read(STDIN_FILENO, &c, 1) > 0) { serial_line_input_byte(c); } } etimer_request_poll(); } return 0; }
/*------Done in a subroutine to keep main routine stack usage small--------*/ void initialize(void) { //calibrate_rc_osc_32k(); //CO: Had to comment this out #ifdef RAVEN_LCD_INTERFACE /* First rs232 port for Raven 3290 port */ rs232_init(RS232_PORT_0, USART_BAUD_38400,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Set input handler for 3290 port */ rs232_set_input(0,raven_lcd_serial_input); #endif /* Second rs232 port for debugging */ rs232_init(RS232_PORT_1, USART_BAUD_57600,USART_PARITY_NONE | USART_STOP_BITS_1 | USART_DATA_BITS_8); /* Redirect stdout to second port */ rs232_redirect_stdout(RS232_PORT_1); clock_init(); printf_P(PSTR("\r\n*******Booting %s*******\r\n"),CONTIKI_VERSION_STRING); /* Initialize process subsystem */ process_init(); #ifdef RF230BB { /* Start radio and radio receive process */ rf230_init(); sicslowpan_init(sicslowmac_init(&rf230_driver)); // ctimer_init(); // sicslowpan_init(lpp_init(&rf230_driver)); // rime_init(sicslowmac_driver.init(&rf230_driver)); // rime_init(lpp_init(&rf230_driver)); /* Set addresses BEFORE starting tcpip process */ rimeaddr_t addr; memset(&addr, 0, sizeof(rimeaddr_t)); AVR_ENTER_CRITICAL_REGION(); eeprom_read_block ((void *)&addr.u8, &mac_address, 8); AVR_LEAVE_CRITICAL_REGION(); memcpy(&uip_lladdr.addr, &addr.u8, 8); rf230_set_pan_addr(IEEE802154_PANID, 0, (uint8_t *)&addr.u8); rf230_set_channel(24); rimeaddr_set_node_addr(&addr); PRINTF("MAC address %x:%x:%x:%x:%x:%x:%x:%x\r\n",addr.u8[0],addr.u8[1],addr.u8[2],addr.u8[3],addr.u8[4],addr.u8[5],addr.u8[6],addr.u8[7]); // uip_ip6addr(&ipprefix, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); // uip_netif_addr_add(&ipprefix, UIP_DEFAULT_PREFIX_LEN, 0, AUTOCONF); // uip_nd6_prefix_add(&ipprefix, UIP_DEFAULT_PREFIX_LEN, 0); // PRINTF("Prefix %x::/%u\r\n",ipprefix.u16[0],UIP_DEFAULT_PREFIX_LEN); #if UIP_CONF_ROUTER rime_init(rime_udp_init(NULL)); uip_router_register(&rimeroute); #endif PRINTF("Driver: %s, Channel: %u\r\n", sicslowmac_driver.name, rf230_get_channel()); } #endif /*RF230BB*/ /* Register initial processes */ procinit_init(); uip_ip6addr_t ipaddr; uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0, AUTOCONF); uip_nd6_prefix_add(&ipaddr, UIP_DEFAULT_PREFIX_LEN, 0); //Give ourselves a prefix init_net(); print_local_addresses(); PRINTF("Starting autostart processes"); /* Autostart processes */ autostart_start(autostart_processes); /*---If using coffee file system create initial web content if necessary---*/ #if COFFEE_FILES int fa = cfs_open( "/index.html", CFS_READ); if (fa<0) { //Make some default web content printf_P(PSTR("No index.html file found, creating upload.html!\r\n")); printf_P(PSTR("Formatting FLASH file system for coffee...")); cfs_coffee_format(); printf_P(PSTR("Done!\r\n")); fa = cfs_open( "/index.html", CFS_WRITE); int r = cfs_write(fa, &"It works!", 9); if (r<0) printf_P(PSTR("Can''t create /index.html!\r\n")); cfs_close(fa); // fa = cfs_open("upload.html"), CFW_WRITE); // <html><body><form action="upload.html" enctype="multipart/form-data" method="post"><input name="userfile" type="file" size="50" /><input value="Upload" type="submit" /></form></body></html> } #endif /*--------------------------Announce the configuration---------------------*/ #define ANNOUNCE_BOOT 1 //adds about 400 bytes to program size #if ANNOUNCE_BOOT #if WEBSERVER uint8_t i; char buf[80]; unsigned int size; eeprom_read_block (buf,server_name, sizeof(server_name)); buf[sizeof(server_name)]=0; printf_P(PSTR("%s"),buf); eeprom_read_block (buf,domain_name, sizeof(domain_name)); buf[sizeof(domain_name)]=0; size=httpd_fs_get_size(); #ifndef COFFEE_FILES printf_P(PSTR(".%s online with fixed %u byte web content\r\n"),buf,size); #elif COFFEE_FILES==1 printf_P(PSTR(".%s online with static %u byte EEPROM file system\r\n"),buf,size); #elif COFFEE_FILES==2 printf_P(PSTR(".%s online with dynamic %u KB EEPROM file system\r\n"),buf,size>>10); #elif COFFEE_FILES==3 printf_P(PSTR(".%s online with static %u byte program memory file system\r\n"),buf,size); #elif COFFEE_FILES==4 printf_P(PSTR(".%s online with dynamic %u KB program memory file system\r\n"),buf,size>>10); #endif /* Add prefixes for testing */ #if 0 { uip_ip6addr_t ipaddr; uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); uip_netif_addr_autoconf_set(&ipaddr, &uip_lladdr); uip_netif_addr_add(&ipaddr, 16, 0, TENTATIVE); } #endif for(i = 0; i < UIP_CONF_NETIF_MAX_ADDRESSES; i ++) { if(uip_netif_physical_if.addresses[i].state != NOT_USED) { httpd_cgi_sprint_ip6(*(uip_ipaddr_t*)&uip_netif_physical_if.addresses[i],buf); printf_P(PSTR("IPv6 Address: %s\r\n"),buf); } } #else printf_P(PSTR("Online\r\n")); #endif /* WEBSERVER */ #endif /* ANNOUNCE_BOOT */ }