struct fat_file_struct* openFile(char * file){
	if (dd == 0){
		return 0;
	}
	// printf("openFID\r\n");
	struct fat_file_struct* fd = open_file_in_dir((struct fat_fs_struct*)fs, (struct fat_dir_struct*)dd, file);
	// printf("check fd\r\n");
	if (!fd){
		struct fat_dir_entry_struct file_entry;
		// printf_P(PSTR("making file...\r\n"));
		// for (int i = 0; i < strlen(file); i++){
			// printf("%d", file[i]);
			// printf(" ");
		// }
		// printf("\r\n");
		if(!fat_create_file((struct fat_dir_struct*)dd, file, &file_entry)){
			printf_P(PSTR("failed to create file\r\n"));
			return 0;
		}
		// printf("created file!");
		fd = open_file_in_dir((struct fat_fs_struct*)fs, (struct fat_dir_struct*)dd, file);
		if (!fd){
			printf_P(PSTR("failed to get file\r\n"));
			return 0;
		}
	}
	return fd;
}
Exemple #2
0
// START FUNC DECL
int
mk_temp_file(
    size_t filesz,
    char *dir,
    char *filename
    )
// STOP FUNC DECL
{
  int status = 0;
  extern char cwd[MAX_LEN_DIR_NAME+1];

  if ( getcwd(cwd, MAX_LEN_DIR_NAME) == NULL ) { go_BYE(-1); } 
  if ( filesz < 0 ) { go_BYE(-1); }
  if ( ( dir == NULL ) || ( *dir == '\0' ) )   { go_BYE(-1); }
  if ( ( filename == NULL ) || ( *filename == '\0' ) )  { go_BYE(-1); }
  status = get_disk_space(dir, &free_space, "free_space"); cBYE(status);
  if ( free_space < filesz ) { go_BYE(-1); }

  // Make empty file with that name 
  status = open_file_in_dir(cwd, dir, filename, filesz); cBYE(status);
  // Stretch it to appropriate size
  status = mk_file(cwd, dir, filename, filesz); cBYE(status);
BYE:
  return(status);
}
Exemple #3
0
/* See documentation in header file. */
int ini_parse(const char* filename,
              int (*handler)(void*, const char*, const char*, const char*),
              void* user,
			  struct fat_fs_struct* fs,
			  struct fat_dir_struct* dd)
{
    struct fat_file_struct* file;
    int error;

