C++ Library for the PsiSwarm Robot - Version 0.7

Fork of PsiSwarmV7 by Psi Swarm Robot

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;