Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PsiSwarm-Headstart 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;