    file = open_file_in_dir(fs, dd, filename);
    if (!file) {
		printf("error opening file\r\n");
        return -1;
	}
    error = ini_parse_file(file, handler, user);
    fat_close_file(file);
    return error;
}
int main (){
    int maxfd, listenfd, connfd, nread, i;
    char c = 'C';
    char temp;
    char *after;
    unsigned short block_crc;
    unsigned char char_block, crc_first, crc_second;
    char *dirname = "filestore";
    struct client *top = malloc(sizeof (struct client));
    top->fd = -1;
    top->next = NULL;
    struct client *p;
    fd_set allset;
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr;
    listenfd = Socket(PF_INET, SOCK_STREAM, 0);
    memset(&servaddr, '\0', sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(PORT);
    
    Bind (listenfd, (struct sockaddr *) &servaddr, sizeof (servaddr));
    Listen (listenfd, LISTENQ);
    while(1){
        fprintf(stderr, "Time to Select\n");
        maxfd = listenfd;
        FD_ZERO (&allset);
        FD_SET(listenfd, &allset);
        //loop through the linked list of clients to refresh the allset
        for (p = top; p->fd >=0; p = p->next){
            FD_SET (p->fd, &allset);
            if (p->fd > maxfd) maxfd = p->fd; //if the fd is larger than the maxfd, change maxfd.
        }
        Select(maxfd+1, &allset, NULL, NULL, NULL);
        //loop through the linked list until the fd corresponding to the client that is set is found
        for (p = top; p->fd >=0; p = p->next){
            if (FD_ISSET(p->fd, &allset)) break;
        }
        //if it is our listening socket then a new client has come
        if (FD_ISSET(listenfd, &allset)){ 
            newconnection(listenfd, &top);
        }
        // otherwise its one of our old clients
        else if(!p){ //if p is null, we have a problem
            fprintf(stderr,"uhoh\n");
            exit(1);
        }
        // if p exists, then we go through the states
        else {
            if(p){
                if (p->state == initial){
                    fprintf(stderr, "initial reading from client\n");
                    // read as many as you can up to 20 characters, leaving off where it last wrote
                    nread = read(p->fd, &(p->buf[p->inbuf]), sizeof(char)*(20 - p->inbuf));
                    if(nread<0){
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    //use inbuf as an index of where to write next, and how much more can be written
                    p->inbuf = p->inbuf + nread;
                    //transfer stuff in buf to filename until a network newline is reached
                    for (i = 0; i < 20; i++){
                        p->filename[i] = p->buf[i];
                        if (p->buf[i] == '\r'){ //once the network newline is found
                            p->filename[i] = '\0';//place a null character to end the string
                            p->state = pre_block; //change states
                            p->fp = open_file_in_dir(p->filename, dirname);  //open a file
                            p->inbuf = 0;// reset inbuf to be 0, going to write over buf from 0 index
                            if (write(p->fd, &c, 1)<0){ //send 'C' to client
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                            break;
                        }
                    }
                    //if the network newline is not found in the 20 characters sent by client, error in filename, drop client
                    if (p->inbuf == 20){
                        fprintf(stderr, "filename was not found. filename must be less than 20 characters\n");
                        removeclient(p->fd, &top);
                    }
                }
                if (p->state == pre_block){
                    fprintf(stderr, "pre_block readering from client \n"); 
                    nread = read(p->fd, &temp, 1); //read a single character
                    if(nread<0){ //if there was a problem with nread then drop the client
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    if (temp== EOT){
                        temp = ACK;
                        if (write(p->fd, &temp, 1)<0){
                            perror("write");
                            removeclient(p->fd, &top);
                        }
                        fprintf(stderr, "finished\n");
                        removeclient(p->fd, &top);
                    }
                    if (temp == SOH){
                        p->blocksize = 132;
                        p->state = get_block;
                    }
                    if (temp == STX){
                        p->blocksize = 1028;
                        p->state = get_block;
                    }
                }
                if (p->state == get_block){
                    fprintf(stderr, "get_block readering from client \n"); 
                    /* reads into the buffer as much as it can upto the blocksize of the client
                     * and continues writing where it left off*/
                    nread = read(p->fd, &(p->buf[p->inbuf]), p->blocksize - p->inbuf);
                    if(nread < 0){
                        perror("read");
                        removeclient(p->fd, &top);
                    }
                    p->inbuf = p->inbuf + nread;
                    //once the entire block is received, go to the next state;
                    if (p->inbuf == p->blocksize) p->state = check_block;
                }
                if (p->state == check_block){
                    fprintf(stderr, "checking_block  client \n"); 
                    char_block = p->current_block;
                    /*removes client if block number and inverse don't match or block number is not
                     * what was expected. however if the blocknum is a previously received block num, send ack*/
                    if (255 - p->buf[0] !=  p->buf[1]){
                        fprintf(stderr, "block number and inverse do not match\n");
                        removeclient(p->fd, &top);
                    }
                    else if (char_block > p->buf[0]){
                        temp = ACK;
                        if(write(p->fd, &temp, 1)<0){
                            perror("write");
                            removeclient(p->fd, &top);
                        }
                    }
                    else if (char_block != p->buf[0]){
                        fprintf(stderr, "char_block is not correct\n");
                        removeclient(p->fd, &top);
                    }
                    //otherwise, need to check crc
                    else{
                        block_crc = crc_message (XMODEM_KEY, &(p->buf[2]), p->blocksize - 4);
                        crc_first = block_crc>>8;
                        crc_second = block_crc;
                        if ((crc_first != p->buf[p->blocksize -2]) || (crc_second != p->buf[p->blocksize -1])){
                            fprintf(stderr, "crc does not match \n");
                            temp = NAK;
                            if(write(p->fd, &temp, 1) < 0){
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                        }
                        else{
                            temp = ACK;
                            fprintf(stderr, "writing to client ACK\n");
                            if (write (p->fd, &temp, 1)<0){
                                perror("write");
                                removeclient(p->fd, &top);
                            }
                           
                            if(fwrite(&(p->buf[2]), p->blocksize-4, 1, p->fp)<0){
                                perror("write");
                                exit(1);
                            }
                            p->state = pre_block;
                            p->current_block ++;
                            p->inbuf = 0;
                            if(p->current_block > 255) p->current_block = 1;
                        }
                    }
                }
            }
        }
    }
Exemple #5
0
int main()
{
    /* we will just use ordinary idle mode */
    set_sleep_mode(SLEEP_MODE_IDLE);

    /* setup uart */
    uart_init();

    while(1)
    {


        /* setup sd card slot */
        if(!sd_raw_init())
        {
#if DEBUG
            uart_puts_p(PSTR("MMC/SD initialization failed\n"));
#endif
            continue;
        }

        /* open first partition */
        struct partition_struct* partition = partition_open(sd_raw_read,
                                                            sd_raw_read_interval,
#if SD_RAW_WRITE_SUPPORT
                                                            sd_raw_write,
                                                            sd_raw_write_interval,
#else
                                                            0,
                                                            0,
#endif
                                                            0
                                                           );

        if(!partition)
        {
            /* If the partition did not open, assume the storage device
             * is a "superfloppy", i.e. has no MBR.
             */
            partition = partition_open(sd_raw_read,
                                       sd_raw_read_interval,
#if SD_RAW_WRITE_SUPPORT
                                       sd_raw_write,
                                       sd_raw_write_interval,
#else
                                       0,
                                       0,
#endif
                                       -1
                                      );
            if(!partition)
            {
#if DEBUG
                uart_puts_p(PSTR("opening partition failed\n"));
#endif
                continue;
            }
        }

        /* open file system */
        struct fat_fs_struct* fs = fat_open(partition);
        if(!fs)
        {
#if DEBUG
            uart_puts_p(PSTR("opening filesystem failed\n"));
#endif
            continue;
        }

        /* open root directory */
        struct fat_dir_entry_struct directory;
        fat_get_dir_entry_of_path(fs, "/", &directory);

        struct fat_dir_struct* dd = fat_open_dir(fs, &directory);
        if(!dd)
        {
#if DEBUG
            uart_puts_p(PSTR("opening root directory failed\n"));
#endif
            continue;
        }

        /* print some card information as a boot message */
        print_disk_info(fs);

        /* provide a simple shell */
        char buffer[24];
        while(1)
        {
            /* print prompt */
            uart_putc('>');
            uart_putc(' ');

            /* read command */
            char* command = buffer;
            if(read_line(command, sizeof(buffer)) < 1)
                continue;

            /* execute command */
            if(strcmp_P(command, PSTR("init")) == 0)
            {
                break;
            }
            else if(strncmp_P(command, PSTR("cd "), 3) == 0)
            {
                command += 3;
                if(command[0] == '\0')
                    continue;

                /* change directory */
                struct fat_dir_entry_struct subdir_entry;
                if(find_file_in_dir(fs, dd, command, &subdir_entry))
                {
                    struct fat_dir_struct* dd_new = fat_open_dir(fs, &subdir_entry);
                    if(dd_new)
                    {
                        fat_close_dir(dd);
                        dd = dd_new;
                        continue;
                    }
                }

                uart_puts_p(PSTR("directory not found: "));
                uart_puts(command);
                uart_putc('\n');
            }
            else if(strcmp_P(command, PSTR("ls")) == 0)
            {
                /* print directory listing */
                struct fat_dir_entry_struct dir_entry;
                while(fat_read_dir(dd, &dir_entry))
                {
                    uint8_t spaces = sizeof(dir_entry.long_name) - strlen(dir_entry.long_name) + 4;

                    uart_puts(dir_entry.long_name);
                    uart_putc(dir_entry.attributes & FAT_ATTRIB_DIR ? '/' : ' ');
                    while(spaces--)
                        uart_putc(' ');
                    uart_putdw_dec(dir_entry.file_size);
                    uart_putc('\n');
                }
            }
            else if(strncmp_P(command, PSTR("cat "), 4) == 0)
            {
                command += 4;
                if(command[0] == '\0')
                    continue;

                /* search file in current directory and open it */
                struct fat_file_struct* fd = open_file_in_dir(fs, dd, command);
                if(!fd)
                {
                    uart_puts_p(PSTR("error opening "));
                    uart_puts(command);
                    uart_putc('\n');
                    continue;
                }

                /* print file contents */
                uint8_t buffer[8];
                uint32_t offset = 0;
                while(fat_read_file(fd, buffer, sizeof(buffer)) > 0)
                {
                    uart_putdw_hex(offset);
                    uart_putc(':');
                    for(uint8_t i = 0; i < 8; ++i)
                    {
                        uart_putc(' ');
                        uart_putc_hex(buffer[i]);
                    }
                    uart_putc('\n');
                    offset += 8;
                }

                fat_close_file(fd);
            }
            else if(strcmp_P(command, PSTR("disk")) == 0)
            {
                if(!print_disk_info(fs))
                    uart_puts_p(PSTR("error reading disk info\n"));
            }
#if FAT_WRITE_SUPPORT
            else if(strncmp_P(command, PSTR("rm "), 3) == 0)
            {
                command += 3;
                if(command[0] == '\0')
                    continue;

                struct fat_dir_entry_struct file_entry;
                if(find_file_in_dir(fs, dd, command, &file_entry))
                {
                    if(fat_delete_file(fs, &file_entry))
                        continue;
                }

                uart_puts_p(PSTR("error deleting file: "));
                uart_puts(command);
                uart_putc('\n');
            }
            else if(strncmp_P(command, PSTR("touch "), 6) == 0)
            {
                command += 6;
                if(command[0] == '\0')
                    continue;

                struct fat_dir_entry_struct file_entry;
                if(!fat_create_file(dd, command, &file_entry))
                {
                    uart_puts_p(PSTR("error creating file: "));
                    uart_puts(command);
                    uart_putc('\n');
                }
            }
            else if(strncmp_P(command, PSTR("write "), 6) == 0)
            {
                command += 6;
                if(command[0] == '\0')
                    continue;

                char* offset_value = command;
                while(*offset_value != ' ' && *offset_value != '\0')
                    ++offset_value;

                if(*offset_value == ' ')
                    *offset_value++ = '\0';
                else
                    continue;

                /* search file in current directory and open it */
                struct fat_file_struct* fd = open_file_in_dir(fs, dd, command);
                if(!fd)
                {
                    uart_puts_p(PSTR("error opening "));
                    uart_puts(command);
                    uart_putc('\n');
                    continue;
                }

                int32_t offset = strtolong(offset_value);
                if(!fat_seek_file(fd, &offset, FAT_SEEK_SET))
                {
                    uart_puts_p(PSTR("error seeking on "));
                    uart_puts(command);
                    uart_putc('\n');

                    fat_close_file(fd);
                    continue;
                }

                /* read text from the shell and write it to the file */
                uint8_t data_len;
                while(1)
                {
                    /* give a different prompt */
                    uart_putc('<');
                    uart_putc(' ');

                    /* read one line of text */
                    data_len = read_line(buffer, sizeof(buffer));
                    if(!data_len)
                        break;

                    /* write text to file */
                    if(fat_write_file(fd, (uint8_t*) buffer, data_len) != data_len)
                    {
                        uart_puts_p(PSTR("error writing to file\n"));
                        break;
                    }
                }

                fat_close_file(fd);
            }
            else if(strncmp_P(command, PSTR("mkdir "), 6) == 0)
            {
                command += 6;
                if(command[0] == '\0')
                    continue;

                struct fat_dir_entry_struct dir_entry;
                if(!fat_create_dir(dd, command, &dir_entry))
                {
                    uart_puts_p(PSTR("error creating directory: "));
                    uart_puts(command);
                    uart_putc('\n');
                }
            }
#endif
#if SD_RAW_WRITE_BUFFERING
            else if(strcmp_P(command, PSTR("sync")) == 0)
            {
                if(!sd_raw_sync())
                    uart_puts_p(PSTR("error syncing disk\n"));
            }
#endif

            else if(strcmp_P(command, PSTR("sync")) == 0)
            {
                // vytvor adresar mereni_teploty

                // nekonecna smycka - pomoci RTCka kazdou minutu odmer teplotu
            }


            else
            {
                uart_puts_p(PSTR("unknown command: "));
                uart_puts(command);
                uart_putc('\n');
            }
        }

        /* close directory */
        fat_close_dir(dd);

        /* close file system */
        fat_close(fs);

        /* close partition */
        partition_close(partition);
    }

    return 0;
}
void loop()
{
  int bytes_read=0; //Keeps track of how many bytes are read when accessing a file on the SD card.
  
  //Init Timer 1
  //Used for 45uS Interrupt
  TCCR1A = 0;		//Set Timer to normal mode
  TCCR1B = 0x0A;	//Set Timer clock to 2 MHz. Clear timer on compare
  TIMSK1 = 0x02;	//Enable Timer 1 Compare A Interrupt;
  OCR1AH = 0X00;	//Count to 90 before triggering an interrupt. Counting to 90 with a 2MHz clock makes
  OCR1AL = 0x5A;    //the interrupt trigger at 22.222kHz
  
  init_filesystem();	//Initialize the FAT16 file system on the SD card.

  if(get_wav_filename(dd, file_name));	//Find the first WAV file on the SD card (must be in the root directory)
  else while(1);	//If a WAV file isn't found then the sketch is stopped here.
  
  //Open the file	
  file_handle=open_file_in_dir(fs, dd, file_name);
  //Read the header information. Alternate purpose is to get to the DATA offset of the file.
  read_wav_header(file_handle, header);
  //Set the initial play buffer, and grab the initial data from the SD card.
  play_buffer=0;
  bytes_read = fat_read_file(file_handle, buffer1, BUFFERSIZE);
  bytes_read = fat_read_file(file_handle, buffer2, BUFFERSIZE);
  //Enable interrupts to start the wav playback.
  sei();
  while(1){
    if(need_new_data==1)	//need_new_data flag is set by ISR to indicate a buffer is empty and should be refilled
    {
      need_new_data=0;	//Clear the flag.
      if(play_buffer==0)	//play_buffer indicates which buffer is now empty
      {
        //Get the next BUFFERSIZE bytes from the file.
        bytes_read = fat_read_file(file_handle, buffer1, BUFFERSIZE);
      }
      else
      {
        //Get the next BUFFERSIZE bytes from the file.
        bytes_read = fat_read_file(file_handle, buffer2, BUFFERSIZE);
      }
      new_buffer_ready=1;	//new_buffer_ready flag tells the ISR that the buffer has been filled.
			
      //If file_read returns 0 or -1 file is over. Find the next file!
      if(bytes_read<=0)
      {
        cli();	//Disable interrupts to stop playback.
        fat_close_file(file_handle);	//Close the current file
        //Find the next WAV file in the SD card
        fat_reset_dir(dd);	//Make sure we start searching from the beginning of the directory
        find_file_in_dir(fs, dd, file_name, &dir_entry);	//Navigate to the current file in the directory
        if(get_wav_filename(dd, file_name));
        else while(1);	//If we don't find another wav file, stop everything!
				
        //If we get here we've found another wav file. Open it!
        file_handle=open_file_in_dir(fs, dd, file_name);
        //Get the file header and load the initial song data.
        read_wav_header(file_handle, header);
        play_buffer=0;
        bytes_read = fat_read_file(file_handle, buffer1, BUFFERSIZE);
        bytes_read = fat_read_file(file_handle, buffer2, BUFFERSIZE);
        sei();	//Start playing the song
      }
    }
  }
  
}
int main() {
    int listenfd, clientfd, maxfd;
    fd_set cset, rset;
    Client *clients = NULL;
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr;
    int one = 1;

    unsigned char temp_block_num, temp_block_inverse;
    unsigned short temp_crc, block_crc;
    char temp = 'C';

    /*If a client disconnects while we are writing an ACK/NAK to them it sends
     * a SIGPIPE which needs to be taken care of
     */
    signal(SIGPIPE, SIG_IGN);


    //Setup the main listening socket
    listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(PORT);

    if ((setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)))
            == -1) {
        perror("setsockopt");
    }
    Bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));

    Listen(listenfd, 5);
    FD_ZERO(&cset);
    FD_SET(listenfd, &cset);
    maxfd = listenfd;


    while (1) {
        /*
        * Accept any clients that want to connect.
        */
        rset = cset;
        Select(maxfd + 1, &rset, NULL, NULL, 0);

        // Check for new clients.
        if (FD_ISSET(listenfd, &rset)) {
            printf("New Client Connected\n");
            Client *temp = Malloc(sizeof(Client));
            clilen = sizeof(cliaddr);
            clientfd = Accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
            FD_SET(clientfd, &cset);
            if (clientfd > maxfd) {
                maxfd = clientfd;
            }

            // Populate the client struct with default starter data.
            temp->fd = clientfd;
            temp->inbuf = 0;
            temp->state = initial;
            temp->next = start;
            temp->prev = NULL;
            if (start) {
                start->prev = temp;
            }
            start = temp;
            continue;
        }

        /*
         * Loop through all the clients in the linked list,
         * checking their file descriptors for activity.
         */

        clients = start;
        while (clients) {
            clientfd = clients->fd;
            if (FD_ISSET(clientfd, &rset)) {
                /*
                 * Using switch statement for states is too messy in terms of proper flow control
                 * so just using if statements instead; they're cleaner and easier to follow.
                 */
                if (clients->state == initial) {

                    // Read name of the file being sent.
                    clients->inbuf += Read(clientfd, &(clients->filename)[clients->inbuf], 20 - clients->inbuf);

                    if (find_network_newline(clients->filename, clients->inbuf) > 0) {

                        clients->filename[clients->inbuf - 2] = '\0';

                        // Open/create a file with the name.
                        clients->fp = open_file_in_dir(clients->filename, FILE_DIR);

                        // Assign defaults to client struct.
                        clients->state = pre_block;
                        clients->inbuf = 0;
                        clients->current_block = 1;

                        // Let the client know that the server is ready for the data.
                        temp = 'C';
                        Write(clientfd, &temp, 1);
                    }
                }

                if (clients->state == pre_block) {
                    // Find out what state the client is in.
                    Read(clientfd, (clients->buf), 1);
                    switch (clients->buf[0]) {
                    case EOT:
                        clients->state = finished;
                        break;
                    case SOH:
                        clients->state = get_block;
                        clients->blocksize = 132;
                        break;
                    case STX:
                        clients->state = get_block;
                        clients->blocksize = 1028;
                        break;
                    default:
                        temp = NAK;
                        Write(clientfd, &temp, 1);
                    }

                }

                if (clients->state == get_block) {
                    // Keep getting more of the payload till you have the required minimum amount.
                    clients->inbuf += Read(clientfd, (clients->buf) + (clients->inbuf), clients->blocksize - clients->inbuf);
                    if (clients->inbuf == clients->blocksize) {
                        clients->state = check_block;
                    }
                }

                if (clients->state == check_block) {
                    // Fetch block numbers from the packet.
                    temp_block_num = (clients->buf)[0];
                    temp_block_inverse = (clients->buf)[1];

                    // Make sure the block numbers are correct - drop the client if they're not.
                    if ((temp_block_num != (255 - temp_block_inverse) || (temp_block_num > clients->current_block))) {
                        FD_CLR(clientfd, &cset);
                        clients = drop_client(clients);
                        /*
                         * Since drop_client gives us the client after the one we dropped,
                         * we use continue to go back to start of the loop.
                         */
                        break;
                    }

                    // Fetch and assemble the CRC given by client for the payload recieved.
                    temp_crc = 0;
                    temp_crc = (unsigned char)(clients->buf)[(clients->blocksize) - 2];
                    temp_crc <<= 8;
                    temp_crc |= (unsigned char)((clients->buf)[(clients->blocksize) - 1]);

                    // Calculate the actual CRC for the payload recieved.
                    block_crc = crc_message(XMODEM_KEY, (unsigned char *)((clients->buf) + 2), (clients->blocksize) - 4);

                    // Compare the given and calculated CRC to ensure payload integrity.
                    if ((temp_block_num == clients->current_block) && (temp_crc == block_crc)) {

                        printf("File: %s \t Block:%d Successfully recieved\n", clients->filename, clients->current_block);

                        // Write the payload to file if CRCs match
                        if (fwrite((clients->buf) + 2, 1, ((clients->blocksize) - 4), clients->fp) == 0) {
                            perror("Write to File error");
                            exit(-1);
                        }

                        // Send the client an ACK
                        temp = ACK;
                        Write(clientfd, &temp, 1);

                        // Increment service side block number counter and prepare for next block.
                        clients->state = pre_block;
                        clients->current_block += 1;

                        // Deal w/ wrap around when block number hits 255.
                        if (clients->current_block == 256) {
                            clients->current_block = 0;
                        }

                        // Reset the buffer position.
                        clients->inbuf = 0;

                    } else if (temp_crc != block_crc) {
                        printf("File: %s \t Block:%d CRC mismatch.\nExpected:%x, Got %x\n",
                         clients->filename, clients->current_block, temp_crc, block_crc);

                        // Sent the client a NAK if the CRCs didn't match and prepare for repeat block.
                        temp = NAK;
                        Write(clientfd, &temp, 1);
                        clients->state = pre_block;
                        clients->inbuf = 0;

                    } else if (temp_block_num < clients->current_block) {

                        // If we got a repeat block, just send the client an ACK.
                        temp = ACK;
                        Write(clientfd, &temp, 1);

                    }
                }

                if (clients->state == finished) {
                    printf("File Transfer Finished: %s\n", clients->filename);

                    // Cleanup after the client when transfer is finished.
                    // Send the client a final ACK.
                    temp = ACK;
                    Write(clientfd, &temp, 1);

                    // Remove the client and their socket from our list/set of clients.
                    FD_CLR(clientfd, &cset);
                    clients = drop_client(clients);

                }
            }

            // Move on to the next client in the list (if any).
            if (clients) {
                clients = clients->next;
            }

        }
    }

}
File AF_Wave::open_file(char *name) {
  return open_file_in_dir(fs, dd, name);
}
void FAT::open()
{
	_file_handle=open_file_in_dir(_fs, _dd, _file_name);
}
Exemple #10
0
/* A helper function for processing a client. This functions covers all states
   except the finished state. This function takes in the argument toplist (the
   top of the linked list, and cl, the current client node/struct. */
int processclient(struct client *cl)
{
	/* Variable used for writing ACK, NAK, and other exciting control codes */
	char acker;

	switch (cl->state) {
	/* If client is in the initial state */
	case initial: 
	{	/* Variable to determine if network newline has been found */
		int readin = 0;

		/* Read in one byte at a time so that the read() call doesn't block, top when
		   network newline has been found and add a null terminator at the end of the
		   filename. */
		memset(cl->filename, 0, 20);
		if (read(cl->fd,  &cl->filename, 20) <= 0) {
			/*XXX*/
			return 0;
		}
		printf("%s:%d--->filename: %s\n", __func__, __LINE__, cl->filename);
		readin = 1;

		/* If filename is completely read in, use helper.c to generate the file
		   pointer for it, reset the buffer index, and transition to pre_block state */
		if ( readin == 1) {
			cl->fp = open_file_in_dir(cl->filename, "storage");
			cl->inbuf = 0;
			cl->state = pre_block;
		}

		/* Write "C" to the client so it can move on with its transfer, if write
		   fails, drop client by transitioning to finished block */
		if ( write(cl->fd, "C", 1) < 1) {
			perror("Writing C failed");
			cl->state = finished;
		}
	}
		break;
	/* If client is in the pre_block state */
	case pre_block:
	{	/* Temporary buffer to hold in any incoming control codes. 2048 is 
		   overkill, yes, however it can't hurt to be safe. */
		char prebuf[2048];

		/* Read in one byte at a time from the client */
		if (read(cl->fd, &prebuf[0], 1) == 1) {
			printf("*");

			/* If EOT is received, drop client by transitioning to finish state */
			if (prebuf[cl->inbuf] == EOT) {

				/* Close file pointer */
				fclose(cl->fp);

				/* Set acker to ACK control code and write it to the client */
				acker = ACK;
				printf("receiver successful\n");
				if (write(cl->fd, &acker, sizeof(char)) < 1) {
					perror("writing ACK for EOT in pre_block failed");
				}

				cl->state = finished;
			}

			/* If SOH block is received, set the expected blocksize on client to 128, 
			   and transition to get_block */
			if (prebuf[0] == SOH) {
				cl->blocksize = 128;
				cl->state = get_block;

			}

			/* If STX block is received, set the expected blocksize on client to 1024, 
			   and transition to get_block */
			if (prebuf[0] == STX) {
				cl->blocksize = 1024;
				cl->state = get_block;

			}
		} else {
			perror("pre_block read fail");

		}
	}
		break;
	/* If client is in the get_block state */
	case get_block:

		/* If server is expecting a SOH block */
		if (cl->blocksize == 128) {

			/* Read in one byte for current block number and store it in the client's
			   current_block attribute */
			if (read(cl->fd, &cl->current_block, 1) < 1) {
				perror("reading in current_block failed in SOH, get_block");
			}

			/* Read in one byte for inverse block number and store it in the client's
			   inverse_block attribute */
			if (read(cl->fd, &cl->inverse_block, 1) < 1) {
				perror("reading in inverse_block failed in SOH, get_block");
			}

			/* Read in the actual payload to the client's buf attribute, one byte at a
			   time */
			while (cl->inbuf < 128) {
				if (read(cl->fd, &cl->buf[cl->inbuf], 1) == 1) {
					cl->inbuf++;
				} else {
					perror("get_block_soh_read_failure\n");
				}

				/* Check if blocksize bytes have been read in, if so, caclculate CRC 
				   and store it in the client's CRC attributes. Transition to check_block. */
				if (cl->inbuf == cl->blocksize) {
					read(cl->fd, &cl->crca, 1);
					read(cl->fd, &cl->crcb, 1);
					cl->state = check_block;	
				}
			}

		}
		/* If server is expecting a STX block */
		if (cl->blocksize == 1024 ) {

			/* Read in one byte for current block number and store it in the client's
			   current_block attribute */
			if (read(cl->fd, &cl->current_block, 1) < 1) {
				perror("reading in current_block failed in STX, get_block");
			}

			/* Read in one byte for inverse block number and store it in the client's
			   inverse_block attribute */
			if (read(cl->fd, &cl->inverse_block, 1) < 1) {
				perror("reading in inverse_block failes in STX, get_block");
			}

			/* Read in the actual payload to the client's buf attribute, one byte at a
			   time */
			while (cl->inbuf < 1024) {
				if ( read(cl->fd, &cl->buf[cl->inbuf], 1) == 1) {
					cl->inbuf++;
				} else {
					perror("get_block_stx_read_failure");
				}
			}

			/* Check if blocksize bytes have been read in, if so, caclculate CRC 
			   and store it in the client's CRC attributes. Transition to check_block. */
			if (cl->inbuf == cl->blocksize) {
				read(cl->fd, &cl->crca, 1);
				read(cl->fd, &cl->crcb, 1);
				cl->state = check_block;
			}

		}
		break;

	case check_block:

		/* Reset buffer index after previous block */
		cl->inbuf = 0;

		/* If inverse block and current block don't corresond, write ACK and drop client */
		if ((255 - cl->inverse_block) != cl->current_block) {

			/* Set acker to the ACK control code and write it */
			acker = ACK;
			if (write(cl->fd, &acker, sizeof(char)) < 1) {
				perror("ACK failed to write in check_block for invalid inverse");
			}
			cl->state = finished;
		}

		/* If previous block and current block numbers are the same, ACK the second one */
		if (cl->previous_block == cl->current_block) {
			acker = ACK;
			if (write(cl->fd, &acker, sizeof(char)) < 1) {
				perror("ACK failed to write in check_block for duplicate blocks");
			}
		}

		/* If blocks are out of order, write ACK and drop client */
		if (cl->current_block != cl->previous_block + 1) {
			if ((cl->previous_block != 255) && (cl->current_block != 0)) {

				/* Set acker to the ACK control code and write it */
				acker = ACK;
				if (write(cl->fd, &acker, sizeof(char)) < 1) {
					perror("ACK failed to write in check_block for invalid block order");
				}
				cl->state = finished;
			}
		}

		/* If CRC's don't match up, send NAK */
		if (crc_message(XMODEM_KEY, cl->buf, cl->blocksize) != ((cl->crca << 8) + cl->crcb)) {

			/* Set acker to NAK and write it */
			acker = NAK;
			if (write(cl->fd, &acker, sizeof(char)) < 1) {
				perror("NAK failed to write in check_block for invalid CRC");
			}
		} else {
			/* If none of the above error checks are triggered */
			/* Set previous block to current, and account for wrapping at block number 
			   255 */
			cl->previous_block = cl->current_block;
			if ( cl->current_block > 255 ) {
				cl->current_block = 0;
			}
			/* Write the current payload in the client's buf attribute to the file */ 
			if (fwrite(&cl->buf, sizeof(char), cl->blocksize, cl->fp) < cl->blocksize) {
				perror("Writing payload to file failed"); 
			}

			/* Set acker to ACK and write it */
			acker = ACK;
			if (write(cl->fd, &acker, sizeof(char)) < 1) {
				perror("ACK failed to write in check_block file write stage");
			}

			/* Transition back to the pre_block */
			cl->state = pre_block;
		}
		break;
	case finished:
		cl->state = initial;
		break;
	
	default:
		printf("error status\n");
		break;
	}
	return 1;
}
Exemple #11
0
int main()
{
    /* setup uart */
    uart_init();
    /* setup stdio */
    uart_connect_stdio();

    /* setup sd card slot */
    if(!sd_raw_init())
    {
#if DEBUG
        printf_P(PSTR("MMC/SD initialization failed\n"));
#endif
        return 1;
    }

    /* open first partition */
    struct partition_struct* partition = partition_open(sd_raw_read,
                                                        sd_raw_read_interval,
                                                        sd_raw_write,
                                                        0);

    if(!partition)
    {
        /* If the partition did not open, assume the storage device
         * is a "superfloppy", i.e. has no MBR.
         */
        partition = partition_open(sd_raw_read,
                                   sd_raw_read_interval,
                                   sd_raw_write,
                                   -1
                                  );
        if(!partition)
        {
#if DEBUG
            printf_P(PSTR("opening partition failed\n"));
#endif
            return 1;
        }
    }

    /* open file system */
    struct fat16_fs_struct* fs = fat16_open(partition);
    if(!fs)
    {
#if DEBUG
        printf_P(PSTR("opening filesystem failed\n"));
#endif
        return 1;
    }

    /* open root directory */
    struct fat16_dir_entry_struct directory;
    fat16_get_dir_entry_of_path(fs, "/", &directory);

    struct fat16_dir_struct* dd = fat16_open_dir(fs, &directory);
    if(!dd)
    {
#if DEBUG
        printf_P(PSTR("opening root directory failed\n"));
#endif
        return 1;
    }
    
    /* provide a simple shell */
    char buffer[24];
    while(1)
    {
        /* print prompt */
        uart_putc('>');
        uart_putc(' ');

        /* read command */
        char* command = buffer;
        if(read_line(command, sizeof(buffer)) < 1)
            continue;

        /* execute command */
        if(strncmp_P(command, PSTR("cd "), 3) == 0)
        {
            command += 3;
            if(command[0] == '\0')
                continue;

            /* change directory */
            struct fat16_dir_entry_struct subdir_entry;
            if(find_file_in_dir(fs, dd, command, &subdir_entry))
            {
                struct fat16_dir_struct* dd_new = fat16_open_dir(fs, &subdir_entry);
                if(dd_new)
                {
                    fat16_close_dir(dd);
                    dd = dd_new;
                    continue;
                }
            }

            printf_P(PSTR("directory not found: %s\n"), command);
        }
        else if(strcmp_P(command, PSTR("ls")) == 0)
        {
            /* print directory listing */
            struct fat16_dir_entry_struct dir_entry;
            while(fat16_read_dir(dd, &dir_entry))
            {
                printf_P(PSTR("%10lu  %s%c\n"),
                         dir_entry.file_size,
                         dir_entry.long_name,
                         (dir_entry.attributes & FAT16_ATTRIB_DIR) ? '/' : ' '
                        );
            }
        }
        else if(strncmp_P(command, PSTR("cat "), 4) == 0)
        {
            command += 4;
            if(command[0] == '\0')
                continue;
            
            /* search file in current directory and open it */
            struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command);
            if(!fd)
            {
                printf_P(PSTR("error opening %s\n"), command);
                continue;
            }

            /* print file contents */
            uint8_t buffer[8];
            uint32_t offset = 0;
            while(fat16_read_file(fd, buffer, sizeof(buffer)) > 0)
            {
                printf_P(PSTR("%08lx: %02x %02x %02x %02x %02x %02x %02x %02x\n"),
                         offset,
                         buffer[0],
                         buffer[1],
                         buffer[2],
                         buffer[3],
                         buffer[4],
                         buffer[5],
                         buffer[6],
                         buffer[7]
                        );
                offset += 8;
            }

            fat16_close_file(fd);
        }
#if FAT16_WRITE_SUPPORT
        else if(strncmp_P(command, PSTR("rm "), 3) == 0)
        {
            command += 3;
            if(command[0] == '\0')
                continue;
            
            struct fat16_dir_entry_struct file_entry;
            if(find_file_in_dir(fs, dd, command, &file_entry))
            {
                if(fat16_delete_file(fs, &file_entry))
                    continue;
            }

            printf_P(PSTR("error deleting file: %s\n"), command);
        }
        else if(strncmp_P(command, PSTR("touch "), 6) == 0)
        {
            command += 6;
            if(command[0] == '\0')
                continue;

            struct fat16_dir_entry_struct file_entry;
            if(!fat16_create_file(dd, command, &file_entry))
                printf_P(PSTR("error creating file: %s\n"), command);
        }
        else if(strncmp_P(command, PSTR("write "), 6) == 0)
        {
            command += 6;
            if(command[0] == '\0')
                continue;

            char* offset_value = command;
            while(*offset_value != ' ' && *offset_value != '\0')
                ++offset_value;

            if(*offset_value == ' ')
                *offset_value++ = '\0';
            else
                continue;

            /* search file in current directory and open it */
            struct fat16_file_struct* fd = open_file_in_dir(fs, dd, command);
            if(!fd)
            {
                printf_P(PSTR("error opening %s\n"), command);
                continue;
            }

            int32_t offset = strtol(offset_value, 0, 0);
            if(!fat16_seek_file(fd, &offset, FAT16_SEEK_SET))
            {
                printf_P(PSTR("error seeking on %s\n"), command);
                fat16_close_file(fd);
                continue;
            }

            /* read text from the shell and write it to the file */
            uint8_t data_len;
            while(1)
            {
                /* give a different prompt */
                uart_putc('<');
                uart_putc(' ');

                /* read one line of text */
                data_len = read_line(buffer, sizeof(buffer));
                if(!data_len)
                    break;

                /* write text to file */
                if(fat16_write_file(fd, (uint8_t*) buffer, data_len) != data_len)
                {
                    printf_P(PSTR("error writing to file\n"));
                    break;
                }
            }

            fat16_close_file(fd);
        }
#endif
#if SD_RAW_WRITE_BUFFERING
        else if(strcmp_P(command, PSTR("sync")) == 0)
        {
            if(!sd_raw_sync())
                printf_P(PSTR("error syncing disk\n"));
        }
#endif
        else
        {
            printf_P(PSTR("unknown command: %s\n"), command);
        }
    }

    /* close file system */
    fat16_close(fs);

    /* close partition */
    partition_close(partition);
    
    return 0;
}
Exemple #12
0
uint8_t RepRapSDCard::open_file(char *name, File *file)
{
  return open_file_in_dir(fs, dd, name, file);
}