posilani dat

Dependencies:   FatFileSystemCpp mbed PowerControl USBHostLite

Files at this revision

API Documentation at this revision

Comitter:
PavelKumpan
Date:
Tue May 23 18:42:14 2017 +0000
Parent:
25:2f964ebcdfd8
Commit message:
Recreated communication protocol.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
wifi.cpp Show annotated file Show diff for this revision Revisions of this file
wifi.h Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Mon Mar 13 15:58:42 2017 +0000
+++ b/main.cpp	Tue May 23 18:42:14 2017 +0000
@@ -70,6 +70,9 @@
  * - Removed clearRoot() call from init.
  * - Change representation of the records file to binary.
  * - Add Prepare command - first send prepare, wait for a file open and then send Start.
+ *
+ * CHANGELOG 20/05/2017
+ * - Changed communication protocol - each message have header with its size.
  */
 
 // Includes ====================================================================
@@ -175,7 +178,7 @@
 void startSaving(void);
 void stopSaving(void);
 void transfer(void);
-void sendLog(void);
+void sendFile(char* name);
 void halt(void);
 void beginScope(void);
 void sendStatus(void);
@@ -273,6 +276,11 @@
 short int gyro_y[SIZE];
 short int gyro_z[SIZE];
 
+/* Command buffers */
+char cmd_header[FRAME_HEADER_LEN];
+char cmd_data[256];
+int cmd_len;
+
 // Functions -> File handling ==================================================
 
 /* Clear all files in root directory */
@@ -295,9 +303,13 @@
             remove(buf);                                                        // Remove file that is currently being pointed to
         }
     }
-    
+      
     /* If file is not present */
     closedir(dir);                                                              // Close dir & return false    
+    
+    FILE *records;
+    records = fopen(RECORDS_FILE, "w");                                         // Create new file for records
+    fclose(records);  
 }
 
 /* Append line to log file */
@@ -330,7 +342,7 @@
         recordbuffer[i+1] = timestamp[i];
     }
     
-    fwrite(recordbuffer, 1, 9, records);                                        // Write 32 buffer lines (16 bytes) to file (512 bytes total -> one block)
+    fwrite(recordbuffer, 1, 9, records);                                        // Write 9 bytes of record
     fflush(records); 
     fclose(records);                                                            // Close file
 }
@@ -339,18 +351,21 @@
 void readSwimmerID(void)
 {   
     size_t fileSize;
-    
+    FILE *records;
+            
     if(false == doesFileExist(RECORDS_FILE))
     {
         swimmer_id = 0;
         printf("File with records does not exists, so ID set to 0...\r\n");
+        swimmer_id = 0;
+        printf("New records file created...\r\n");
+        records = fopen(RECORDS_FILE, "a");
     }
     else
     {
         printf("Reading last swimmer ID from records file...\r\n");
 
         /* Append line to records file */
-        FILE *records;
         records = fopen(RECORDS_FILE, "r");                                     // Open file with records name
         
         fseek(records, 0L, SEEK_END);
@@ -366,9 +381,10 @@
             fseek(records, -9, SEEK_END);
             swimmer_id = (uint8_t)fgetc(records) + 1;
         }
-        fclose(records);
-        printf("Actual index is %d...\r\n", swimmer_id);
-    }                                                       
+    }
+    
+    printf("Actual index is %d...\r\n", swimmer_id);
+    fclose(records);                                                       
 }
 
 /* Sees whether giver file exists on flash disk */
