Library for the PsiSwarm Robot for Headstart Lab - Version 0.5
Fork of PsiSwarmLibrary by
Diff: serial.cpp
- Revision:
- 1:060690a934a9
- Parent:
- 0:d6269d17c8cf
- Child:
- 2:c6986ee3c7c5
--- a/serial.cpp Thu Feb 04 21:48:54 2016 +0000 +++ b/serial.cpp Thu Mar 03 23:21:47 2016 +0000 @@ -25,6 +25,12 @@ char allow_commands = 1; char allow_requests = 1; +char file_transfer_state = 0; +int file_length; +char filename [13]; + + +Timeout ft_timeout; Timeout pc_command_timeout; Timeout bt_command_timeout; @@ -65,6 +71,49 @@ } } +void IF_start_file_transfer_mode() +{ + display.clear_display(); + display.set_position(0,0); + display.write_string("FILE TRANSFER"); + display.set_position(1,0); + display.write_string("MODE..."); + file_transfer_mode = 1; + file_transfer_state = 0; + file_length = 0; + user_code_restore_mode = user_code_running; + user_code_running = 0; + ft_timeout.attach(IF_file_transfer_timeout,2.0); +} + + +void IF_invalid_transfer(void) +{ + debug("File transfer failed\n"); + display.clear_display(); + display.set_position(0,0); + display.write_string("TRANSFER FAILED"); + wait(0.5); + IF_end_file_transfer_mode(); +} + +void IF_file_transfer_timeout(void) +{ + debug("File transfer failed: timeout\n"); + display.clear_display(); + display.set_position(0,0); + display.write_string("TRANSFER TIMEOUT"); + wait(0.5); + IF_end_file_transfer_mode(); +} + +void IF_end_file_transfer_mode(void) +{ + display.clear_display(); + file_transfer_mode = 0; + user_code_running = user_code_restore_mode; +} + void IF_handle_file_transfer_serial_message(char * message, char length, char interface) { @@ -74,8 +123,75 @@ // length = length of message // interface = 0 for PC serial connection, 1 for Bluetooth [NB only Bluetooth used for file transfer in this version] - debug("FTM Message:%s [%d]\n",message,length); - + debug("FTM Message:%.*s [%d]\n",length,message,length); + char * file_data; + int block_index; + int final_block; + int expected_size; + int block_size = 100; + // The first byte in EVERY message received should be 33; if it isn't, abort the transfer + if(message[0] != 33) { + IF_invalid_transfer(); + } else { + switch(file_transfer_state) { + case 0: //First message received is the target filename + //The filenames cannot be more that 8.3 characters long (FAT12 format) + if(length == 1 || length > 13) IF_invalid_transfer(); + else { + strncpy(filename, message + 1, length - 1); + //Send acknowledge ("FN") + ft_timeout.detach(); + ft_timeout.attach(IF_file_transfer_timeout,2.0); + bt.printf("%c%c%s",RESPONSE_MESSAGE_BYTE,2,"FN"); + file_transfer_state = 1; + } + break; + case 1: //Second message is the length of the file in bytes + //Length is encoded as a 3-byte value + if(length != 4) IF_invalid_transfer(); + else { + file_length = (message[1]) * 256; + file_length += (message[2]); + file_length *= 256; + file_length += message[3]; + file_transfer_state = 2; + display.clear_display(); + char display_message[17]; + sprintf(display_message,"F:%s",filename); + display.set_position(0,0); + display.write_string(display_message); + display.set_position(1,0); + sprintf(display_message,"S:%d b",file_length); + display.write_string(display_message); + block_index = 0; + //Work out how many blocks the file will be sent in (size = block_size, tested at 100 bytes) + //Allocate memory for the file up to a limit of 16 blocks; larger files will be split across + //multiple blocks.... + final_block = file_length / block_size; + if(file_length % block_size != 0) final_block ++; + int target_size = file_length; + if(file_length > (block_size * 16)) target_size = block_size * 16; + file_data = (char *) malloc(target_size); + ft_timeout.detach(); + ft_timeout.attach(IF_file_transfer_timeout,1.0); + //Send acknowledge (size of file) + bt.printf("%c%c%c%c%c",RESPONSE_MESSAGE_BYTE,3,message[1],message[2],message[3]); + } + break; + case 2: + block_index ++; + if(block_index == final_block) expected_size = file_length % block_size; + if(expected_size == 0) expected_size = block_size; + if(length!=expected_size + 1){ + // Unexpected length + + }else{ + + ft_timeout.detach(); + ft_timeout.attach(IF_file_transfer_timeout,1.0); + } + } + } } @@ -724,9 +840,7 @@ strcpy(command,"START FILE TRANSFER MODE"); if(allow_commands) { command_status = 1; - file_transfer_mode = 1; - user_code_restore_mode = user_code_running; - user_code_running = 0; + IF_start_file_transfer_mode(); sprintf(ret_message,"OK"); send_message = 1; } else command_status = 2;