static void settings_save_callback(u16 sender_id, u8 len, u8 msg[], void* context) { int f = cfs_open(SETTINGS_FILE, CFS_WRITE); const char *sec = NULL; char buf[128]; int i; (void)sender_id; (void) context; (void)len; (void)msg; if (f == -1) { log_error("Error opening config file!\n"); return; } for (struct setting *s = settings_head; s; s = s->next) { /* Skip unchanged parameters */ if (!s->dirty) continue; if ((sec == NULL) || (strcmp(s->section, sec) != 0)) { /* New section, write section header */ sec = s->section; i = snprintf(buf, sizeof(buf), "[%s]\n", sec); if (cfs_write(f, buf, i) != i) { log_error("Error writing to config file!\n"); } } /* Write setting */ i = snprintf(buf, sizeof(buf), "%s=", s->name); i += s->type->to_string(s->type->priv, &buf[i], sizeof(buf) - i - 1, s->addr, s->len); buf[i++] = '\n'; if (cfs_write(f, buf, i) != i) { log_error("Error writing to config file!\n"); } } cfs_close(f); log_info("Wrote settings to config file.\n"); }
/*---------------------------------------------------------------------------*/ static int read_chunk(struct rucb_conn *c, int offset, char *to, int maxsize) { int ret; if(fd < 0) { /* No file, send EOF */ leds_off(LEDS_GREEN); return 0; } cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_read(fd, to, maxsize); PRINTF("read_chunk %d bytes at %d\n", ret, offset); if(ret < maxsize) { PRINTF("read_chunk DONE\n"); cfs_close(fd); fd = -1; } return ret; }
static void almanac_callback(u16 sender_id, u8 len, u8 msg[], void* context) { (void)sender_id; (void)len; (void) context; almanac_t *new_almanac = (almanac_t*)msg; log_info("Received alamanc for PRN %02d\n", new_almanac->prn); memcpy(&almanac[new_almanac->prn-1], new_almanac, sizeof(almanac_t)); int fd = cfs_open("almanac", CFS_WRITE); if (fd != -1) { cfs_seek(fd, (new_almanac->prn-1)*sizeof(almanac_t), CFS_SEEK_SET); if (cfs_write(fd, new_almanac, sizeof(almanac_t)) != sizeof(almanac_t)) { log_error("Error writing to almanac file\n"); } else { log_info("Saved almanac to flash\n"); } cfs_close(fd); } else { log_error("Error opening almanac file\n"); } }
/*---------------------------------------------------------------------------*/ static void handle_get_command(void) { int fd = 0; fd = cfs_open("cp", CFS_READ); if(fd < 0) { printf("ERROR: No file access (get)\n"); } else { PRINTF_COMMAND("GET:START\n"); char data[8]; int offset=0, size=0, read=8; unsigned short crc = 0; cfs_seek(fd, offset, CFS_SEEK_SET); while (read == 8) { int i; /*if(offset != cfs_seek(fd, offset, CFS_SEEK_SET)) { printf("bad seek, breaking\n"); break; }*/ read = cfs_read(fd, data, 8); size += read; printf("%04i: ", offset); /*REMOVE*/ for (i=0; i < read; i++) { crc = crc16_add((uint8_t) data[i], crc); printf("%02x", (uint8_t) (0xff&data[i])); } printf("\n"); offset += 8; } PRINTF_COMMAND("GET:DONE CRC=%u\n", crc); cfs_close(fd); } }
/*---------------------------------------------------------------------------*/ static void request_recv(struct runicast_conn *c, rimeaddr_t *from, uint8_t seqno) { const char *filename; uint8_t seq; if(packetbuf_datalen() < 2) { /* Bad filename, ignore request */ printf("download: bad filename request (null)\n"); return; } seq = ((uint8_t *)packetbuf_dataptr())[0]; if(seq == req_last_seq) { PRINTF("download: ignoring duplicate request\n"); return; } req_last_seq = seq; filename = ((char *)packetbuf_dataptr()) + 1; PRINTF("file requested: '%s'\n", filename); /* Initiate file transfer */ leds_on(LEDS_GREEN); if(fd >= 0) { cfs_close(fd); } fd = cfs_open(filename, CFS_READ); if(fd < 0) { printf("download: bad filename request (no read access): %s\n", filename); } else { PRINTF("download: sending file: %s\n", filename); } rucb_close(&rucb); rucb_open(&rucb, RUCB_CHANNEL, &rucb_call); rucb_send(&rucb, from); }
void manage_acq_setup() { for (u8 prn=0; prn<32; prn++) { acq_prn_param[prn].state = ACQ_PRN_ACQUIRING; for (enum acq_hint hint = 0; hint < ACQ_HINT_NUM; hint++) acq_prn_param[prn].score[hint] = 0; acq_prn_param[prn].dopp_hint_low = ACQ_FULL_CF_MIN; acq_prn_param[prn].dopp_hint_high = ACQ_FULL_CF_MAX; } int fd = cfs_open("almanac", CFS_READ); if (fd != -1) { cfs_read(fd, almanac, 32*sizeof(almanac_t)); log_info("Loaded almanac from flash\n"); cfs_close(fd); } else { log_info("No almanac file present in flash, create an empty one\n"); cfs_coffee_reserve("almanac", 32*sizeof(almanac_t)); cfs_coffee_configure_log("almanac", 256, sizeof(almanac_t)); for (u8 prn=0; prn<32; prn++) { almanac[prn].valid = 0; } } sbp_register_cbk( SBP_MSG_ALMANAC, &almanac_callback, &almanac_callback_node ); chThdCreateStatic( wa_manage_acq_thread, sizeof(wa_manage_acq_thread), MANAGE_ACQ_THREAD_PRIORITY, manage_acq_thread, NULL ); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_checkpoint_process, ev, data) { int fd = 0; PROCESS_BEGIN(); /* Make sure file does not already exist */ cfs_remove(data); cfs_coffee_reserve(data, checkpoint_arch_size()); fd = cfs_open(data, CFS_WRITE); if(fd < 0) { shell_output_str(&checkpoint_command, "checkpoint: could not open file for writing: ", data); } else { shell_output_str(&rollback_command, "checkpoint to: ", data); checkpoint_checkpoint(fd); cfs_close(fd); } PROCESS_END(); }
PROCESS_THREAD(checkpoint_button_process, ev, data) { PROCESS_BEGIN(); button_sensor.configure(SENSORS_ACTIVE, 1); while(1) { PROCESS_WAIT_EVENT(); if(ev == sensors_event && data == &button_sensor) { int fd = 0; /* Rollback from Coffee file "cp_wdt" */ fd = cfs_open("cp_wdt", CFS_READ); if(fd >= 0) { checkpoint_rollback(fd); cfs_close(fd); } } } PROCESS_END(); }
/* Write to file callback. * Responds to a SBP_MSG_FILEIO_WRITE_REQUEST message. * * Writes a certain length (up to 255 bytes) at a given offset. Returns a copy * of the original SBP_MSG_FILEIO_WRITE_RESPONSE message to check integrity of * the write. */ static void write_cb(u16 sender_id, u8 len, u8 msg[], void* context) { (void)context; if (sender_id != SBP_SENDER_ID) { log_error("Invalid sender!\n"); return; } if (len < 6) { log_error("Invalid fileio write message!\n"); return; } u32 offset = ((u32)msg[3] << 24) | ((u32)msg[2] << 16) | (msg[1] << 8) | msg[0]; u8 headerlen = 4 + strlen((char*)&msg[4]) + 1; int f = cfs_open((char*)&msg[4], CFS_WRITE); cfs_seek(f, offset, CFS_SEEK_SET); cfs_write(f, msg + headerlen, len - headerlen); cfs_close(f); sbp_send_msg(SBP_MSG_FILEIO_WRITE_RESPONSE, headerlen, msg); }
/*---------------------------------------------------------------------*/ static void write_chunk(struct rudolph0_conn *c, int offset, int flag, uint8_t *data, int datalen) { int fd; leds_toggle(LEDS_YELLOW); if(flag == RUDOLPH0_FLAG_NEWFILE) { printf("+++ rudolph0 new file incoming at %u\n", clock_time()); fd = cfs_open("codeprop.out", CFS_WRITE); if(elfloader_autostart_processes != NULL) { PRINTF("Stopping old programs.\n"); autostart_exit(elfloader_autostart_processes); elfloader_autostart_processes = NULL; } } else { fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); } if(datalen > 0) { int ret; cfs_seek(fd, offset, CFS_SEEK_SET); ret = cfs_write(fd, data, datalen); /* printf("write_chunk wrote %d bytes at %d, %d\n", ret, offset, (unsigned char)data[0]);*/ } cfs_close(fd); if(flag == RUDOLPH0_FLAG_LASTCHUNK) { printf("+++ rudolph0 entire file received at %u\n", clock_time()); start_program(); leds_off(LEDS_YELLOW); } }
char * storage_generate_file(char *prefix, unsigned long size) { static char filename[ATTRIBUTE_NAME_LENGTH + sizeof(".ffff")]; #if !DB_FEATURE_COFFEE int fd; #endif snprintf(filename, sizeof(filename), "%s.%x", prefix, (unsigned)(random_rand() & 0xffff)); #if DB_FEATURE_COFFEE PRINTF("DB: Reserving %lu bytes in %s\n", size, filename); if(cfs_coffee_reserve(filename, size) < 0) { PRINTF("DB: Failed to reserve\n"); return NULL; } return filename; #else fd = cfs_open(filename, CFS_WRITE); cfs_close(fd); return fd < 0 ? NULL : filename; #endif /* DB_FEATURE_COFFEE */ }
db_result_t storage_put_relation(relation_t *rel) { int fd; int r; char *str; unsigned char *last_byte; PRINTF("DB: put_relation(%s)\n", rel->name); cfs_remove(rel->name); #if DB_FEATURE_COFFEE cfs_coffee_reserve(rel->name, DB_COFFEE_CATALOG_SIZE); #endif fd = cfs_open(rel->name, CFS_WRITE | CFS_READ); if(fd < 0) { return DB_STORAGE_ERROR; } r = cfs_write(fd, rel->name, sizeof(rel->name)); if(r != sizeof(rel->name)) { cfs_close(fd); cfs_remove(rel->name); return DB_STORAGE_ERROR; } if(rel->tuple_filename[0] == '\0') { str = storage_generate_file("tuple", DB_COFFEE_RESERVE_SIZE); if(str == NULL) { cfs_close(fd); cfs_remove(rel->name); return DB_STORAGE_ERROR; } strncpy(rel->tuple_filename, str, sizeof(rel->tuple_filename) - 1); rel->tuple_filename[sizeof(rel->tuple_filename) - 1] = '\0'; } /* * Encode the last byte to ensure that the filename is not * null-terminated. This will make the Coffee FS determine * the correct length when re-opening the file. */ last_byte = (unsigned char *)&rel->tuple_filename[sizeof(rel->tuple_filename) - 1]; *last_byte ^= ROW_XOR; r = cfs_write(fd, rel->tuple_filename, sizeof(rel->tuple_filename)); *last_byte ^= ROW_XOR; if(r != sizeof(rel->tuple_filename)) { cfs_close(fd); cfs_remove(rel->tuple_filename); return DB_STORAGE_ERROR; } PRINTF("DB: Saved relation %s\n", rel->name); cfs_close(fd); return DB_OK; }
/*------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("\n*******Booting %s*******\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\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\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\n", sicslowmac_driver.name, rf230_get_channel()); } #endif /*RF230BB*/ /* Register initial processes */ procinit_init(); /* Autostart processes */ autostart_start(autostart_processes); //Give ourselves a prefix // init_net(); /*---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!\n")); printf_P(PSTR("Formatting FLASH file system for coffee...")); cfs_coffee_format(); printf_P(PSTR("Done!\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!\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---------------------*/ #if WEBSERVER 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\n"),buf,size); #elif COFFEE_FILES==1 printf_P(PSTR(".%s online with static %u byte EEPROM file system\n"),buf,size); #elif COFFEE_FILES==2 printf_P(PSTR(".%s online with dynamic %u KB EEPROM file system\n"),buf,size>>10); #elif COFFEE_FILES==3 printf_P(PSTR(".%s online with static %u byte program memory file system\n"),buf,size); #elif COFFEE_FILES==4 printf_P(PSTR(".%s online with dynamic %u KB program memory file system\n"),buf,size>>10); #endif #else printf_P(PSTR("Online\n")); #endif /* WEBSERVER */ }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(shell_read_process, ev, data) { static int fd = 0; static int block_size = MAX_BLOCKSIZE; char *next; char filename[MAX_FILENAME_LEN]; int len; int offset = 0; char buf[MAX_BLOCKSIZE]; struct shell_input *input; PROCESS_EXITHANDLER(cfs_close(fd)); PROCESS_BEGIN(); if(data != NULL) { next = strchr(data, ' '); if(next == NULL) { strncpy(filename, data, sizeof(filename)); } else { len = (int)(next - (char *)data); if(len <= 0) { shell_output_str(&read_command, "read: filename too short: ", data); PROCESS_EXIT(); } if(len > MAX_FILENAME_LEN) { shell_output_str(&read_command, "read: filename too long: ", data); PROCESS_EXIT(); } memcpy(filename, data, len); filename[len] = 0; offset = shell_strtolong(next, NULL); next++; next = strchr(next, ' '); if(next != NULL) { block_size = shell_strtolong(next, NULL); if(block_size > MAX_BLOCKSIZE) { shell_output_str(&read_command, "read: block size too large: ", data); PROCESS_EXIT(); } } } fd = cfs_open(filename, CFS_READ); cfs_seek(fd, offset, CFS_SEEK_SET); if(fd < 0) { shell_output_str(&read_command, "read: could not open file for reading: ", filename); } else { while(1) { len = cfs_read(fd, buf, block_size); if(len <= 0) { cfs_close(fd); PROCESS_EXIT(); } shell_output(&read_command, buf, len, "", 0); process_post(&shell_read_process, PROCESS_EVENT_CONTINUE, NULL); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_CONTINUE || ev == shell_event_input); if(ev == shell_event_input) { input = data; /* printf("cat input %d %d\n", input->len1, input->len2);*/ if(input->len1 + input->len2 == 0) { cfs_close(fd); PROCESS_EXIT(); } } } } } PROCESS_END(); }
void storage_close(db_storage_id_t fd) { cfs_close(fd); }
PROCESS_THREAD(checkpoint_serial_process, ev, data) { static int set_fd = -1; static int set_count = -1; PROCESS_BEGIN(); /* Note: 'cp', 'rb', and 'mt' commands are intercepted */ PROCESS_PAUSE(); uart1_set_input(serial_input_byte_intercept); /* Format Coffee? */ PRINTF("Formatting Coffee\n"); cfs_coffee_format(); PRINTF("Formatting Coffee... done!\n"); while(1) { PROCESS_WAIT_EVENT_UNTIL(ev == serial_line_event_message && data != NULL); if(strcmp("set", data) == 0) { /* TODO Handle set command */ /* Open file */ cfs_remove("cp"); cfs_coffee_reserve("cp", checkpoint_arch_size()); set_fd = cfs_open("cp", CFS_WRITE); set_count = 0; if(set_fd < 0) { printf("SET:FSBUSY\n"); } else { printf("SET:LINE\n"); } } else if(set_fd >= 0 && strcmp("set:done", data) == 0) { cfs_close(set_fd); set_fd = -1; if(set_count == 9862) { printf("SET:DONE\n"); } else { printf("SET:WRONGSIZE\n"); } } else if(set_fd >= 0) { /* We are ready for another line */ printf("SET:LINE\n"); /* Set command: parse hex data */ int len = strlen((char*)data); if(len > 16 || (len%2)!=0) { printf("WARN: bad set data: %s\n", (char*)data); } else { int i; for (i=0; i < len; i+=2) { uint8_t b = (hex_decode_char(((char*)data)[i]) << 4) + (hex_decode_char(((char*)data)[i+1])); PRINTF("Parsing set command: writing to CFS: %02x\n", b); write_byte(set_fd, b); /* TODO Check return value */ set_count++; } } } else if(strcmp("", data) == 0 || strcmp("cp", data) == 0 || strcmp("rb", data) == 0 || strcmp("mt", data) == 0) { /* ignore commands: handled by interrupt */ } else if(strcmp("ping", data) == 0) { nr_pongs++; printf("pong %u\n", nr_pongs); } else if(strcmp("get", data) == 0) { handle_get_command(); } else { printf("WARN: Unknown command: '%s'\n", (char*)data); } } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(coffee_test_process, ev, data) { int fd_write, n, i; static int cnt = 0; uint8_t buffer[FILE_SIZE]; clock_time_t now; unsigned short now_fine; static uint32_t time_start, time_stop; printf("###########################################################\n"); PROCESS_BEGIN(); printf("process running\n"); // wait for 5 sec etimer_set(&et, CLOCK_SECOND * 5); PROCESS_YIELD_UNTIL(etimer_expired(&et)); #if (COFFEE_DEVICE == 6) int initialized = 0, i; SDCARD_POWER_ON(); //--- Detecting devices and partitions TEST_EQUALS(diskio_detect_devices(), DISKIO_SUCCESS); info = diskio_devices(); for (i = 0; i < DISKIO_MAX_DEVICES; i++) { if ((info + i)->type == (DISKIO_DEVICE_TYPE_SD_CARD | DISKIO_DEVICE_TYPE_PARTITION)) { info += i; initialized = 1; break; } } TEST_EQUALS(initialized, 1); diskio_set_default_device(info); #endif printf("fomartting...\n"); TEST_EQUALS(cfs_coffee_format(), 0); //printf("test starting\n"); do { now_fine = clock_time(); now = clock_seconds(); } while (now_fine != clock_time()); time_start = ((unsigned long)now)*CLOCK_SECOND + now_fine%CLOCK_SECOND; while(1) { // Shortest possible pause PROCESS_PAUSE(); // Determine the filename char b_file[8]; sprintf(b_file,"%u.b", cnt); // Set the file size printf("Reserving '%s'...\n", b_file); TEST_EQUALS(cfs_coffee_reserve(b_file, FILE_SIZE), 0); // And open it printf("Opening '%s'...\n", b_file); fd_write = cfs_open(b_file, CFS_WRITE); TEST_NEQ(fd_write, -1); // fill buffer for(i=0; i<FILE_SIZE; i++) { buffer[i] = cnt % 0xFF; } // Open was successful, write has to be successful too since the size has been reserved printf("Writing'%s'...\n", b_file); n = cfs_write(fd_write, buffer, FILE_SIZE); cfs_close(fd_write); TEST_EQUALS(n, FILE_SIZE); printf("%s written\n", b_file); if( cnt >= FILES_IN_STORAGE ) { int fd_read; // Figure out the filename char r_file[8]; sprintf(r_file,"%u.b", cnt - FILES_IN_STORAGE); // Open the bundle file printf("Reopening '%s'...\n", r_file); fd_read = cfs_open(r_file, CFS_READ); if(fd_read == -1) { // Could not open file printf("############# STORAGE: could not open file %s\n", r_file); fail(); } memset(buffer, 0, FILE_SIZE); // And now read the bundle back from flash printf("Reading '%s'...\n", b_file); if (cfs_read(fd_read, buffer, FILE_SIZE) == -1){ printf("############# STORAGE: cfs_read error\n"); cfs_close(fd_read); fail(); } cfs_close(fd_read); for(i=0; i<FILE_SIZE; i++) { if( buffer[i] != (cnt - FILES_IN_STORAGE) % 0xFF ) { printf("############# STORAGE: verify error\n"); fail(); } } if( cfs_remove(r_file) == -1 ) { printf("############# STORAGE: unable to remove %s\n", r_file); fail(); } printf("%s deleted\n", r_file); } cnt ++; if( cnt >= 10 ) { do { now_fine = clock_time(); now = clock_seconds(); } while (now_fine != clock_time()); time_stop = ((unsigned long)now)*CLOCK_SECOND + now_fine%CLOCK_SECOND; TEST_REPORT("data written", FILE_SIZE*cnt*CLOCK_SECOND, time_stop-time_start, "bytes/s"); TEST_PASS(); watchdog_stop(); while(1); } } PROCESS_END(); }
/* this process handle the reception of messages */ PROCESS_THREAD(delugeGroupP, ev, data) { int fd; char* buf; uint8_t nr_pages_local; static struct etimer et; static struct jsonparse_state jsonState; static ContainerRoot * newModel; static uip_ipaddr_t addr; PROCESS_BEGIN(); /* keep track of the singleton instance */ instance = (DelugeGroup*)data; /* register new event types */ NEW_AVAILABLE_OA_MODEL = process_alloc_event(); NEW_OA_MODEL_DOWNLOADED = process_alloc_event(); /* initialize model announcement's system */ simple_udp_register(&deluge_group_broadcast, 34555, NULL, 34555, model_version_recv); /* set announcement's initial value*/ instance->info.version = 0; instance->info.nr_pages = 0; /* set timer for announcements */ etimer_set(&et, CLOCK_SECOND * instance->interval); while (1) { /* Listen for announcements every interval seconds. */ PROCESS_WAIT_EVENT(); if (ev == PROCESS_EVENT_TIMER) { /* announce my model */ uip_create_linklocal_allnodes_mcast(&addr); simple_udp_sendto(&deluge_group_broadcast, &instance->info, sizeof(struct ModelInfo), &addr); etimer_restart(&et); } else if (ev == NEW_AVAILABLE_OA_MODEL){ /* receive the new over the air model */ /* contains the number of pages */ nr_pages_local = instance->info.nr_pages; /* create the file with the required number of pages */ cfs_remove(instance->fileNameWithModel); fd = cfs_open(instance->fileNameWithModel, CFS_WRITE); buf = (char*) malloc(S_PAGE); memset(buf, '0' , S_PAGE); PRINTF("Number of pages is %d\n", nr_pages_local); while(nr_pages_local) { cfs_seek(fd, 0, CFS_SEEK_END); cfs_write(fd, buf, S_PAGE); nr_pages_local--; } free(buf); cfs_close(fd); /* Deluge-based dissemination */ if (deluge_disseminate(instance->fileNameWithModel, 0, modelDownloaded)) { PRINTF("ERROR: some problem waiting for new version of the file\n"); } else { PRINTF("INFO: Waiting for new version of the file \n"); } } else if (ev == NEW_OA_MODEL_DOWNLOADED) { /* deserialize the model received over the air */ PRINTF("New model %s received in group with instance %p\n", instance->fileNameWithModel, instance); newModel = NULL; /* TODO: check if the file exists */ /* parse model from json file */ jsonparse_setup(&jsonState, instance->fileNameWithModel); newModel = JSONKevDeserializer(&jsonState, jsonparse_next(&jsonState)); cfs_close(jsonState.fd); PRINTF("INFO: Deserialization finished in Deluge Group %p\n", newModel); /* save a reference to the new model */ instance->lastReceivedModel = newModel; /* Afterwards, just call notifyNewModel */ if (newModel != NULL && notifyNewModel(newModel) == PROCESS_ERR_OK) { PRINTF("INFO: Model was successfully sent\n"); } else { PRINTF("ERROR: The model cannot be loaded!\n"); } } } PROCESS_END(); }
static int exec_file(char *name, char **error) { int fd; int ret; *error = 0; /* Kill any old processes. */ if(elfloader_autostart_processes != NULL) { autostart_exit(elfloader_autostart_processes); } fd = cfs_open(name, CFS_READ | CFS_WRITE); if(fd < 0) { #if DEBUG error = "Could not open file"; #endif } else { ret = elfloader_load(fd); cfs_close(fd); #if DEBUG switch(ret) { case ELFLOADER_OK: *error = "OK"; break; case ELFLOADER_BAD_ELF_HEADER: *error = "Bad ELF header"; break; case ELFLOADER_NO_SYMTAB: *error = "No symbol table"; break; case ELFLOADER_NO_STRTAB: *error = "No string table"; break; case ELFLOADER_NO_TEXT: *error = "No text segment"; break; case ELFLOADER_SYMBOL_NOT_FOUND: *error = "Symbol not found"; // symbol = elfloader_unknown; PRINTF("Symbol not found: %s\n", elfloader_unknown); break; case ELFLOADER_SEGMENT_NOT_FOUND: *error = "Segment not found"; // symbol = elfloader_unknown; PRINTF("Segment not found: %s\n", elfloader_unknown); break; case ELFLOADER_NO_STARTPOINT: *error = "No starting point"; break; default: *error = "Unknown return code from the ELF loader (internal bug)"; break; } #endif if(ret == ELFLOADER_OK) { autostart_start(elfloader_autostart_processes); return 0; } } return 1; }
void logging_serialprint(void) { volatile enum logging_states prev_state; uint8_t data[LOGGING_MAX_LOGLEN]; /* read data is stored here */ struct logheader lh; uint8_t k; //XXX debug counter /* XXX need to disable the watchdog before this? */ /* Check logging status is ok first */ if(log_state == LOGGING_NOT_INIT || log_state == LOGGING_FATAL_ERROR){ printf("FATAL: log printf failed: %u\n", log_state); return; } /* If it is busy, we wait until it is ready */ while(log_state == LOGGING_BUSY){ ; } prev_state = log_state; log_state = LOGGING_BUSY; if(prev_state == LOGGING_OK_TO_LOG){ cfs_close(fd); } /* To print the log, the file must first be closed (now has CFS_WRITE flag) and reopened with CFS_READ. Then read file, print message by message, until the file ends. */ fd = cfs_open(FILENAME, CFS_READ); do { /* Read the header */ //r = cfs_read(fd, &((void *)lh), sizeof(struct logheader)); r = cfs_read(fd, &lh, sizeof(struct logheader)); if(r < 0) { printf("CFS read error\n"); /* Invalid file descriptor or not opened to read -> -1*/ break; } if(r > 0) { printf("Log: End of file\n"); break; } /* Read the log itself */ //r = cfs_read(fd, &((void *)data), lh.len); r = cfs_read(fd, &data, lh.len); if(r == -1 || r == 0){ printf("Log: read error\n"); break; } /* read success, parse and print logmsg */ printf("[%lu] Log Type %u Len %u ", lh.time, lh.type, lh.len); for(k=0 ; k<lh.len ; k++){ printf(" %u", data[k]); } printf("\n"); #if 0 switch(logmsg.type){ /* Will this work? (default w time...) */ case default: printf("[%lu] ", logmsg.time); case LOGTYPE_TRACEPLAY: case LOGTYPE_TRACESAVE: printf("Trace\n"); break; case LOGTYPE_SYSERR: case LOGTYPE_SYSWARN: printf("System\n"); break; } #endif } while(r != -1 && r != 0); cfs_close(fd); if(prev_state == LOGGING_OK_TO_LOG){ fd = cfs_open(FILENAME, CFS_WRITE | CFS_APPEND); } log_state = prev_state; }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(cfs_process, ev, data) { PROCESS_BEGIN(); { int i, j, fd; int errors = 0; int filesize = 65000; #define CHUNKSIZE 128 fd = cfs_open("hej", CFS_WRITE); if(fd < 0) { printf("could not open file for writing, aborting\n"); } else { unsigned char buf[CHUNKSIZE]; for(i = 0; i < filesize; i += CHUNKSIZE) { for(j = 0; j < CHUNKSIZE; ++j) { buf[j] = i + j; } cfs_write(fd, buf, CHUNKSIZE); } cfs_close(fd); } fd = cfs_open("hej", CFS_READ); if(fd < 0) { printf("could not open file for reading, aborting\n"); } else { for(i = 0; i < filesize; ++i) { unsigned char buf; cfs_read(fd, &buf, 1); if(buf != i) { errors++; printf("error: diff at %d, %d != %d\n", i, i, buf); } } } printf("CFS xmem test 1 completed with %d errors\n", errors); fd = cfs_open("hej", CFS_WRITE); if(fd < 0) { printf("could not open file for writing, aborting\n"); } else { unsigned char buf[CHUNKSIZE]; for(i = 0; i < filesize; i += CHUNKSIZE) { for(j = 0; j < CHUNKSIZE; ++j) { buf[j] = i + j + 1; } cfs_write(fd, buf, CHUNKSIZE); } cfs_close(fd); } fd = cfs_open("hej", CFS_READ); if(fd < 0) { printf("could not open file for reading, aborting\n"); } else { for(i = 0; i < filesize; ++i) { unsigned char buf; cfs_read(fd, &buf, 1); if(buf != i + 1) { errors++; printf("error: diff at %d, %d != %d\n", i, i, buf); } } } printf("CFS xmem test 2 completed with %d errors\n", errors); } PROCESS_END(); }
int coffee_file_test(void) { int error; int wfd, rfd, afd; unsigned char buf[256], buf2[11]; int r, i, j, total_read; unsigned offset; cfs_remove("T1"); cfs_remove("T2"); cfs_remove("T3"); cfs_remove("T4"); cfs_remove("T5"); wfd = rfd = afd = -1; for(r = 0; r < sizeof(buf); r++) { buf[r] = r; } PRINTF("TEST 1\n"); /* Test 1: Open for writing. */ wfd = cfs_open("T1", CFS_WRITE); if(wfd < 0) { FAIL(-1); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("2\n"); /* Test 2: Write buffer. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { FAIL(-2); } else if(r < sizeof(buf)) { FAIL(-3); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("3\n"); /* Test 3: Deny reading. */ r = cfs_read(wfd, buf, sizeof(buf)); if(r >= 0) { FAIL(-4); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("4\n"); /* Test 4: Open for reading. */ rfd = cfs_open("T1", CFS_READ); if(rfd < 0) { FAIL(-5); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("5\n"); /* Test 5: Write to read-only file. */ r = cfs_write(rfd, buf, sizeof(buf)); if(r >= 0) { FAIL(-6); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("7\n"); /* Test 7: Read the buffer written in Test 2. */ memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { FAIL(-8); } else if(r < sizeof(buf)) { PRINTF_CFS("r=%d\n", r); FAIL(-9); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("8\n"); /* Test 8: Verify that the buffer is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { PRINTF_CFS("r=%d. buf[r]=%d\n", r, buf[r]); FAIL(-10); } } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("9\n"); /* Test 9: Seek to beginning. */ if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { FAIL(-11); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("10\n"); /* Test 10: Write to the log. */ r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { FAIL(-12); } else if(r < sizeof(buf)) { FAIL(-13); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("11\n"); /* Test 11: Read the data from the log. */ cfs_seek(rfd, 0, CFS_SEEK_SET); memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { FAIL(-14); } else if(r < sizeof(buf)) { FAIL(-15); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("12\n"); /* Test 12: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != r) { FAIL(-16); } } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("13\n"); /* Test 13: Write a reversed buffer to the file. */ for(r = 0; r < sizeof(buf); r++) { buf[r] = sizeof(buf) - r - 1; } if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) { FAIL(-17); } r = cfs_write(wfd, buf, sizeof(buf)); if(r < 0) { FAIL(-18); } else if(r < sizeof(buf)) { FAIL(-19); } if(cfs_seek(rfd, 0, CFS_SEEK_SET) != 0) { FAIL(-20); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("14\n"); /* Test 14: Read the reversed buffer. */ cfs_seek(rfd, 0, CFS_SEEK_SET); memset(buf, 0, sizeof(buf)); r = cfs_read(rfd, buf, sizeof(buf)); if(r < 0) { FAIL(-21); } else if(r < sizeof(buf)) { PRINTF_CFS("r = %d\n", r); FAIL(-22); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("15\n"); /* Test 15: Verify that the data is correct. */ for(r = 0; r < sizeof(buf); r++) { if(buf[r] != sizeof(buf) - r - 1) { FAIL(-23); } } cfs_close(rfd); cfs_close(wfd); if(cfs_coffee_reserve("T2", FILE_SIZE) < 0) { FAIL(-24); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("16\n"); /* Test 16: Test multiple writes at random offset. */ for(r = 0; r < 100; r++) { wfd = cfs_open("T2", CFS_WRITE | CFS_READ); if(wfd < 0) { FAIL(-25); } offset = random_rand() % FILE_SIZE; for(r = 0; r < sizeof(buf); r++) { buf[r] = r; } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { FAIL(-26); } if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) { FAIL(-27); } if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) { FAIL(-28); } memset(buf, 0, sizeof(buf)); if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) { FAIL(-29); } for(i = 0; i < sizeof(buf); i++) { if(buf[i] != i) { PRINTF_CFS("buf[%d] != %d\n", i, buf[i]); FAIL(-30); } } } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("17\n"); /* Test 17: Append data to the same file many times. */ #define APPEND_BYTES 3000 #define BULK_SIZE 10 for (i = 0; i < APPEND_BYTES; i += BULK_SIZE) { afd = cfs_open("T3", CFS_WRITE | CFS_APPEND); if (afd < 0) { FAIL(-31); } for (j = 0; j < BULK_SIZE; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if ((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) { PRINTF_CFS("Count:%d, r=%d\n", i, r); FAIL(-32); } cfs_close(afd); } PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("18\n"); /* Test 18: Read back the data written in Test 17 and verify that it is correct. */ afd = cfs_open("T3", CFS_READ); if(afd < 0) { FAIL(-33); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { FAIL(-34); } } total_read += r; } if(r < 0) { PRINTF_CFS("FAIL:-35 r=%d\n",r); FAIL(-35); } if(total_read != APPEND_BYTES) { PRINTF_CFS("FAIL:-35 total_read=%d\n",total_read); FAIL(-35); } cfs_close(afd); PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("19\n"); /***************T4********************/ /* file T4 and T5 writing forces to use garbage collector in greedy mode * this test is designed for 10kb of file system * */ #define APPEND_BYTES_1 2000 #define BULK_SIZE_1 10 for (i = 0; i < APPEND_BYTES_1; i += BULK_SIZE_1) { afd = cfs_open("T4", CFS_WRITE | CFS_APPEND); if (afd < 0) { FAIL(-36); } for (j = 0; j < BULK_SIZE_1; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if ((r = cfs_write(afd, buf, BULK_SIZE_1)) != BULK_SIZE_1) { PRINTF_CFS("Count:%d, r=%d\n", i, r); FAIL(-37); } cfs_close(afd); } afd = cfs_open("T4", CFS_READ); if(afd < 0) { FAIL(-38); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { PRINTF_CFS("FAIL:-39, total_read=%d r=%d\n",total_read,r); FAIL(-39); } } total_read += r; } if(r < 0) { PRINTF_CFS("FAIL:-40 r=%d\n",r); FAIL(-40); } if(total_read != APPEND_BYTES_1) { PRINTF_CFS("FAIL:-41 total_read=%d\n",total_read); FAIL(-41); } cfs_close(afd); /***************T5********************/ PRINTF("PASSED\n"); PRINTF("TEST "); PRINTF("20\n"); #define APPEND_BYTES_2 1000 #define BULK_SIZE_2 10 for (i = 0; i < APPEND_BYTES_2; i += BULK_SIZE_2) { afd = cfs_open("T5", CFS_WRITE | CFS_APPEND); if (afd < 0) { FAIL(-42); } for (j = 0; j < BULK_SIZE_2; j++) { buf[j] = 1 + ((i + j) & 0x7f); } if ((r = cfs_write(afd, buf, BULK_SIZE_2)) != BULK_SIZE_2) { PRINTF_CFS("Count:%d, r=%d\n", i, r); FAIL(-43); } cfs_close(afd); } afd = cfs_open("T5", CFS_READ); if(afd < 0) { FAIL(-44); } total_read = 0; while((r = cfs_read(afd, buf2, sizeof(buf2))) > 0) { for(j = 0; j < r; j++) { if(buf2[j] != 1 + ((total_read + j) & 0x7f)) { PRINTF_CFS("FAIL:-45, total_read=%d r=%d\n",total_read,r); FAIL(-45); } } total_read += r; } if(r < 0) { PRINTF_CFS("FAIL:-46 r=%d\n",r); FAIL(-46); } if(total_read != APPEND_BYTES_2) { PRINTF_CFS("FAIL:-47 total_read=%d\n",total_read); FAIL(-47); } cfs_close(afd); PRINTF("PASSED\n"); error = 0; end: cfs_close(wfd); cfs_close(rfd); cfs_close(afd); return error; }
static int file_test(const char *filename, char *msg) { static uint8_t sequence; int fd; int r; struct record { char message[16]; uint8_t sequence; } record; /* * Coffee determines the file length by finding the last non-zero byte * of the file. This I/O semantic requires that each record should end * with a non-zero, if we are writing multiple records and closing the * file descriptor in between. * * In this example, in which the file_test function can be called * multiple times, we ensure that the sequence counter starts at 1. */ if(sequence == 255) { /* No more sequence numbers available. */ return -1; } sequence++; strncpy(record.message, msg, sizeof(record.message) - 1); record.message[sizeof(record.message) - 1] = '\0'; record.sequence = sequence; /* Obtain a file descriptor for the file, capable of handling both reads and writes. */ fd = cfs_open(FILENAME, CFS_WRITE | CFS_APPEND | CFS_READ); if(fd < 0) { printf("failed to open %s\n", FILENAME); return 0; } r = cfs_write(fd, &record, sizeof(record)); if(r != sizeof(record)) { printf("failed to write %d bytes to %s\n", (int)sizeof(record), FILENAME); cfs_close(fd); return 0; } printf("Wrote message \"%s\", sequence %u\n", record.message, record.sequence); /* To read back the message, we need to move the file pointer to the beginning of the file. */ if(cfs_seek(fd, 0, CFS_SEEK_SET) != 0) { printf("seek failed\n"); cfs_close(fd); return 0; } /* Read all written records and print their contents. */ for(;;) { r = cfs_read(fd, &record, sizeof(record)); if(r == 0) { break; } else if(r < sizeof(record)) { printf("failed to read %d bytes from %s, got %d\n", (int)sizeof(record), FILENAME, r); cfs_close(fd); return 0; } printf("Read message \"%s\", sequence %u\n", record.message, record.sequence); } /* Release the internal resources held by Coffee for the file descriptor. */ cfs_close(fd); return 1; }
PROCESS_THREAD(tftpd_process, ev, data) { static struct etimer t; static tftp_header *h; static int len, block, ack; static int tries; static int fd = -1; #if WITH_EXEC static char *elf_err; #endif PROCESS_BEGIN(); etimer_set(&t, CLOCK_CONF_SECOND*3); PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER); setup_server(); #if WITH_EXEC elfloader_init(); #endif print_local_addresses(); while(1) { /* connection from client */ RECV_PACKET(h); len = 0; init_config(); if(h->op == uip_htons(TFTP_RRQ)) { connect_back(); PRINTF("< rrq for %s\n", h->filename); len += strlen(h->filename)+1; if(strcmp("octet", h->filename+len)) { send_error(EUNDEF, "only octet mode supported"); goto close_connection; } len += strlen(h->filename+len)+1; /* skip mode */ parse_opts(h->options+len, uip_datalen()-len-2); if(config.to_ack & OACK_ERROR) { send_error(EOPTNEG, ""); goto close_connection; } fd = cfs_open(h->filename, CFS_READ); if(fd<0) { send_error(ENOTFOUND, ""); goto close_connection; } block = 0; ack = 0; tries = TFTP_MAXTRIES; PRINTF("starting transfer...\n"); for(;;) { if(send_oack()) len = config.blksize; /* XXX hack to prevent loop exit*/ else len = send_data(fd, block+1); if(len<0) { send_error(EUNDEF, "read failed"); goto close_file; } RECV_PACKET_TIMEOUT(h,t); if(ev == PROCESS_EVENT_TIMER) { PRINTF("ack timed out, tries left: %d\n", tries); if(--tries<=0) goto close_file; continue; } if(h->op != uip_htons(TFTP_ACK)) { send_error(EBADOP, ""); goto close_file; } config.to_ack = 0; tries = TFTP_MAXTRIES; ack = uip_htons(h->block_nr); if(ack == block+1) block++; if(len < config.blksize && ack == block) goto done; } } else if(h->op == uip_htons(TFTP_WRQ)) { connect_back(); PRINTF("< wrq for %s\n", h->filename); len += strlen(h->filename)+1; strncpy(config.filename, h->filename, sizeof(config.filename)-1); if(strcmp("octet", h->filename+strlen(h->filename)+1)) { send_error(EUNDEF, "only octet mode supported"); goto close_connection; } len += strlen(h->filename+len)+1; /* skip mode */ parse_opts(h->options+len, uip_datalen()-len-2); if(config.to_ack & OACK_ERROR) { send_error(EOPTNEG, ""); goto close_connection; } cfs_remove(h->filename); fd = cfs_open(h->filename, CFS_WRITE); if(fd<0) { send_error(EACCESS, ""); goto close_connection; } block = 0; ack = 0; tries = TFTP_MAXTRIES; PRINTF("starting transfer...\n"); if(!send_oack()) send_ack(block); for(;;) { RECV_PACKET_TIMEOUT(h,t); if(ev == PROCESS_EVENT_TIMER) { PRINTF("data timed out, tries left: %d\n", tries); if(--tries<=0) goto close_file; len = config.blksize; /* XXX hack to prevent loop exit*/ goto resend_ack; } if(h->op != uip_htons(TFTP_DATA)) { send_error(EBADOP, ""); goto close_file; } config.to_ack = 0; tries = TFTP_MAXTRIES; ack = uip_htons(h->block_nr); if(ack != block+1) continue; /* else */ block++; len = recv_data(fd, block); if(len<0) { send_error(EUNDEF, "write failed"); goto close_file; } #if WITH_EXEC if(len < config.blksize) { if(config.exec) { if(exec_file(config.filename, &elf_err) != 0) { send_error(EUNDEF, elf_err); goto close_file; } } } #endif resend_ack: if(!send_oack()) send_ack(block); if(len < config.blksize) goto done; } } done: PRINTF("done.\n"); close_file: if(fd>=0) cfs_close(fd); fd = -1; close_connection: if(client_conn) uip_udp_remove(client_conn); client_conn = 0; PRINTF("connection closed.\n"); } PROCESS_END(); }
/*---------------------------------------------------------------------------*/ PROCESS_THREAD(console_server, ev, data) { static uint8_t buf[257]; static uint8_t processingFile = 0; static uint32_t received = 0; static struct cfs_dirent dirent; static struct cfs_dir dir; static uint32_t fdFile; static char *filename; PROCESS_BEGIN(); elfloader_init(); printf("Console server started !\n"); while(1) { PROCESS_YIELD(); if (ev == serial_line_event_message) { if (!strcmp(data, "ls")) { if(cfs_opendir(&dir, ".") == 0) { while(cfs_readdir(&dir, &dirent) != -1) { printf("File: %s (%ld bytes)\n", dirent.name, (long)dirent.size); } cfs_closedir(&dir); } } else if (!strcmp(data, "format")) { /* format the flash */ printf("Formatting\n"); printf("It takes around 3 minutes\n"); printf("...\n"); fdFile = cfs_coffee_format(); printf("Formatted with result %ld\n", fdFile); } else if (strstr(data, "cat") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ); if (fdFile < 0) printf("error opening the file %s\n", tmp); while ((n = cfs_read(fdFile, buf, 60)) > 0) { for (jj = 0 ; jj < n ; jj++) printf("%c", (char)buf[jj]); } printf("\n"); cfs_close(fdFile); if (n!=0) printf("Some error reading the file\n"); } else if (strstr(data, "loadelf") == data) { filename = strstr(data, " "); filename++; // Cleanup previous loads if (elfloader_autostart_processes != NULL) autostart_exit(elfloader_autostart_processes); elfloader_autostart_processes = NULL; // Load elf file fdFile = cfs_open(filename, CFS_READ | CFS_WRITE); received = elfloader_load(fdFile); cfs_close(fdFile); printf("Result of loading %lu\n", received); // As the file has been modified and can't be reloaded, remove it printf("Remove dirty firmware '%s'\n", filename); cfs_remove(filename); // execute the program if (ELFLOADER_OK == received) { if (elfloader_autostart_processes) { PRINT_PROCESSES(elfloader_autostart_processes); autostart_start(elfloader_autostart_processes); } } else if (ELFLOADER_SYMBOL_NOT_FOUND == received) { printf("Symbol not found: '%s'\n", elfloader_unknown); } } else if (strstr(data, "rm") == data) { int n, jj; char* tmp = strstr(data, " "); tmp++; cfs_remove(tmp); } else if (strstr(data, "upload") == data) { char* tmp = strstr(data, " "); tmp++; fdFile = cfs_open(tmp, CFS_READ | CFS_WRITE); printf("Uploading file %s\n", tmp); processingFile = 1; } else if (!strcmp(data, "endupload")) { cfs_close(fdFile); printf("File uploaded (%ld bytes)\n", received); received = 0; processingFile = 0; } else if (processingFile) { int n = strlen(data); int r = decode(data, n, buf); received += r; cfs_write(fdFile, buf, r); } else { printf("%s (%lu bytes received)\n", (char*)data, received); } } } PROCESS_END(); }
/*------Done in a subroutine to keep main routine stack usage small--------*/ void initialize(void) { watchdog_init(); watchdog_start(); #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(); #if STACKMONITOR /* Simple stack pointer highwater monitor. Checks for magic numbers in the main * loop. In conjuction with TESTRTIMER, never-used stack will be printed * every STACKMONITOR seconds. */ { extern uint16_t __bss_end; uint16_t p=(uint16_t)&__bss_end; do { *(uint16_t *)p = 0x4242; p+=10; } while (p<SP-10); //don't overwrite our own stack } #endif #define CONF_CALIBRATE_OSCCAL 0 #if CONF_CALIBRATE_OSCCAL { extern uint8_t osccal_calibrated; uint8_t i; PRINTF("\nBefore calibration OSCCAL=%x\n",OSCCAL); for (i=0;i<10;i++) { calibrate_rc_osc_32k(); PRINTF("Calibrated=%x\n",osccal_calibrated); //#include <util/delay_basic.h> //#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) // delay_us(50000); } clock_init(); } #endif #if ANNOUNCE_BOOT PRINTF("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); #endif /* rtimers needed for radio cycling */ rtimer_init(); /* Initialize process subsystem */ process_init(); /* etimers must be started before ctimer_init */ process_start(&etimer_process, NULL); #if RF230BB ctimer_init(); /* Start radio and radio receive process */ NETSTACK_RADIO.init(); /* Set addresses BEFORE starting tcpip process */ rimeaddr_t addr; memset(&addr, 0, sizeof(rimeaddr_t)); get_mac_from_eeprom(addr.u8); #if UIP_CONF_IPV6 memcpy(&uip_lladdr.addr, &addr.u8, 8); #endif rf230_set_pan_addr( get_panid_from_eeprom(), get_panaddr_from_eeprom(), (uint8_t *)&addr.u8 ); rf230_set_channel(get_channel_from_eeprom()); rimeaddr_set_node_addr(&addr); PRINTFD("MAC address %x:%x:%x:%x:%x:%x:%x:%x\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]); /* Initialize stack protocols */ queuebuf_init(); NETSTACK_RDC.init(); NETSTACK_MAC.init(); NETSTACK_NETWORK.init(); #if ANNOUNCE_BOOT PRINTF("%s %s, channel %u",NETSTACK_MAC.name, NETSTACK_RDC.name,rf230_get_channel()); if (NETSTACK_RDC.channel_check_interval) {//function pointer is zero for sicslowmac unsigned short tmp; tmp=CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval == 0 ? 1:\ NETSTACK_RDC.channel_check_interval()); if (tmp<65535) printf_P(PSTR(", check rate %u Hz"),tmp); } PRINTF("\n"); #if UIP_CONF_IPV6_RPL PRINTF("RPL Enabled\n"); #endif #if UIP_CONF_ROUTER PRINTF("Routing Enabled\n"); #endif #endif /* ANNOUNCE_BOOT */ // rime_init(rime_udp_init(NULL)); // uip_router_register(&rimeroute); process_start(&tcpip_process, NULL); #else /* Original RF230 combined mac/radio driver */ /* mac process must be started before tcpip process! */ process_start(&mac_process, NULL); process_start(&tcpip_process, NULL); #endif /*RF230BB*/ #ifdef RAVEN_LCD_INTERFACE process_start(&raven_lcd_process, NULL); #endif /* Autostart other processes */ autostart_start(autostart_processes); //Give ourselves a prefix // init_net(); /*---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("No index.html file found, creating upload.html!\n"); PRINTF("Formatting FLASH file system for coffee..."); cfs_coffee_format(); PRINTF("Done!\n"); fa = cfs_open( "/index.html", CFS_WRITE); int r = cfs_write(fa, &"It works!", 9); if (r<0) PRINTF("Can''t create /index.html!\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 /* COFFEE_FILES */ /* Add addresses for testing */ #if 0 { uip_ip6addr_t ipaddr; uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); // uip_ds6_prefix_add(&ipaddr,64,0); } #endif /*--------------------------Announce the configuration---------------------*/ #if ANNOUNCE_BOOT #if AVR_WEBSERVER uint8_t i; char buf[80]; unsigned int size; for (i=0;i<UIP_DS6_ADDR_NB;i++) { if (uip_ds6_if.addr_list[i].isused) { httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf); PRINTF("IPv6 Address: %s\n",buf); } } eeprom_read_block (buf,server_name, sizeof(server_name)); buf[sizeof(server_name)]=0; PRINTF("%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(".%s online with fixed %u byte web content\n",buf,size); #elif COFFEE_FILES==1 PRINTF(".%s online with static %u byte EEPROM file system\n",buf,size); #elif COFFEE_FILES==2 PRINTF(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10); #elif COFFEE_FILES==3 PRINTF(".%s online with static %u byte program memory file system\n",buf,size); #elif COFFEE_FILES==4 PRINTF(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); #endif /* COFFEE_FILES */ #else PRINTF("Online\n"); #endif /* AVR_WEBSERVER */ #endif /* ANNOUNCE_BOOT */ }
/** Link the given file into flash ROM. * \param programfile Filename containing program to load * \param symtabfile File containing the symbol table of the kernel * \param process Output for storing pointer to process structure * of program * \return 0 on success, 1 if file was damaged or not found, 2 if not * enough memory, 3 if symbol could not be resolved */ uint_fast8_t minilink_load(const char *programfile, const char *symtabfile, struct process ***proclist) { Minilink_Header mlhdr; uint16_t *symvalp = NULL; Minilink_ProgramInfoHeader pihdr, *instprog; int status = 1; struct io_buf_st buf_ml; struct io_buf_st buf_sym; #if DEBUG_DIFF void * memblock; memblock = malloc(node_id * 40); #endif LEDGOFF; LEDBOFF; LEDRON; memset(&pihdr, 0, sizeof(pihdr)); if (strlen(programfile) > MINILINK_MAX_FILENAME - 1) { DPUTS("Name too long.\n"); return 1; } buf_ml.filled = 0; buf_ml.pos = 0; LEDBON; buf_ml.fd = cfs_open(programfile, CFS_READ); if (buf_ml.fd < 0) { DPUTS("Could not open File."); goto cleanup; } buf_sym.pos = 0; buf_sym.filled = 0; buf_sym.fd = cfs_open(symtabfile, CFS_READ); LEDBOFF; //Check whether the files are ok if (ml_file_check(buf_ml.fd, MINILINK_PGM_MAGIC) != 1) { DPUTS("Ret is not 1\n"); return 1; } if (ml_file_check(buf_sym.fd, MINILINK_SYM_MAGIC) != 1) { DPUTS("Ret is not 1\n"); return 1; } LEDGON; //Reset cfs_seek(buf_ml.fd, 0, CFS_SEEK_SET); cfs_seek(buf_sym.fd, 0, CFS_SEEK_SET); LEDBON; //Read header, but do not write to buffer! if (cfs_read(buf_ml.fd, &mlhdr, sizeof(mlhdr)) != sizeof(mlhdr)) { DPUTS("Could not Read Header."); goto cleanup; } //Now let's get the ram for the symbol table symvalp = malloc(mlhdr.symentries * sizeof(uint16_t)); if (symvalp == NULL) { DPUTS("Could not allocate memory for symtbl."); status = 2; goto cleanup; } //------------ Resolve the symbol-list. - This must be done anyway { uint16_t symctr; char cursym[MINILINK_MAX_SYMLEN]; uint16_t curr_add = 0; cursym[0] = 0; if (buf_sym.fd < 0) { DPUTS("Could not open File."); goto cleanup; } { //get rid of the header. uint8_t shift = sizeof(Minilink_SymbolHeader); while (shift) { shift_iobuf(&buf_sym); buf_sym.pos = Min(buf_sym.filled, shift); shift -= buf_sym.pos; } } //Fill Buffer..... shift_iobuf(&buf_sym); #define NEXTSYMPOS {buf_sym.pos++; if(buf_sym.filled == buf_sym.pos) shift_iobuf(&buf_sym);} for (symctr = 0; symctr < mlhdr.symentries; symctr++) { uint8_t samechars; //fill buffer. shift_iobuf(&buf_ml); samechars = buf_ml.data[buf_ml.pos]; buf_ml.pos++; DPRINTF("Looking up: <%i>%s\n", samechars, &(buf_ml.data[buf_ml.pos])); while (1) { /// \fixme make sure we don't go past the buffer // The next code is a bit complicated, I'll add some graphix to visualize it /// \todo Grafiken erstellen. //get next symbol uint8_t symattr; uint16_t sym_write_pos; symattr = buf_sym.data[buf_sym.pos]; NEXTSYMPOS; sym_write_pos = symattr & 0x3F; if (samechars > sym_write_pos) { //Ok, looks like we went past the symbol DPUTS("Symbol could not be resolved - past same\n"); status = 1; goto cleanup; } else if (samechars == sym_write_pos) { while (1) { //Loop until we reach the Null-char if (buf_sym.data[buf_sym.pos] != buf_ml.data[buf_ml.pos]) break; if (buf_ml.data[buf_ml.pos] == '\0') { DPUTS("FOUND!\n"); break; //Could take any of the two, as they are the same } //It is important that this comes afterwards! - It must point at the NULL NEXTSYMPOS; buf_ml.pos++; samechars++; } if (buf_sym.data[buf_sym.pos] > buf_ml.data[buf_ml.pos]) { // We are searching for a symbol smaller then // the current on. - They are sorted, therefore we will not find it anymore DPUTS("Symbol could not be resolved - past alpha\n"); status = 3; goto cleanup; } } while (buf_sym.data[buf_sym.pos] != '\0') NEXTSYMPOS; NEXTSYMPOS; //one more! symattr &= 0xC0; symattr >>= 6; switch (symattr) { case 0: CPY16(curr_add, buf_sym.data[buf_sym.pos]); NEXTSYMPOS; break; case 1: curr_add--; curr_add -= buf_sym.data[buf_sym.pos]; break; case 3: curr_add += 0x0100; case 2: curr_add += buf_sym.data[buf_sym.pos]; break; } NEXTSYMPOS; //DPRINTF("Checking: %i:%s - %x same: %i\n",buf_sym.data[0] & 0x3F , &(buf_sym.data[1]), curr_add, samechars); //We've found the symbol, so let's break if (buf_ml.data[buf_ml.pos] == '\0') { //Move on to next symbol. buf_ml.pos++; break; } } //Loop searching for the symbol ((uint16_t *) (symvalp))[symctr] = curr_add; //copy the symbol address to memory MALLOC_CHK(symvalp); } //Loop looping through symbols } // End of resolving symbol list. #undef NEXTSYMPOS LEDGOFF; pihdr.magic = MINILINK_INST_MAGIC; pihdr.crc = mlhdr.common.crc; //pihdr.mem[DATA].ptr = NULL; pihdr.mem[MINILINK_DATA].size = mlhdr.datasize; //pihdr.mem[MINILINK_BSS].ptr = NULL; pihdr.mem[MINILINK_BSS].size = mlhdr.bsssize; //pihdr.mem[MINILINK_MIG].ptr = NULL; pihdr.mem[MINILINK_MIG].size = mlhdr.migsize; //pihdr.mem[MINILINK_MIGPTR].ptr = NULL; pihdr.mem[MINILINK_MIGPTR].size = mlhdr.migptrsize; //pihdr.process = NULL; pihdr.mem[MINILINK_TEXT].size = mlhdr.textsize; strncpy(pihdr.sourcefile, programfile, MINILINK_MAX_FILENAME); //Let's see whether the program is already installed instprog = program_already_loaded(&pihdr); if (instprog != NULL) { struct process * curproc; /* Check if program to be reloaded has active processes, i.e. appears * in the process list */ for (curproc = process_list; curproc != NULL; curproc = curproc->next) { if ((uintptr_t) (void*) curproc >= (uintptr_t)(instprog->mem[MINILINK_DATA].ptr) && (uintptr_t) (void*) curproc < (uintptr_t)(instprog->mem[MINILINK_DATA].ptr + instprog->mem[MINILINK_DATA].size)) { puts("Process in use. Can't install."); status = 2; goto cleanup; } } DPRINTF("Loading header from %x\n Data: %x\nBss: %x\n", (uint16_t ) instprog, (uint16_t)instprog->mem[MINILINK_DATA].ptr, (uint16_t)instprog->mem[MINILINK_BSS].ptr); memcpy(&pihdr, instprog, sizeof(pihdr)); DPRINTF("After copy:\n Data: %x\nBss: %x\n", (uint16_t)(pihdr.mem[MINILINK_DATA].ptr), (uint16_t)pihdr.mem[MINILINK_BSS].ptr); pihdr.mem[MINILINK_TEXT].ptr = (uint8_t *) instprog + sizeof(pihdr); } else { //Process does not exist, let's get some memory for linking it status = 2; uint8_t ctr; //Now let's allocate Memory if ((mlhdr.textsize & 1) || (mlhdr.datasize & 1) || (mlhdr.bsssize & 1)) { DPUTS(".data, .bss or .text section not word aligned"); goto cleanup; } pihdr.mem[MINILINK_TEXT].ptr = ml_alloc_text(pihdr.mem[MINILINK_TEXT].size + sizeof(pihdr)); if (pihdr.mem[MINILINK_TEXT].ptr == NULL) { DPUTS("Could not alloc Text."); goto cleanup; } pihdr.mem[MINILINK_TEXT].ptr += sizeof(pihdr); //Allocate Memory; Starting beheind text for (ctr = MINILINK_DATA; ctr < MINILINK_SEC; ctr++) { if (pihdr.mem[ctr].size) { pihdr.mem[ctr].ptr = ml_alloc_mem(mlhdr.datasize); if (pihdr.mem[ctr].ptr == NULL) { DPRINTF("Could not alloc Memory for %i\n", ctr); goto cleanup; } } } pihdr.process = pihdr.mem[MINILINK_TEXT].ptr + mlhdr.processoffset; DPRINTF("PO: %.4x = %.4x + %.4x\n", (uintptr_t )pihdr.process, (uintptr_t)pihdr.mem[MINILINK_TEXT].ptr, mlhdr.processoffset); } // Build up array where to place what.... { uint8_t r; for (r = 0; r < MINILINK_SEC; r++) { DPRINTF("%x len: %x\n", (uintptr_t)(pihdr.mem[r].ptr), (uintptr_t)(pihdr.mem[r].size)); } } LEDBOFF; // Link data section DPRINTF("\n\nRelocating DATA to %x len: %x\n", (uint16_t)pihdr.mem[MINILINK_DATA].ptr, (uint16_t)pihdr.mem[MINILINK_DATA].size); status = ml_relocate(&buf_ml, pihdr.mem[MINILINK_DATA].size, pihdr.mem[MINILINK_DATA].ptr, symvalp, mlhdr.symentries, &pihdr, NULL); if (status != 0) goto cleanup; MALLOC_CHK(symvalp); // Link mig section if (mlhdr.migsize) { DPRINTF("\n\nRelocating MIG to %x len: %x\n", (uint16_t)pihdr.mem[MINILINK_MIG].ptr, (uint16_t)pihdr.mem[MINILINK_MIG].size); status = ml_relocate(&buf_ml, pihdr.mem[MINILINK_MIG].size, pihdr.mem[MINILINK_MIG].ptr, symvalp, mlhdr.symentries, &pihdr, NULL); if (status != 0) goto cleanup; } MALLOC_CHK(symvalp); // Link migptr section if (mlhdr.migptrsize) { DPRINTF("\n\nRelocating MIG to %x len: %x\n", (uint16_t)pihdr.mem[MINILINK_MIGPTR].ptr, (uint16_t)pihdr.mem[MINILINK_MIGPTR].size); status = ml_relocate(&buf_ml, pihdr.mem[MINILINK_MIGPTR].size, pihdr.mem[MINILINK_MIGPTR].ptr, symvalp, mlhdr.symentries, &pihdr, NULL); if (status != 0) goto cleanup; } MALLOC_CHK(symvalp); //Set Bss to 0 if (mlhdr.bsssize) { DPRINTF("\n\nClearing BSS at %x\n", (uint16_t) pihdr.mem[MINILINK_BSS].ptr); memset(pihdr.mem[MINILINK_BSS].ptr, 0, pihdr.mem[MINILINK_BSS].size); } LEDGON; if (instprog == NULL) { DPRINTF("\n\nRelocating ROM to %x len: %x\n", (uint16_t) pihdr.mem[MINILINK_TEXT].ptr, (uint16_t ) mlhdr.textsize); //Buf ML is positioned behind the symbol table status = ml_relocate(&buf_ml, mlhdr.textsize, pihdr.mem[MINILINK_TEXT].ptr, symvalp, mlhdr.symentries, &pihdr, &memwrite_flash); if (status != 0) goto cleanup; MALLOC_CHK(symvalp); DPRINTF("\n\nWriting header to %x\n", (uint16_t)pihdr.mem[MINILINK_TEXT].ptr - sizeof(pihdr)); memwrite_flash(pihdr.mem[MINILINK_TEXT].ptr - sizeof(pihdr), &pihdr, sizeof(pihdr)); //if(memcmp(pTxt - sizeof(pihdr), &pihdr, sizeof(pihdr)) != 0) printf("\n\nPANIC!!!\n\n"); { Minilink_ProgramInfoHeader *tmp, *tmp2; tmp2 = &pihdr; tmp = pihdr.mem[MINILINK_TEXT].ptr - sizeof(pihdr); //printf("PIHproc: %x - %x\n", (uint16_t)(tmp->process), (uint16_t)(tmp2->process)); } if (status != 0) goto cleanup; } LEDROFF; LEDGOFF; *proclist = pihdr.process; DPUTS("Loading complete."); cleanup: #if DEBUG_DIFF free(memblock); #endif free(symvalp); cfs_close(buf_ml.fd); cfs_close(buf_sym.fd); if (status != 0) { uint8_t ctr; //No flash for (ctr = 1; ctr < MINILINK_SEC; ctr++) { ml_free_mem(pihdr.mem[ctr].ptr); } } return status; }
/*---------------------------------------------------------------------*/ static PT_THREAD(recv_tcpthread(struct pt *pt)) { PT_BEGIN(pt); /* Read the header. */ PT_WAIT_UNTIL(pt, uip_newdata() && uip_datalen() > 0); if(uip_datalen() < sizeof(struct codeprop_tcphdr)) { PRINTF(("codeprop: header not found in first tcp segment\n")); uip_abort(); goto thread_done; } /* Kill old program. */ rudolph0_stop(&rudolph0); /* elfloader_unload();*/ s.len = htons(((struct codeprop_tcphdr *)uip_appdata)->len); s.addr = 0; uip_appdata += sizeof(struct codeprop_tcphdr); uip_len -= sizeof(struct codeprop_tcphdr); s.fd = cfs_open("codeprop.out", CFS_WRITE); cfs_close(s.fd); /* xmem_erase(XMEM_ERASE_UNIT_SIZE, EEPROMFS_ADDR_CODEPROP);*/ /* Read the rest of the data. */ do { leds_toggle(LEDS_RED); if(uip_len > 0) { s.fd = cfs_open("codeprop.out", CFS_WRITE + CFS_APPEND); cfs_seek(s.fd, s.addr, CFS_SEEK_SET); /* xmem_pwrite(uip_appdata, uip_len, EEPROMFS_ADDR_CODEPROP + s.addr);*/ cfs_write(s.fd, uip_appdata, uip_len); cfs_close(s.fd); PRINTF("Wrote %d bytes to file\n", uip_len); s.addr += uip_len; } if(s.addr < s.len) { PT_YIELD_UNTIL(pt, uip_newdata()); } } while(s.addr < s.len); leds_off(LEDS_RED); #if DEBUG { int i, fd, j; printf("Contents of file:\n"); fd = cfs_open("codeprop.out", CFS_READ); j = 0; printf("\n0x%04x: ", 0); for(i = 0; i < s.len; ++i) { unsigned char byte; cfs_read(fd, &byte, 1); printf("0x%02x, ", byte); ++j; if(j == 8) { printf("\n0x%04x: ", i + 1); j = 0; } clock_delay(400); } cfs_close(fd); } #endif int ret; ret = start_program(); #if CONTIKI_TARGET_NETSIM rudolph0_send(&rudolph0, CLOCK_SECOND / 4); #else /* CONTIKI_TARGET_NETSIM */ if(ret == ELFLOADER_OK) { /* Propagate program. */ rudolph0_send(&rudolph0, CLOCK_SECOND / 4); } #endif /* CONTIKI_TARGET_NETSIM */ /* Return "ok" message. */ do { ret = strlen(msg); uip_send(msg, ret); PT_WAIT_UNTIL(pt, uip_acked() || uip_rexmit() || uip_closed()); } while(uip_rexmit()); /* Close the connection. */ uip_close(); thread_done:; PT_END(pt); }
/*---------------------------------------------------------------------------*/ static int merge_log(coffee_page_t file_page, int extend) { struct file_header hdr, hdr2; int fd, n; cfs_offset_t offset; coffee_page_t max_pages; struct file *new_file; int i; read_header(&hdr, file_page); fd = cfs_open(hdr.name, CFS_READ); if(fd < 0) { return -1; } /* * The reservation function adds extra space for the header, which has * already been accounted for in the previous reservation. */ max_pages = hdr.max_pages << extend; new_file = reserve(hdr.name, max_pages, 1, 0); if(new_file == NULL) { cfs_close(fd); return -1; } offset = 0; do { char buf[hdr.log_record_size == 0 ? COFFEE_PAGE_SIZE : hdr.log_record_size]; n = cfs_read(fd, buf, sizeof(buf)); if(n < 0) { remove_by_page(new_file->page, !REMOVE_LOG, !CLOSE_FDS, ALLOW_GC); cfs_close(fd); return -1; } else if(n > 0) { COFFEE_WRITE(buf, n, absolute_offset(new_file->page, offset)); offset += n; } } while(n != 0); for(i = 0; i < COFFEE_FD_SET_SIZE; i++) { if(coffee_fd_set[i].flags != COFFEE_FD_FREE && coffee_fd_set[i].file->page == file_page) { coffee_fd_set[i].file = new_file; new_file->references++; } } if(remove_by_page(file_page, REMOVE_LOG, !CLOSE_FDS, !ALLOW_GC) < 0) { remove_by_page(new_file->page, !REMOVE_LOG, !CLOSE_FDS, !ALLOW_GC); cfs_close(fd); return -1; } /* Copy the log configuration and the EOF hint. */ read_header(&hdr2, new_file->page); hdr2.log_record_size = hdr.log_record_size; hdr2.log_records = hdr.log_records; write_header(&hdr2, new_file->page); new_file->flags &= ~COFFEE_FILE_MODIFIED; new_file->end = offset; cfs_close(fd); return 0; }
/*------Done in a subroutine to keep main routine stack usage small--------*/ void initialize(void) { #ifdef BUZZER buzz_id(); #endif watchdog_init(); watchdog_start(); clock_init(); PRINTD("\n\nChecking MCUSR...\n"); if(MCUSR & (1<<PORF )) PRINTD("Power-on reset.\n"); if(MCUSR & (1<<EXTRF)) PRINTD("External reset!\n"); if(MCUSR & (1<<BORF )) PRINTD("Brownout reset!\n"); if(MCUSR & (1<<WDRF )) PRINTD("Watchdog reset!\n"); if(MCUSR & (1<<JTRF )) PRINTD("JTAG reset!\n"); MCUSR = 0; PRINTD("CLOCK_SECOND %d\n",CLOCK_SECOND); PRINTD("RTIMER_ARCH_SECOND %lu\n",RTIMER_ARCH_SECOND); PRINTD("F_CPU %lu\n",F_CPU); #if STACKMONITOR /* Simple stack pointer highwater monitor. Checks for magic numbers in the main * loop. In conjuction with PERIODICPRINTS, never-used stack will be printed * every STACKMONITOR seconds. */ { extern uint16_t __bss_end; uint16_t p=(uint16_t)&__bss_end; do { *(uint16_t *)p = 0x4242; p+=10; } while (p<SP-10); //don't overwrite our own stack } #endif /* Calibrate internal mcu clock against external 32768Hz watch crystal */ #define CONF_CALIBRATE_OSCCAL 0 #if CONF_CALIBRATE_OSCCAL void calibrate_rc_osc_32k(); { extern uint8_t osccal_calibrated; uint8_t i; PRINTD("\nBefore calibration OSCCAL=%x\n",OSCCAL); for (i=0;i<10;i++) { calibrate_rc_osc_32k(); PRINTD("Calibrated=%x\n",osccal_calibrated); //#include <util/delay_basic.h> //#define delay_us( us ) ( _delay_loop_2(1+(us*F_CPU)/4000000UL) ) // delay_us(50000); } clock_init(); } #endif PRINTA("\n*******Booting %s*******\n",CONTIKI_VERSION_STRING); leds_init(); leds_on(LEDS_RED); /* Initialize USART */ #ifdef CAMERA_INTERFACE camera_init(); #else init_usart(); #endif /* rtimers needed for radio cycling */ rtimer_init(); /* Initialize process subsystem */ process_init(); /* etimers must be started before ctimer_init */ process_start(&etimer_process, NULL); #if RF2XXBB ds2401_init(); node_id_restore(); /* Get a random seed for the 802.15.4 packet sequence number. * Some layers will ignore duplicates found in a history (e.g. Contikimac) * causing the initial packets to be ignored after a short-cycle restart. */ random_init(rng_get_uint8()); ctimer_init(); init_net(); #else /* !RF2XXBB */ /* Original RF230 combined mac/radio driver */ /* mac process must be started before tcpip process! */ process_start(&mac_process, NULL); process_start(&tcpip_process, NULL); #endif /* RF2XXBB */ /* Autostart other 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 PRINTA("No index.html file found, creating upload.html!\n"); PRINTA("Formatting FLASH file system for coffee..."); cfs_coffee_format(); PRINTA("Done!\n"); fa = cfs_open( "/index.html", CFS_WRITE); int r = cfs_write(fa, &"It works!", 9); if (r<0) PRINTA("Can''t create /index.html!\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 /* COFFEE_FILES */ /* Add addresses for testing */ #if 0 { uip_ip6addr_t ipaddr; uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); uip_ds6_addr_add(&ipaddr, 0, ADDR_AUTOCONF); // uip_ds6_prefix_add(&ipaddr,64,0); } #endif /*--------------------------Announce the configuration---------------------*/ #if ANNOUNCE_BOOT { #if AVR_WEBSERVER uint8_t i; char buf1[40],buf[40]; unsigned int size; for (i=0;i<UIP_DS6_ADDR_NB;i++) { if (uip_ds6_if.addr_list[i].isused) { httpd_cgi_sprint_ip6(uip_ds6_if.addr_list[i].ipaddr,buf); PRINTA("IPv6 Address: %s\n",buf); } } cli(); eeprom_read_block (buf1,eemem_server_name, sizeof(eemem_server_name)); eeprom_read_block (buf,eemem_domain_name, sizeof(eemem_domain_name)); sei(); buf1[sizeof(eemem_server_name)]=0; PRINTA("%s",buf1); buf[sizeof(eemem_domain_name)]=0; size=httpd_fs_get_size(); #ifndef COFFEE_FILES PRINTA(".%s online with fixed %u byte web content\n",buf,size); #elif COFFEE_FILES==1 PRINTA(".%s online with static %u byte EEPROM file system\n",buf,size); #elif COFFEE_FILES==2 PRINTA(".%s online with dynamic %u KB EEPROM file system\n",buf,size>>10); #elif COFFEE_FILES==3 PRINTA(".%s online with static %u byte program memory file system\n",buf,size); #elif COFFEE_FILES==4 PRINTA(".%s online with dynamic %u KB program memory file system\n",buf,size>>10); #endif /* COFFEE_FILES */ #else PRINTA("Online\n"); #endif /* AVR_WEBSERVER */ #endif /* ANNOUNCE_BOOT */ } }