Esempio n. 1
0
/*---------------------------------------------------------------------------*/
static int
coffee_test_gc(void)
{
  int i;

  cfs_remove("alpha");
  cfs_remove("beta");


  for (i = 0; i < 100; i++) {
    if (i & 1) {
      if(cfs_coffee_reserve("alpha", random_rand() & 0xffff) < 0) {
	return i;
      }
      cfs_remove("beta");
    } else {
      if(cfs_coffee_reserve("beta", 93171) < 0) {
	return i;
      }
      cfs_remove("alpha");
    }
  }

  return 0;
}
Esempio n. 2
0
db_result_t
storage_drop_relation(relation_t *rel, int remove_tuples)
{
  if(remove_tuples && RELATION_HAS_TUPLES(rel)) {
    cfs_remove(rel->tuple_filename);
  }
  return cfs_remove(rel->name) < 0 ? DB_STORAGE_ERROR : DB_OK;
}
Esempio n. 3
0
db_result_t
storage_put_attribute(relation_t *rel, attribute_t *attr)
{
  int fd;
  struct attribute_record record;
  int r;

  PRINTF("DB: put_attribute(%s, %s)\n", rel->name, attr->name);

  fd = cfs_open(rel->name, CFS_WRITE | CFS_APPEND);
  if(fd < 0) {
    return DB_STORAGE_ERROR;
  }

  memset(&record.name, 0, sizeof(record.name));
  memcpy(record.name, attr->name, sizeof(record.name));
  record.domain = attr->domain;
  record.element_size = attr->element_size;
  r = cfs_write(fd, &record, sizeof(record));
  if(r != sizeof(record)) {
    cfs_close(fd);
    cfs_remove(rel->name);
    return DB_STORAGE_ERROR;
  }

  cfs_close(fd);
  return DB_OK;
}
Esempio n. 4
0
static void
serial_interrupt_checkpoint()
{
  int fd = 0;
  PAUSE_TIME();

  if(SPI_IS_ENABLED()) {
    /* SPI is busy, abort */
    PRINTF_COMMAND("CP:SPIBUSY\n");
    RESUME_TIME();
    return;
  }

  /* Open file */
  cfs_remove("cp");
  cfs_coffee_reserve("cp", checkpoint_arch_size());
  fd = cfs_open("cp", CFS_WRITE);

  if(fd < 0) {
    printf("ERROR: No file access (cp)\n");
    RESUME_TIME();
    return;
  }

  /* Checkpoint */
  preset_cmd = COMMAND_CHECKPOINT;
  preset_fd = fd;
  mt_exec(&checkpoint_thread);

  /* Close file */
  cfs_close(fd);

  RESUME_TIME();
}
Esempio n. 5
0
PROCESS_THREAD(example_coffee_process, ev, data)
{
  PROCESS_BEGIN();

#define SDCARD

#ifdef SDCARD
	uSDcard_init();
	printf("sdcard initialised.\n");
#endif

#if NEED_FORMATTING
  cfs_coffee_format();
#endif

  /* Ensure that we will be working with a new file. */
  cfs_remove(FILENAME);

  if (file_test(FILENAME, "The first test") == 0) {
    printf("file test 1 failed\n");
  }
  if (file_test(FILENAME, "The second test") == 0) {
    printf("file test 2 failed\n");
  }
  if (dir_test() == 0) {
    printf("dir test failed\n");
  }

  PROCESS_END();
}
Esempio n. 6
0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(shell_rm_process, ev, data)
{
  PROCESS_BEGIN();

  if(data != NULL) {
    cfs_remove(data);
  }
  PROCESS_END();
}
Esempio n. 7
0
/*---------------------------------------------------------------------------*/
static int
coffee_test_append(void)
{
  int error;
  int afd;
  unsigned char buf[256], buf2[11];
  int r, i, j, total_read;
#define APPEND_BYTES 1000
#define BULK_SIZE 10

  cfs_remove("T2");

  /* Test 1 and 2: Append data to the same file many times. */
  for(i = 0; i < APPEND_BYTES; i += BULK_SIZE) {
    afd = cfs_open("T3", CFS_WRITE | CFS_APPEND);
    if(afd < 0) {
      FAIL(1);
    }
    for(j = 0; j < BULK_SIZE; j++) {
      buf[j] = 1 + ((i + j) & 0x7f);
    }
    if((r = cfs_write(afd, buf, BULK_SIZE)) != BULK_SIZE) {
      printf("r=%d\n", r);
      FAIL(2);
    }
    cfs_close(afd);
  }

  /* Test 3-6: Read back the data written previously and verify that it 
     is correct. */
  afd = cfs_open("T3", CFS_READ);
  if(afd < 0) {
    FAIL(3);
  }
  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(4);
      }
    }
    total_read += r;
  }
  if(r < 0) {
    FAIL(5);
  }
  if(total_read != APPEND_BYTES) {
    FAIL(6);
  }
  cfs_close(afd);

  error = 0;