@@ -637,13 +653,11 @@
 /* Prepares all to acquire data from sensors */
 void prepareSaving(void)
 {
-    for (int i = 0; i < 8; i++) 
+    for(int i = 0; i < 8; i++)
     {
-        timestamp[i] = wifi.readByte();                                           // Get bytes containing timestamp for the current record
+        timestamp[i] = cmd_data[i];
     }
     
-    wifi.sendAck();
-    
     savingFlag = 1;                                                             // Set saving flag
     /* Open global file with current swimmer ID */
     gfp = fopen(fname, "wb");                                                   // Try to open that file
@@ -723,98 +737,14 @@
     char name[30];                                                              // File name buffer  
     
     /* File transfer prerequisites */
-    fclose(gfp);
-    int requested_id = wifi.readByte();                                 // Get byte containing requested file ID
-    sprintf(name, "/usb/swimmer%d.txt", requested_id);                  // Create file name based on current swimmer ID
-    
-    /* Handle transfer */
-    if(doesFileExist(name))                                             // At first check whether file exists (fopen used to freeze mbed)
-    {
-        /* Send ACK */
-        wifi.sendAck();
-        wait_ms(50);                                                    // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain)
-        /* Actually try to send file */                                         
-        printf("Sending %s\r\n", name);                                 // Notify user which user is being sent
-        if (wifi.sendFile(name))                                        // Send !
-        {
-            leds_error();                                               // Handle error
-            printf("Unable to send data (ID:%d)\r\n", requested_id);    // Notify user via text also
-        }
-        else
-        {
-            printf("Swimmer %d finished\r\n", requested_id);            // Otherwise all is AOK
-        }  
+    printf("closing");
+    if (gfp != NULL) {
+        fclose(gfp);
     }
-    else
-    {
-        /* In case file doest not exist send NACK */
-        wifi.sendByte('#');                                                     
-        wifi.sendByte('F');
-        printf("Requested non-existing file...\r\n");
-    }     
-}
-
-/* Sends log file*/
-void sendLog(void)
-{
-     /* Vars */
-    char name[30];                                                              // File name buffer  
-    
-    /* File transfer prerequisites */                                           
-    sprintf(name, LOG_FILE);                                                    // Create file name from log name    
-    /* Handle transfer */
-    if(doesFileExist(name))                                                     // At first check whether file exists (fopen used to freeze mbed)
-    {
-        /* Send ACK (should make this more abstract) */
-        wifi.sendAck();
-        wait_ms(50);                                                            // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain)
-        /* Actually try to send file */                                         
-        printf("Sending %s\r\n", name);                                         // Notify user which user is being sent
-        if (wifi.sendFile(name))                                                // Send !
-        {
-            leds_error();                                                       // Handle error
-            printf("Unable to send log file\r\n");                              // Notify user via text also
-        }
-        else
-        {
-            printf("Log file sent!\r\n");                                       // Otherwise all is AOK
-        }  
-    }
-    else
-    {
-        /* In case file doest not exist send NACK */
-        wifi.sendByte('#');                                                     
-        wifi.sendByte('F');
-        printf("Requested non-existing file...\r\n");
-    }
-}
-
-/* Sends records file*/
-void sendRecords(void)
-{
-    /* Handle transfer */
-    if(doesFileExist(RECORDS_FILE))                                                     // At first check whether file exists (fopen used to freeze mbed)
-    {
-        wait_ms(50);                                                            // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain)
-        /* Actually try to send file */                                         
-        printf("Sending %s\r\n", RECORDS_FILE);                                         // Notify user which user is being sent
-        if (wifi.sendFile(RECORDS_FILE))                                                // Send !
-        {
-            leds_error();                                                       // Handle error
-            printf("Unable to send records file\r\n");                          // Notify user via text also
-        }
-        else
-        {
-            printf("Records file sent!\r\n");                                   // Otherwise all is AOK
-        }  
-    }
-    else
-    {
-        /* In case file doest not exist send NACK */
-        wifi.sendByte('#');                                                     
-        wifi.sendByte('F');
-        printf("Requested non-existing file...\r\n");
-    }
+    printf(" file %d", cmd_data[0]);
+    sprintf(name, "/usb/swimmer%d.txt", cmd_data[0]);                           // Create file name based on current swimmer ID
+    printf(name);
+    sendFile(name);    
 }
 
 /* Halts board */
@@ -844,15 +774,50 @@
 
 // Functions -> Generic functions ==============================================
 
+/* Sends acquired data via Wi-Fi */
+void sendFile(char* name)
+{
+    /* Handle transfer */
+    if(doesFileExist(name))                                             // At first check whether file exists (fopen used to freeze mbed)
+    {                                                                   // Timeout is used to make sure C# gets ready (sockets are messy, flushing is pain)
+        /* Actually try to send file */                                         
+        printf("Sending %s...\r\n", name);                              // Notify user which user is being sent
+        if (wifi.sendFile(name) != 0)                                   // Send !
+        {
+            leds_error();                                               // Handle error
+            wifi.sendFail();
+            printf("Unable to send file.\r\n");                         // Notify user via text also
+        }
+        else
+        {
+            printf("File transfer finished.\r\n");                     // Otherwise all is AOK
+        }  
+    }
+    else
+    {
+        /* In case file doest not exist send NACK */
+        wifi.sendNack();
+        printf("Requested non-existing file.\r\n");
+    }     
+}
+
 /* Sends status */
 void sendStatus(void)
 {
     uint8_t checksum = SOH + savingFlag + battLevel + swimmer_id;               // Calculate checksum
+    wifi.sendByte('#');                                                         // #
+    wifi.sendByte('A');                                                         // A
+    wifi.sendByte(5);                                                           // Send count of the data
+    wifi.sendByte(0);
+    wifi.sendByte(0);
+    wifi.sendByte(0);
     wifi.sendByte(SOH);                                                         // Send start of heading
     wifi.sendByte(savingFlag);                                                  // Send state of saving
     wifi.sendByte(battLevel);                                                   // Sends current battery level
     wifi.sendByte(swimmer_id);                                                  // Sends current swimmer id index
     wifi.sendByte(checksum);                                                    // Send checksum
+    
+    wifi.waitForAck();
 }
 
 void blink(void)
@@ -873,19 +838,25 @@
 {
     /* Begin by initialization */                                               
     boardInit();                                                                // Initialize board
-
+    
     /* Set zeroth swimmer name */
     sprintf(fname, "/usb/swimmer%d.txt", swimmer_id);                           // Prepare zeroth swimmer filename
-
+    
     /* Main while */
     while (1)
     {
         /* Shutdown handler */
         shutdownHandler();
         /* Read command from wifly */
-        char cmd = wifi.getCmd();
+        cmd_len = wifi.getCmd(cmd_header, cmd_data);
+        
+        if(cmd_header[1] != 'N')
+        {
+            printf(">> #%c and %d bytes\r\n", cmd_header[1], cmd_len);
+        }
+        
         /* Master switch */
-        switch (cmd) {
+        switch (cmd_header[1]) {
             /* start measuring data periodically and save them info file */
             case PREPARE_SAVING:
             {
@@ -910,9 +881,9 @@
             /* stop saving data */
             case SAVING_STOP:
             {
-                wifi.sendAck();
                 leds_off();                                                     // Turn off all leds
                 stopSaving();                                                   // Actually stop saving
+                wifi.sendAck();
                 printf("Stopped...\r\n");                                       // Notify user
                 break;                                                          // Break from switch
             }
@@ -920,7 +891,6 @@
             /* Send all data */
             case TRANSFER_REQUEST:
             {
-                wifi.sendAck();
                 leds_off();                                                     // Turn off all leds
                 led_sending = 1;                                                // Turn on led_sending
                 printf("Sending data...\r\n");                                  // Notify user that data is being sent
@@ -949,7 +919,7 @@
                 leds_off();                                                     // Turn off all leds
                 led_measuring = led_saving = 1;                                 // Turn on two leds to depict special behaviour
                 printf("Sending log...\r\n");                                   // Notify user that new scope is beginning
-                sendLog();                                                      // Send log file
+                sendFile(LOG_FILE);                                             // Send log file
                 leds_off();                                                     // Turn off all leds
                 break;                                                          // Break
             }
@@ -957,11 +927,10 @@
             /* Send records file */
             case SEND_RECORDS:
             {
-                wifi.sendAck();
                 leds_off();                                                     // Turn off all leds
                 led_measuring = led_saving = 1;                                 // Turn on two leds to depict special behaviour
                 printf("Sending records...\r\n");                               // Notify user that new scope is beginning
-                sendRecords();                                                  // Send records file
+                sendFile(RECORDS_FILE);                                         // Send records file
                 leds_off();                                                     // Turn off all leds
                 break;                                                          // Break
             }
@@ -980,7 +949,7 @@
             /* Ready */
             case CHECK_READY:
             {
-                wifi.sendAck();
+                printf("Sending status...\r\n");                                //
                 leds_off();                                                     // Turn off all leds
                 sendStatus();                                                   // Sends status message
                 break;                                                          // Break
@@ -998,12 +967,24 @@
                 break;                                                          // Break from switch
             }
 
+            /* Fail (should be handled in some inner function */
+            case 'F':
+            {
+                break;                                                          // Break from switch
+            }
+            
+            /* Nothing on serial */
+            case 'A':
+            {
+                break;                                                          // Break from switch
+            }
+            
             /* Everything else is ballast */
             default :
             {
                 wifi.sendNack();
                 leds_error();                                                   // Turn on all leds
-                printf("Command %c is unknown!\r\n", cmd);                      // Notify user
+                printf("Command %c is unknown!\r\n", cmd_header[1]);            // Notify user
                 break;                                                          // Break from switch
             }
         }
--- a/wifi.cpp	Mon Mar 13 15:58:42 2017 +0000
+++ b/wifi.cpp	Tue May 23 18:42:14 2017 +0000
@@ -3,7 +3,6 @@
 
 #define BAUDR 460800
 //#define BAUDR 1100000
-#define SEND_SIZE 1024
 
 Wifi::Wifi (PinName tx, PinName rx, PinName cts, PinName reset): 
         wifi_(tx, rx) {    
@@ -26,7 +25,6 @@
 *   many times (int) count 3*(short) acc 3*(float)gyro
 *         (int) -1 (int) -1    up to 1023 zeros   
 */
-//int Wifi::sendFile(const char *fname, int swimmer_id)
 int Wifi::sendFile(const char *fname)
 {
     char c;
@@ -37,6 +35,26 @@
         printf("Unable to open %s\r\n", fname);
         return -1;
     }
+    
+    fseek(file, 0, SEEK_END);                           // seek to end of file
+    int size = ftell(file);                             // get current file pointer
+    fseek(file, 0, SEEK_SET);                           // seek back to beginning of file
+    
+    wifi_.putc('#');                                    // send ACK
+    wifi_.putc('A');
+    for(int i = 0; i < FRAME_HEADER_LEN - 2; i++)       // send num of bytes in the message
+    {
+        wifi_.putc((char)((size >> (i * 8)) & 0xFF));
+    }
+    
+    printf("Ack sended...\r\n");
+    printf("Transfer of %d bytes initialized...\r\n", size);
+    
+    if(size == 0)                                       // when nothing to send, terminated here
+    {
+        return 0;
+    }
+    
     in_buf = 0;
     while (fread(&c, sizeof(char), 1, file) != 0) {
         if ((last = bufferSendVerify(c)) == -1) {
@@ -44,57 +62,65 @@
             return -1;
         }
     }
-
-    //fill the last data to SEND_SIZE with zeros
-    if (last == 1) {
-        while (bufferSendVerify(0x00) != 0)
-            ;    
+    fclose(file);
+    
+    if (bufferFlush() == -1) {
+        return -1;
     }
 
-    fclose(file); 
     return 0;
 }
 
 /*
- * Returns 'N' if no command was recieved
- * or the command
+ * Returns length of command data received, load the command into the cmd array and the data into the data array.
  */
-char Wifi::getCmd(void)
+int Wifi::getCmd(char* cmd, char* data)
 {
+    short dataLength = 0u;
+    cmd[0] = '#';
+    cmd[1] = 'N';
+    
+    /* Read the command */
     if (wifi_.readable() && wifi_.getc() == '#')
     {
+        for(int i = 1; i < FRAME_HEADER_LEN; i++)
+        {
+            wait_ms(20);
+            if (wifi_.readable())
+            {
+                cmd[i] = wifi_.getc();
+            }
+            else
+            {
+                cmd[1] = 'N';
+            }    
+        }
+    }
+    
+    /* Read count of data */
+    if(cmd[1] == 'N')
+    {
+        return 0;
+    }
+    
+    for(int i = 0; i < FRAME_HEADER_LEN - 2; i++)
+    {
+        dataLength += (int)cmd[i+2] << (i * 8); 
+    }
+    
+    /* Read data */
+    for(int i = 0; i < dataLength; i++)
+    {
         wait_ms(20);
         if (wifi_.readable())
         {
-            return wifi_.getc();
+            data[i] = wifi_.getc();
         }
-        else
-        {
-            return 'N';   
-        }    
     }
-    else
-    {
-        return 'N';
-    }
+    
+    return dataLength;
 }
 
-//char Wifi::getCmd(void)
-//{
-//    // Needs to be done properly
-//    //if (wifi_.readable() || wifi_.getc() == '#');
-//    if (wifi_.readable() && wifi_.getc() == '#')
-//   {
-//        wifi_.putc('#');
-//        wifi_.putc('A');
-//        return wifi_.getc();
-//    }
-//    else
-//    {
-//        return 'N';
-//    }
-//d}
-
 /*
  * Sends given byte to wifly
  */
@@ -135,6 +161,10 @@
 {
     wifi_.putc('#');
     wifi_.putc('A');
+    for(int i = 0; i < FRAME_HEADER_LEN - 2; i++)
+    {
+        wifi_.putc(0x0);
+    }
 }
 
 /*
@@ -144,12 +174,58 @@
 {
     wifi_.putc('#');
     wifi_.putc('N');
+    for(int i = 0; i < FRAME_HEADER_LEN - 2; i++)
+    {
+        wifi_.putc(0x0);
+    }
+}
+
+/*
+ * Sends NACK to wiflys UART
+ */
+void Wifi::sendFail(void)
+{
+    wifi_.putc('#');
+    wifi_.putc('F');
+    for(int i = 0; i < FRAME_HEADER_LEN - 2; i++)
+    {
+        wifi_.putc(0x0);
+    }
+}
+
+int Wifi::waitForAck()
+{
+    char cmd[FRAME_HEADER_LEN];
+    char data[256];
+
+    for (int i=0; i<64; i++)
+    {
+        getCmd(cmd, data);
+        
+        if ('A' == cmd[1])
+        {
+            return 1;   
+        }
+        else if ('F' == cmd[1])
+        {
+            return 0;
+        }
+        else
+        {
+            wait_ms(5);   
+        }    
+    }
+    return -1;
+    
+    //if (wifi_.getc() == 'A')
+    //    break;
 }
 
 /* ********************************
  * private
  * *******************************/
-void Wifi::bufferSend(char *buffer, size_t size)
+ 
+void Wifi::bufferSend(size_t size)
 {
     int i;
     for (i = 0; i < size; i++) {
@@ -157,50 +233,91 @@
     }
 }
 
+int Wifi::bufferFlush()
+{
+    LPC_WDT->WDFEED = 0xAA;
+    LPC_WDT->WDFEED = 0x55;
+    int counter = 0;
+    int result = 0;
+    
+    if (in_buf == 0)
+    {
+        return 1;
+    }
+       
+    while (counter++ < 10) 
+    {
+        bufferSend(in_buf);
+        result = waitForAck();
+                
+        if(result == 1)
+        {
+            /* Ack - break, no need to send it again */
+            break;
+        }
+        else if (result == -1)
+        {
+            /* Fail - transmition faild, terminate sending */
+            return -1;
+        }
+        else
+        {
+            /* Nack - send it again*/
+        }
+    }
+    
+    if (counter >= 10)
+    {
+        return -1;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
 int Wifi::bufferSendVerify(char c)
 {
     LPC_WDT->WDFEED = 0xAA;
     LPC_WDT->WDFEED = 0x55;
-    static char buffer[SEND_SIZE];
     int counter = 0;
-    
+    int result = 0;
     buffer[in_buf] = c;
     in_buf++;
         
     if (in_buf != SEND_SIZE)
+    {
         return 1;
+    }
     
     in_buf = 0;
-    while (counter++ < 10) {
-        bufferSend(buffer, SEND_SIZE);
-        //while (!wifi_.readable());
-        for (int i=0; i<50; i++)
+    while (counter++ < 16) 
+    {
+        bufferSend(SEND_SIZE);
+        result = waitForAck();
+        
+        if(result == 1)
+        {
+            /* Ack - break, no need to send it again */
+            break;
+        }
+        else if (result == -1)
         {
-            if (wifi_.readable())
-            {
-                char buf = wifi_.getc();
-                if ('A' == buf)
-                {
-                    return 0;   
-                }
-                else if ('F' == buf)
-                {
-                    break;    
-                }
-                else
-                {
-                    return -1;    
-                }
-            }
-            else
-            {
-                wait_ms(5);   
-            }    
+            /* Fail - transmition faild, terminate sending */
+            return -1;
+        }
+        else
+        {
+            /* Nack - send it again*/
         }
-        //if (wifi_.getc() == 'A')
-        //    break;
     }
+    
     if (counter >= 10)
+    {
         return -1;
-    return 0;
+    }
+    else
+    {
+        return 0;
+    }
 }
\ No newline at end of file
--- a/wifi.h	Mon Mar 13 15:58:42 2017 +0000
+++ b/wifi.h	Tue May 23 18:42:14 2017 +0000
@@ -9,6 +9,8 @@
 
 #include "mbed.h"
 //#include "WiflyInterface.h"
+#define FRAME_HEADER_LEN 6
+#define SEND_SIZE 1024
 
 class Wifi {
     public:
@@ -20,7 +22,7 @@
         /*
          * Returns received command (without #), just the one char
          */
-        char getCmd(void);
+        int getCmd(char* cmd_header, char* cmd_data);
         
         /*
          * Sends one char to wifly
@@ -42,12 +44,16 @@
         bool readable(void);
         void sendAck(void);
         void sendNack(void);
+        void sendFail(void);
+        int waitForAck(void);
 
     private:
         Serial wifi_;
         int in_buf;
-        void bufferSend(char *buffer, size_t size);
-        int bufferSendVerify(char buffer); 
+        char buffer[SEND_SIZE];
+        void bufferSend(size_t size);
+        int bufferSendVerify(char byte); 
+        int bufferFlush(void);
 };
 
 #endif
\ No newline at end of file