/*---------------------------------------------------------------------------*/ void eth_dev_init() { if(sixlbr_config_use_raw_ethernet) { eth_fd = eth_alloc(sixlbr_config_eth_device); } else { eth_fd = tap_alloc(sixlbr_config_eth_device); } if(eth_fd == -1) { LOG6LBR_FATAL("eth_dev_init() : %s\n", strerror(errno)); exit(1); } select_set_callback(eth_fd, ð_select_callback); LOG6LBR_INFO("opened device /dev/%s\n", sixlbr_config_eth_device); atexit(cleanup); signal(SIGHUP, sigcleanup); signal(SIGTERM, sigcleanup); signal(SIGINT, sigcleanup); ifconf(sixlbr_config_eth_device); #if !CETIC_6LBR_ONE_ITF if(sixlbr_config_use_raw_ethernet) { #endif fetch_mac(eth_fd, sixlbr_config_eth_device, ð_mac_addr); LOG6LBR_ETHADDR(INFO, ð_mac_addr, "Eth MAC address : "); eth_mac_addr_ready = 1; #if !CETIC_6LBR_ONE_ITF } #endif }
void tun_init() { setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ if(use_raw_ethernet) { tunfd = eth_alloc(slip_config_tundev); } else { tunfd = tun_alloc(slip_config_tundev); } if(tunfd == -1) { LOG6LBR_FATAL("tun_alloc() : %s\n", strerror(errno)); exit(1); } select_set_callback(tunfd, &tun_select_callback); LOG6LBR_INFO("opened device /dev/%s\n", slip_config_tundev); atexit(cleanup); signal(SIGHUP, sigcleanup); signal(SIGTERM, sigcleanup); signal(SIGINT, sigcleanup); ifconf(slip_config_tundev); #if !CETIC_6LBR_ONE_ITF if(use_raw_ethernet) { #endif fetch_mac(tunfd, slip_config_tundev, ð_mac_addr); LOG6LBR_ETHADDR(INFO, ð_mac_addr, "Eth MAC address : "); eth_mac_addr_ready = 1; #if !CETIC_6LBR_ONE_ITF } #endif }
/*---------------------------------------------------------------------------*/ static void fetch_mac(int fd, char const *dev, ethaddr_t * eth_mac_addr) { struct ifaddrs *ifap, *ifaptr; unsigned char *ptr; int found = 0; if(getifaddrs(&ifap) == 0) { for(ifaptr = ifap; ifaptr != NULL; ifaptr = (ifaptr)->ifa_next) { if(!strcmp((ifaptr)->ifa_name, dev) && (((ifaptr)->ifa_addr)->sa_family == AF_LINK)) { ptr = (unsigned char *)LLADDR((struct sockaddr_dl *)(ifaptr)->ifa_addr); memcpy(eth_mac_addr, ptr, 6); //(*eth_mac_addr)[5] = 7; found = 1; break; } } freeifaddrs(ifap); } if(!found) { LOG6LBR_FATAL("Could not find mac address for %s\n", dev); exit(1); } }
void nvm_data_write(void) { long err; int retry = 4; while (retry > 0 ) { LOG6LBR_INFO("Flashing 6LBR NVM\n"); err = rom_util_page_erase(CETIC_6LBR_NVM_ADDRESS, CETIC_6LBR_NVM_SIZE); if ( err != 0 ) { LOG6LBR_ERROR("erase error : %ld\n", err); } rom_util_program_flash( (uint32_t*)&nvm_data, CETIC_6LBR_NVM_ADDRESS, (sizeof(nvm_data_t)/4+1)*4); if ( err != 0 ) { LOG6LBR_ERROR("write error : %ld\n", err); } if(rom_util_memcmp( (void *)&nvm_data, (void *)CETIC_6LBR_NVM_ADDRESS, sizeof(nvm_data_t)) == 0) { break; } LOG6LBR_ERROR("verify NVM failed, retry\n"); retry--; } if(retry == 0) { LOG6LBR_FATAL("Could not program 6LBR NVM !\n"); } else { LOG6LBR_INFO("Flashing 6LBR NVM done\n"); } }
/*---------------------------------------------------------------------------*/ void eth_dev_output(uint8_t * data, int len) { if(write(eth_fd, data, len) != len) { LOG6LBR_FATAL("write() : %s\n", strerror(errno)); exit(1); } LOG6LBR_PRINTF(PACKET, TAP_OUT, "write: %d\n", len); }
/*---------------------------------------------------------------------------*/ static int eth_dev_input(unsigned char *data, int maxlen) { int size; if((size = read(eth_fd, data, maxlen)) == -1) { LOG6LBR_FATAL("read() : %s\n", strerror(errno)); exit(1); } LOG6LBR_PRINTF(PACKET, TAP_IN, "read: %d\n", size); return size; }
static int eth_alloc(const char *eth_dev) { int sockfd; if((sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) { LOG6LBR_FATAL("socket() : %s\n", strerror(errno)); exit(1); } memset(&if_idx, 0, sizeof(struct ifreq)); strncpy(if_idx.ifr_name, eth_dev, IFNAMSIZ - 1); if(ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) { LOG6LBR_FATAL("ioctl() : %s\n", strerror(errno)); exit(1); } struct sockaddr_ll sll; sll.sll_family = AF_PACKET; sll.sll_ifindex = if_idx.ifr_ifindex; sll.sll_protocol = htons(ETH_P_ALL); if(bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) < 0) { LOG6LBR_FATAL("bind() : %s\n", strerror(errno)); exit(1); } struct packet_mreq mr; memset(&mr, 0, sizeof(mr)); mr.mr_ifindex = if_idx.ifr_ifindex; mr.mr_type = PACKET_MR_PROMISC; if(setsockopt(sockfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) { LOG6LBR_FATAL("setsockopt() : %s\n", strerror(errno)); exit(1); } return sockfd; }
/*---------------------------------------------------------------------------*/ static void slip_send(int fd, unsigned char c) { if(slip_end >= sizeof(slip_buf)) { LOG6LBR_FATAL("slip_send overflow\n"); exit(1); } slip_buf[slip_end] = c; slip_end++; slip_sent++; if(c == SLIP_END) { /* Full packet received. */ slip_packet_count++; if(slip_packet_end == 0) { slip_packet_end = slip_end; } } }
/*---------------------------------------------------------------------------*/ void native_config_load(config_level_t config_level) { int result; if (config_file_name) { LOG6LBR_INFO("Loading configuration : %s\n",config_file_name); result = ini_parse(config_file_name, native_config_handler, &config_level); if (result < 0) { LOG6LBR_WARN("Can not open %s : %s\n", config_file_name, strerror(errno)); } else if (result) { LOG6LBR_FATAL("Syntax error in %s at line %d\n", config_file_name, result); exit(1); } } else { LOG6LBR_WARN("No configuration file specified\n"); } }
/*---------------------------------------------------------------------------*/ void slip_flushbuf(int fd) { int n; if(slip_empty()) { return; } n = write(fd, slip_buf + slip_begin, slip_packet_end - slip_begin); if(n == -1 && errno != EAGAIN) { LOG6LBR_FATAL("slip_flushbuf::write() : %s\n", strerror(errno)); exit(1); } else if(n == -1) { PROGRESS("Q"); /* Outqueue is full! */ } else { slip_begin += n; if(slip_begin == slip_packet_end) { slip_packet_count--; if(slip_end > slip_packet_end) { memcpy(slip_buf, slip_buf + slip_packet_end, slip_end - slip_packet_end); } slip_end -= slip_packet_end; slip_begin = slip_packet_end = 0; if(slip_end > 0) { /* Find end of next slip packet */ for(n = 1; n < slip_end; n++) { if(slip_buf[n] == SLIP_END) { slip_packet_end = n + 1; break; } } /* a delay between slip packets to avoid losing data */ if(send_delay > 0) { timer_set(&send_delay_timer, send_delay); } } } } }
/*---------------------------------------------------------------------------*/ static void ifconf(const char *eth_dev) { if(sixlbr_config_ifup_script != NULL) { if(access(sixlbr_config_ifup_script, R_OK | X_OK) == 0) { LOG6LBR_INFO("Running 6lbr-ifup script '%s'\n", sixlbr_config_ifup_script); int status = ssystem("%s %s %s 2>&1", sixlbr_config_ifup_script, sixlbr_config_use_raw_ethernet ? "raw" : "tap", sixlbr_config_eth_device); if(status != 0) { LOG6LBR_FATAL("6lbr-ifup script returned an error, aborting...\n"); exit(1); } } else { LOG6LBR_ERROR("Could not access %s : %s\n", sixlbr_config_ifup_script, strerror(errno)); } } else { LOG6LBR_INFO("No 6lbr-up script specified\n"); } }
/*---------------------------------------------------------------------------*/ static int eth_alloc(const char *eth_dev) { LOG6LBR_FATAL("RAW Ethernet mode not supported\n"); exit(1); }
/*---------------------------------------------------------------------------*/ static void sigcleanup(int signo) { LOG6LBR_FATAL("signal %d\n", signo); exit(1); /* exit(0) will call cleanup() */ }
/*---------------------------------------------------------------------------*/ int slip_config_handle_arguments(int argc, char **argv) { const char *prog; signed char c; int baudrate = -2; prog = argv[0]; while((c = getopt(argc, argv, "c:B:H:D:L:S:hs:t:v::d::a:p:rRfU:D:w:W:P:C:n:o:m:yY")) != -1) { switch (c) { case 'c': sixlbr_config_nvm_file = optarg; break; case 'o': sixlbr_config_config_file_name = optarg; break; case 'B': baudrate = atoi(optarg); break; case 'H': sixlbr_config_slip_flowcontrol = 1; break; #if !LOG6LBR_STATIC case 'L': if (optarg) { Log6lbr_level = atoi(optarg) * 10; } else { Log6lbr_level = Log6lbr_Level_DEFAULT; } break; case 'S': if (optarg) { Log6lbr_services = strtol(optarg, NULL, 16); } else { Log6lbr_services = Log6lbr_Service_DEFAULT; } break; #endif case 's': if(strncmp("/dev/", optarg, 5) == 0) { sixlbr_config_slip_device = optarg + 5; } else { sixlbr_config_slip_device = optarg; } break; case 't': if(strncmp("/dev/", optarg, 5) == 0) { strncpy(sixlbr_config_eth_device, optarg + 5, sizeof(sixlbr_config_eth_device)); } else { strncpy(sixlbr_config_eth_device, optarg, sizeof(sixlbr_config_eth_device)); } break; case 'a': sixlbr_config_slip_host = optarg; break; case 'p': sixlbr_config_slip_port = optarg; break; case 'd': sixlbr_config_eth_basedelay = 10; if(optarg) sixlbr_config_eth_basedelay = atoi(optarg); break; case 'r': sixlbr_config_use_raw_ethernet = 1; break; case 'R': sixlbr_config_use_raw_ethernet = 0; break; case 'f': sixlbr_config_ethernet_has_fcs = 1; break; case 'U': sixlbr_config_ifup_script = optarg; break; case 'D': sixlbr_config_ifdown_script = optarg; break; case 'w': sixlbr_config_www_root = optarg; break; case 'v': printf("Warning: -v option is deprecated, use -L and -S instead\n"); break; case 'P': sixlbr_config_watchdog_interval = atoi(optarg); break; case 'W': sixlbr_config_watchdog_file_name = optarg; break; case 'C': sixlbr_config_ip_file_name = optarg; break; case 'm': sixlbr_config_plugins = optarg; break; case 'n': sixlbr_config_node_config_file_name = optarg; break; case 'y': sixlbr_config_slip_dtr_rts_set = 0; break; case 'Y': sixlbr_config_slip_dtr_rts_set = 1; break; case '?': case 'h': default: fprintf(stderr, "Options are:\n"); fprintf(stderr, " -B baudrate Slip-radio baudrate (default 115200)\n"); fprintf(stderr, " -H Hardware CTS/RTS flow control (default disabled)\n"); fprintf(stderr, " -s siodev Serial device (default /dev/ttyUSB0)\n"); fprintf(stderr, " -a host Connect via TCP to server at <host>\n"); fprintf(stderr, " -p port Connect via TCP to server at <host>:<port>\n"); fprintf(stderr, " -t dev Name of interface\n"); fprintf(stderr, " -r Use Raw Ethernet interface\n"); fprintf(stderr, " -R Use Tap Ethernet interface\n"); fprintf(stderr, " -f Raw Ethernet frames contains FCS\n"); fprintf(stderr, " -d[basedelay] Minimum delay between outgoing SLIP packets.\n"); fprintf(stderr, " Actual delay is basedelay*(#6LowPAN fragments) milliseconds.\n"); fprintf(stderr, " -d is equivalent to -d10.\n"); fprintf(stderr, " -L[level] Log level\n"); fprintf(stderr, " -S[services] Log services\n"); fprintf(stderr, " -c conf Configuration file (nvm file)\n"); fprintf(stderr, " -U script Interface up configuration script\n"); fprintf(stderr, " -D script Interface down configuration script\n"); exit(1); break; } } argc -= optind - 1; argv += optind - 1; if(argc > 1) { LOG6LBR_FATAL( "usage: %s [-B baudrate] [-H] [-L log] [-S services] [-s siodev] [-t dev] [-d delay] [-a serveraddress] [-p serverport] [-c conf] [-U ifup] [-D ifdown]", prog); exit(1); } switch (baudrate) { case -2: break; /* Use default. */ #ifdef B50 case 50: sixlbr_config_slip_baud_rate = B50; break; #endif #ifdef B75 case 75: sixlbr_config_slip_baud_rate = B75; break; #endif #ifdef B110 case 110: sixlbr_config_slip_baud_rate = B110; break; #endif #ifdef B134 case 134: sixlbr_config_slip_baud_rate = B134; break; #endif #ifdef B150 case 150: sixlbr_config_slip_baud_rate = B150; break; #endif #ifdef B200 case 200: sixlbr_config_slip_baud_rate = B200; break; #endif #ifdef B300 case 300: sixlbr_config_slip_baud_rate = B300; break; #endif #ifdef B600 case 600: sixlbr_config_slip_baud_rate = B600; break; #endif #ifdef B1200 case 1200: sixlbr_config_slip_baud_rate = B1200; break; #endif #ifdef B1800 case 1800: sixlbr_config_slip_baud_rate = B1800; break; #endif #ifdef B2400 case 2400: sixlbr_config_slip_baud_rate = B2400; break; #endif #ifdef B4800 case 4800: sixlbr_config_slip_baud_rate = B4800; break; #endif #ifdef B9600 case 9600: sixlbr_config_slip_baud_rate = B9600; break; #endif #ifdef B19200 case 19200: sixlbr_config_slip_baud_rate = B19200; break; #endif #ifdef B38400 case 38400: sixlbr_config_slip_baud_rate = B38400; break; #endif #ifdef B57600 case 57600: sixlbr_config_slip_baud_rate = B57600; break; #endif #ifdef B115200 case 115200: sixlbr_config_slip_baud_rate = B115200; break; #endif #ifdef B230400 case 230400: sixlbr_config_slip_baud_rate = B230400; break; #endif #ifdef B460800 case 460800: sixlbr_config_slip_baud_rate = B460800; break; #endif #ifdef B500000 case 500000: sixlbr_config_slip_baud_rate = B500000; break; #endif #ifdef B576000 case 576000: sixlbr_config_slip_baud_rate = B576000; break; #endif #ifdef B921600 case 921600: sixlbr_config_slip_baud_rate = B921600; break; #endif #ifdef B1000000 case 1000000: sixlbr_config_slip_baud_rate = B1000000; break; #endif #ifdef B1152000 case 1152000: sixlbr_config_slip_baud_rate = B1152000; break; #endif #ifdef B1500000 case 1500000: sixlbr_config_slip_baud_rate = B1500000; break; #endif #ifdef B2000000 case 2000000: sixlbr_config_slip_baud_rate = B2000000; break; #endif #ifdef B2500000 case 2500000: sixlbr_config_slip_baud_rate = B2500000; break; #endif #ifdef B3000000 case 3000000: sixlbr_config_slip_baud_rate = B3000000; break; #endif #ifdef B3500000 case 3500000: sixlbr_config_slip_baud_rate = B3500000; break; #endif #ifdef B4000000 case 4000000: sixlbr_config_slip_baud_rate = B4000000; break; #endif default: LOG6LBR_FATAL("unknown baudrate %d", baudrate); exit(1); break; } return 1; }
/*---------------------------------------------------------------------------*/ void slip_init(void) { setvbuf(stdout, NULL, _IOLBF, 0); /* Line buffered output. */ if(slip_config_host != NULL) { if(slip_config_port == NULL) { slip_config_port = "60001"; } slipfd = connect_to_server(slip_config_host, slip_config_port); if(slipfd == -1) { LOG6LBR_FATAL("can't connect to %s:%s\n", slip_config_host, slip_config_port); exit(1); } } else if(slip_config_siodev != NULL) { if(strcmp(slip_config_siodev, "null") == 0) { /* Disable slip */ return; } slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK); if(slipfd == -1) { LOG6LBR_FATAL( "can't open siodev /dev/%s : %s\n", slip_config_siodev, strerror(errno)); exit(1); } } else { static const char *siodevs[] = { "ttyUSB0", "cuaU0", "ucom0" /* linux, fbsd6, fbsd5 */ }; int i; for(i = 0; i < 3; i++) { slip_config_siodev = siodevs[i]; slipfd = devopen(slip_config_siodev, O_RDWR | O_NONBLOCK); if(slipfd != -1) { break; } } if(slipfd == -1) { LOG6LBR_FATAL("can't open siodev : %s\n", strerror(errno)); exit(1); } } select_set_callback(slipfd, &slip_callback); if(slip_config_host != NULL) { LOG6LBR_INFO("SLIP opened to %s:%s\n", slip_config_host, slip_config_port); } else { LOG6LBR_INFO("SLIP started on /dev/%s\n", slip_config_siodev); stty_telos(slipfd); } timer_set(&send_delay_timer, 0); slip_send(slipfd, SLIP_END); inslip = fdopen(slipfd, "r"); if(inslip == NULL) { LOG6LBR_FATAL("main: fdopen: %s\n", strerror(errno)); exit(1); } }
/*---------------------------------------------------------------------------*/ static void stty_telos(int fd) { struct termios tty; speed_t speed = slip_config_b_rate; int i; if(tcflush(fd, TCIOFLUSH) == -1) { LOG6LBR_FATAL("tcflush() : %s\n", strerror(errno)); exit(1); } if(tcgetattr(fd, &tty) == -1) { LOG6LBR_FATAL("tcgetattr() : %s\n", strerror(errno)); exit(1); } cfmakeraw(&tty); /* Nonblocking read. */ tty.c_cc[VTIME] = 0; tty.c_cc[VMIN] = 0; if(slip_config_flowcontrol) { tty.c_cflag |= CRTSCTS; } else { tty.c_cflag &= ~CRTSCTS; } tty.c_cflag &= ~HUPCL; tty.c_cflag &= ~CLOCAL; cfsetispeed(&tty, speed); cfsetospeed(&tty, speed); if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) { LOG6LBR_FATAL("tcsetattr() : %s\n", strerror(errno)); exit(1); } #if 1 /* Nonblocking read and write. */ /* if(fcntl(fd, F_SETFL, O_NONBLOCK) == -1) err(1, "fcntl"); */ tty.c_cflag |= CLOCAL; if(tcsetattr(fd, TCSAFLUSH, &tty) == -1) { LOG6LBR_FATAL("tcsetattr() : %s\n", strerror(errno)); exit(1); } i = TIOCM_DTR; if(ioctl(fd, TIOCMBIS, &i) == -1) { LOG6LBR_FATAL("ioctl() : %s\n", strerror(errno)); exit(1); } #endif usleep(10 * 1000); /* Wait for hardware 10ms. */ /* Flush input and output buffers. */ if(tcflush(fd, TCIOFLUSH) == -1) { LOG6LBR_FATAL("tcflush() : %s\n", strerror(errno)); exit(1); } }
PROCESS_THREAD(cetic_6lbr_process, ev, data) { static struct etimer timer; static int addr_number; PROCESS_BEGIN(); /* Step 0: Basic infrastructure initialization */ LOG6LBR_NOTICE("Starting 6LBR version " CETIC_6LBR_VERSION " (" CONTIKI_VERSION_STRING ")\n"); //Turn off radio until 6LBR is properly configured NETSTACK_MAC.off(0); cetic_6lbr_restart_event = process_alloc_event(); cetic_6lbr_reload_event = process_alloc_event(); cetic_6lbr_startup = clock_seconds(); #if CETIC_6LBR_MULTI_RADIO network_itf_init(); #endif /* Step 1: Platform specific initialization */ platform_init(); /* Step 2: Register configuration hooks and set default configuration */ #if CETIC_6LBR_NODE_INFO node_info_config(); #endif /* Step 3: Load configuration from NVM and configuration file */ platform_load_config(CONFIG_LEVEL_BOOT); #if !LOG6LBR_STATIC if(nvm_data.log_level != 0xFF) { Log6lbr_level = nvm_data.log_level; Log6lbr_services = nvm_data.log_services; } LOG6LBR_NOTICE("Log level: %d (services: %x)\n", Log6lbr_level, Log6lbr_services); #else LOG6LBR_NOTICE("Log level: %d (services: %x)\n", LOG6LBR_LEVEL, LOG6LBR_SERVICE_DEFAULT); #endif /* Step 4: Initialize radio and network interfaces */ #if CETIC_6LBR_FRAMER_WRAPPER framer_wrapper_init(); #endif #if CETIC_6LBR_MAC_WRAPPER mac_wrapper_init(); #endif #if CETIC_6LBR_MULTI_RADIO CETIC_6LBR_MULTI_RADIO_DEFAULT_MAC.init(); #endif #if !CETIC_6LBR_ONE_ITF platform_radio_init(); while(!radio_ready) { PROCESS_PAUSE(); } #endif eth_drv_init(); while(!ethernet_ready) { PROCESS_PAUSE(); } //Turn on radio and keep it always on NETSTACK_MAC.off(1); /* Step 5: Initialize Network stack */ #if CETIC_6LBR_LLSEC_WRAPPER #if CETIC_6LBR_WITH_ADAPTIVESEC llsec_strategy_wrapper_init(); #endif llsec_wrapper_init(); #endif #if CETIC_6LBR_MULTICAST_WRAPPER multicast_wrapper_init(); #endif //6LoWPAN init memcpy(addr_contexts[0].prefix, nvm_data.wsn_6lowpan_context_0, sizeof(addr_contexts[0].prefix)); //clean up any early packet uip_len = 0; process_start(&tcpip_process, NULL); PROCESS_PAUSE(); /* Step 6: Configure network interfaces */ packet_filter_init(); cetic_6lbr_init(); //Wait result of DAD on 6LBR addresses addr_number = uip_ds6_get_addr_number(-1); LOG6LBR_INFO("Checking addresses duplication\n"); etimer_set(&timer, CLOCK_SECOND); while(uip_ds6_get_addr_number(ADDR_TENTATIVE) > 0) { PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); etimer_set(&timer, CLOCK_SECOND); } //Can not use equality as autoconf address could be created when running DAD if(uip_ds6_get_addr_number(-1) < addr_number) { LOG6LBR_FATAL("Addresses duplication failed\n"); cetic_6lbr_restart_type = CETIC_6LBR_RESTART; platform_restart(); } /* Step 7: Finalize configuration of network interfaces */ cetic_6lbr_init_finalize(); /* Step 8: Initialize 6LBR core and base applications */ platform_load_config(CONFIG_LEVEL_CORE); PROCESS_PAUSE(); #if CETIC_6LBR_WITH_WEBSERVER webserver_init(); #endif #if CETIC_6LBR_NODE_INFO node_info_init(); #endif #if CETIC_6LBR_NODE_CONFIG node_config_init(); #endif /* Step 9: Initialize and configure 6LBR applications */ platform_load_config(CONFIG_LEVEL_BASE); PROCESS_PAUSE(); #if CETIC_6LBR_WITH_UDPSERVER udp_server_init(); #endif #if UDPCLIENT process_start(&udp_client_process, NULL); #endif #if WITH_TINYDTLS dtls_init(); #endif #if WITH_COAPSERVER if((nvm_data.global_flags & CETIC_GLOBAL_DISABLE_COAP_SERVER) == 0) { coap_server_init(); } #endif #if WITH_DTLS_ECHO process_start(&dtls_echo_server_process, NULL); #endif #if CETIC_6LBR_WITH_NVM_PROXY nvm_proxy_init(); #endif #if CETIC_6LBR_WITH_DNS_PROXY dns_proxy_init(); #endif /* Step 10: Finalize platform configuration and load runtime configuration */ platform_finalize(); platform_load_config(CONFIG_LEVEL_APP); LOG6LBR_INFO("CETIC 6LBR Started\n"); PROCESS_WAIT_EVENT_UNTIL(ev == cetic_6lbr_restart_event); etimer_set(&timer, CLOCK_SECOND); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); /* Shutdown 6LBR */ //Turn off radio NETSTACK_MAC.off(0); platform_restart(); PROCESS_END(); }
/* * Read from serial, when we have a packet call slip_packet_input. No output * buffering, input buffered by stdio. */ void serial_input(FILE * inslip) { static unsigned char inbuf[2048]; static int inbufptr = 0; int ret, i; unsigned char c; #ifdef linux ret = fread(&c, 1, 1, inslip); if(ret == -1 || ret == 0) { LOG6LBR_FATAL("read() : %s\n", strerror(errno)); exit(1); } goto after_fread; #endif read_more: if(inbufptr >= sizeof(inbuf)) { LOG6LBR_ERROR("*** dropping large %d byte packet\n", inbufptr); inbufptr = 0; } ret = fread(&c, 1, 1, inslip); #ifdef linux after_fread: #endif if(ret == -1) { LOG6LBR_FATAL("read() : %s\n", strerror(errno)); exit(1); } if(ret == 0) { clearerr(inslip); return; } slip_received++; switch (c) { case SLIP_END: if(inbufptr > 0) { slip_message_received++; LOG6LBR_PRINTF(PACKET, SLIP_IN, "read: %d\n", inbufptr); if (LOG6LBR_COND(DUMP, SLIP_IN)) { printf(" "); for(i = 0; i < inbufptr; i++) { printf("%02x", inbuf[i]); if((i & 3) == 3) printf(" "); if((i & 15) == 15) printf("\n "); } printf("\n"); } if(inbuf[0] == '!') { command_context = CMD_CONTEXT_RADIO; cmd_input(inbuf, inbufptr); } else if(inbuf[0] == '?') { } else if(inbuf[0] == DEBUG_LINE_MARKER) { LOG6LBR_WRITE(INFO, SLIP_DBG, inbuf + 1, inbufptr - 1); } else if(inbuf[0] == 'E' && is_sensible_string(inbuf, inbufptr) ) { LOG6LBR_WRITE(ERROR, GLOBAL, inbuf + 1, inbufptr - 1); LOG6LBR_APPEND(ERROR, GLOBAL, "\n"); } else if(is_sensible_string(inbuf, inbufptr)) { LOG6LBR_WRITE(INFO, SLIP_DBG, inbuf, inbufptr); } else { slip_packet_input(inbuf, inbufptr); } inbufptr = 0; } break; case SLIP_ESC: if(fread(&c, 1, 1, inslip) != 1) { clearerr(inslip); /* Put ESC back and give up! */ ungetc(SLIP_ESC, inslip); return; } switch (c) { case SLIP_ESC_END: c = SLIP_END; break; case SLIP_ESC_ESC: c = SLIP_ESC; break; } /* FALLTHROUGH */ default: inbuf[inbufptr++] = c; break; } goto read_more; }