end:
  cfs_close(afd);
  return error;
}
Esempio n. 8
0
db_result_t
storage_rename_relation(char *old_name, char *new_name)
{
  db_result_t result;
  int old_fd;
  int new_fd;
  int r;
  char buf[64];

  result = DB_STORAGE_ERROR;
  old_fd = new_fd = -1;

  old_fd = cfs_open(old_name, CFS_READ);
  new_fd = cfs_open(new_name, CFS_WRITE);
  if(old_fd < 0 || new_fd < 0) {
    goto error;
  }

  for(;;) {
    r = cfs_read(old_fd, buf, sizeof(buf));
    if(r < 0) {
      goto error;
    } else if(r == 0) {
      break;
    }
    if(cfs_write(new_fd, buf, r) != r) {
      goto error;
    }
  };

  cfs_remove(old_name);
  result = DB_OK;

error:
  cfs_close(old_fd);
  cfs_close(new_fd);

  if(result != DB_OK) {
    cfs_remove(new_name);
  }
  return result;
}
Esempio n. 9
0
/* Remove file callback.
 * Responds to a SBP_MSG_FILEIO_REMOVE message.
 */
static void remove_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 < 2) || (msg[len-1] != '\0')) {
    log_error("Invalid fileio remove message!\n");
    return;
  }

  cfs_remove((char*)msg);
}
Esempio n. 10
0
int
logging_purge_logs(void)
{
  if(log_state != LOGGING_NOT_INIT && log_state != LOGGING_FATAL_ERROR){

    /* If writing to flash, then wait till we're done */
    while(log_state == LOGGING_BUSY){ ; }

    if(!cfs_remove(LOGGING_FILE_NAME)){
      /* removal successful */
      return 0;
    }
  }

  /* Some error occurred */
  return 1;
}
Esempio n. 11
0
/*---------------------------------------------------------------------------*/
static void
qbuf_renew_file(int file)
{
  int ret;
  char name[2];
  name[0] = 'a' + file;
  name[1] = '\0';
  if(qbuf_files[file].renewable == 1) {
    PRINTF("qbuf_renew_file: removing file %d\n", file);
    cfs_remove(name);
  }
  ret = cfs_open(name, CFS_READ | CFS_WRITE);
  if(ret == -1) {
    PRINTF("qbuf_renew_file: cfs open error\n");
  }
  qbuf_files[file].fd = ret;
  qbuf_files[file].usage = 0;
  qbuf_files[file].renewable = 0;
}
Esempio n. 12
0
/*---------------------------------------------------------------------------*/
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();
}
Esempio n. 13
0
/*---------------------------------------------------------------------------*/
static int
coffee_test_modify(void)
{
  int error;
  int wfd;
  unsigned char buf[256];
  int r, i;
  unsigned offset;

  cfs_remove("T3");
  wfd = -1;

  if(cfs_coffee_reserve("T3", FILE_SIZE) < 0) {
    FAIL(1);
  }

  if(cfs_coffee_configure_log("T3", FILE_SIZE / 2, 11) < 0) {
    FAIL(2);
  }

  /* 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(3);
    }

    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(4);
    }

    if(cfs_write(wfd, buf, sizeof(buf)) != sizeof(buf)) {
      FAIL(5);
    }

    if(cfs_seek(wfd, offset, CFS_SEEK_SET) != offset) {
      FAIL(6);
    }

    memset(buf, 0, sizeof(buf));
    if(cfs_read(wfd, buf, sizeof(buf)) != sizeof(buf)) {
      FAIL(7);
    }

    for(i = 0; i < sizeof(buf); i++) {
      if(buf[i] != i) {
        printf("buf[%d] != %d\n", i, buf[i]);
        FAIL(8);
      }
    }
  }

  error = 0;
end:
  cfs_close(wfd);
  return error;
}
Esempio n. 14
0
/*---------------------------------------------------------------------------*/
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();
}
Esempio n. 15
0
/* 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();
}
Esempio n. 16
0
/*---------------------------------------------------------------------------*/
static int
coffee_test_basic(void)
{
  int error;
  int wfd, rfd, afd;
  unsigned char buf[256];
  int r;

  cfs_remove("T1");

  wfd = rfd = afd = -1;

  for(r = 0; r < sizeof(buf); r++) {
    buf[r] = r;
  }

  /* Test 1: Open for writing. */
  wfd = cfs_open("T1", CFS_WRITE);
  if(wfd < 0) {
    FAIL(1);
  }

  /* Test 2 and 3: Write buffer. */
  r = cfs_write(wfd, buf, sizeof(buf));
  if(r < 0) {
    FAIL(2);
  } else if(r < sizeof(buf)) {
    FAIL(3);
  }

  /* Test 4: Deny reading. */
  r = cfs_read(wfd, buf, sizeof(buf));
  if(r >= 0) {
    FAIL(4);
  }

  /* Test 5: Open for reading. */
  rfd = cfs_open("T1", CFS_READ);
  if(rfd < 0) {
    FAIL(5);
  }

  /* Test 6: Write to read-only file. */
  r = cfs_write(rfd, buf, sizeof(buf));
  if(r >= 0) {
    FAIL(6);
  }

  /* Test 7 and 8: Read the buffer written in Test 2. */
  memset(buf, 0, sizeof(buf));
  r = cfs_read(rfd, buf, sizeof(buf));
  if(r < 0) {
    FAIL(7);
  } else if(r < sizeof(buf)) {
    printf("r=%d\n", r);
    FAIL(8);
  }

  /* Test 9: Verify that the buffer is correct. */
  for(r = 0; r < sizeof(buf); r++) {
    if(buf[r] != r) {
      printf("r=%d. buf[r]=%d\n", r, buf[r]);
      FAIL(9);
    }
  }

  /* Test 10: Seek to beginning. */
  if(cfs_seek(wfd, 0, CFS_SEEK_SET) != 0) {
    FAIL(10);
  }

  /* Test 11 and 12: Write to the log. */
  r = cfs_write(wfd, buf, sizeof(buf));
  if(r < 0) {
    FAIL(11);
  } else if(r < sizeof(buf)) {
    FAIL(12);
  }

  /* Test 13 and 14: 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);
  }

  /* Test 16: Verify that the data is correct. */
  for(r = 0; r < sizeof(buf); r++) {
    if(buf[r] != r) {
      FAIL(16);
    }
  }

  /* Test 17 to 20: 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);
  }

  /* Test 21 and 22: 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("r = %d\n", r);
    FAIL(22);
  }

  /* Test 23: Verify that the data is correct. */
  for(r = 0; r < sizeof(buf); r++) {
    if(buf[r] != sizeof(buf) - r - 1) {
      FAIL(23);
    }
  }

  error = 0;
end:
  cfs_close(wfd);
  cfs_close(rfd);
  return error;
}
Esempio n. 17
0
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;
}
Esempio n. 18
0
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();
}
Esempio n. 19
0
void handle_remove_file(char* name)
{
    log_info("handle_remove_file(%s)\n", name);
    cfs_remove(name);
}
Esempio n. 20
0
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;
}
Esempio n. 21
0
/* Initialize a test relation using Contiki Filesystem interface. */
db_int init_cfs_test_relations(char *relationname, db_int numattr,
				db_int numtuples, db_int bound, db_int seed, db_int type)
{
	/* General variable declarations. */
	char charWrite;
	db_int intWrite;
	char offset = 0;
	char size = 0;
	int cfs_fd;
	cfs_remove(relationname);
	db_int i, j;
	// Allocate enough room for any integer.
	char attrname[5 + integerlength((db_int)DB_INT_MAX)];
	
	/* Seed the random number generator to always generate the same
	   relation. */
	random_init(seed);
	/**** Create the new relation. ****/ 
	size = 0;
	offset = 0;
	//cfs_coffee_reserve(relationname, 100);
	cfs_fd = cfs_open(relationname, CFS_WRITE);
	if (0 > cfs_fd)
	{
		printf("Could not open file for writing.\n");
		return -1;
	}
	
	/* Write out the number of attributes into the relation. */
	charWrite = numattr;
	cfs_write(cfs_fd, &charWrite, 1*sizeof(char));
	
	/** Header information for all attributes. **/
	for (i = 0; i < numattr; ++i)
	{
		/* Size of name. */
		charWrite = 5 + integerlength(i);
		cfs_write(cfs_fd, &charWrite, 1*sizeof(char));
		
		sprintf(attrname, "attr%d", i);
		/* Attribute name. */
		cfs_write(cfs_fd, attrname, (strlen(attrname)+1)*sizeof(char));
		
		/* Attribute type. */
		charWrite = 0;
		cfs_write(cfs_fd, &charWrite, 1*sizeof(char));
		
		/* Attribute offset. */
		offset += size;
		cfs_write(cfs_fd, &offset, 1*sizeof(char));
		
		/* Attribute size. */
		size = (char)sizeof(db_int);
		cfs_write(cfs_fd, &size, 1*sizeof(char));
	}
	
	db_int autoid = 0;
	/*** Write out tuples. ***/
	for (i = 0; i < numtuples; ++i)
	{
		/* Determine size of isnull array. */
		db_int isnull_size = numattr / 8;
		if (0 < numattr % 8)
			isnull_size++;
		/* Write out isnull bit array. */
		for (j = 0; j < isnull_size; ++j)
		{
			charWrite = 0x0;
			cfs_write(cfs_fd, &charWrite, 1*sizeof(char));
		}
		
		/* Write out attributes. */
		for (j = 0; j < numattr; ++j)
		{
			if (1 == type && 0==j)
			{
				intWrite = autoid;
				autoid++;
			}
			else
			{
				intWrite = (db_int)((random_rand()) % bound);
			}
			cfs_write(cfs_fd, &intWrite, 1*sizeof(db_int));
		}
	}
	
	cfs_close(cfs_fd);
	/* Write out index data, if necessary. */
	if (1==type)
	{
		/* General variable declaration. */
		long longWrite;
		db_fileref_t file;
		db_eet_t eet;
		db_eetnode_attr_t attr;
		char *tempname[100];
		
		sprintf(tempname, "DB_IDXM_%s", relationname);
		file = db_openwritefile(tempname);
		
		if (file == DB_STORAGE_NOFILE)
		{
			puts("CAN'T OPEN IDXM FILE!");
			return -1;
		}
		
		/* Write out the number of indexes for this relation.  */
		charWrite = 1;
		db_filewrite(file, &charWrite, sizeof(char));
		
		/* Write out the length (including \0) of index name. */
		charWrite = 2+strlen(relationname);
		db_filewrite(file, &charWrite, sizeof(char));
		
		sprintf(tempname, "i%s", relationname);
		
		/* Index name.*/
		db_filewrite(file, tempname, charWrite);
		
		/* Write out the number of expressions for this index.  */
		charWrite = 1;
		db_filewrite(file, &charWrite, sizeof(char));
		
		/* Write out the expression. */
		eet.size = sizeof(db_eetnode_attr_t);
		eet.stack_size = sizeof(db_eetnode_dbint_t);
		db_filewrite(file, (unsigned char*)(&eet), sizeof(db_eet_t));
		attr.base.type = DB_EETNODE_ATTR;
		attr.pos = 0;
		attr.tuple_pos = 0;
		db_filewrite(file, (unsigned char*)(&attr), sizeof(db_eetnode_attr_t));
		
		db_fileclose(file);
		
		sprintf(tempname, "DB_IDX_i%s", relationname);
		file = db_openwritefile(tempname);
		
		if (file == DB_STORAGE_NOFILE)
		{
			puts("CAN'T OPEN IDX FILE!");
			return -1;
		}
		
		/* Write out index type. */
		charWrite = DB_INDEX_TYPE_INLINE;
		db_filewrite(file, (unsigned char*)&charWrite, sizeof(char));
		
		/* Write out number of records. */
		longWrite = numtuples;
		db_filewrite(file, (unsigned char*)&longWrite, sizeof(long));
		
		db_fileclose(file);
	}
	return 0;
}
Esempio n. 22
0
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();
}
Esempio n. 23
0
/*---------------------------------------------------------------------------*/
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();
}