uses pushing box to publish to google spreadsheets with a state machine instead of a while loop

Dependents:   DCS_FINAL_CODE

Fork of GSM_PUSHING_BOX_STATE_MACHINE by DCS_TEAM

Revision:
24:7d2ff444d6d8
Parent:
13:9ac5ff131214
Child:
27:fe1c7eaf5b88
--- a/gsmqueue.cpp	Tue Mar 24 18:39:13 2015 +0000
+++ b/gsmqueue.cpp	Sat Apr 11 23:21:46 2015 +0000
@@ -1,44 +1,112 @@
 #include "gsmqueue.h"
-#include "mbed.h"
-/* queue.cpp
+#include "GSMLibrary.h"
+#include <string.h>
+
+/* gsmqueue.cpp
  * Contains functions to read from the DMA buffer in a queue fashion
  */
+ 
+#define LAST_UNPRINTABLE_CHAR 31
+
 extern Serial pc;
+extern Serial gsm;
 
 char buffer[BUFFER_LENGTH];
 char* queueHead;
+char* queueHeadExp; //Expected location of queueHead after gsm.puts() finishes executing
 
 
-//Initialize variables 
+//Public functions ------------------------------------------------------------------------------
+//Initialize variables
 void queueInit()
 {
-    //The buffer is initialized in init.cpp
+    //The buffer is initialized in GSMLibrary.cpp
     queueHead = QUEUETAIL;
+    queueHeadExp = queueHead;
+}
+
+//Send gsm a command (don't forget to flush queue and increment past QUEUETAIL
+//by the number of characters send)
+void sendCommand(char* sPtr)
+{
+    flushQueue();       //This "removes" any characters remaining in the queue
+    int size = strlen(sPtr);
+    if (size > 0 && size <= MAX_SMS_LENGTH)   //Don't send if too long or negative size
+    {
+        //Send the command
+        gsm.puts(sPtr);
+        //The increment part below: Effectively "removes" characters we just sent from the buffer
+        // by advancing queueHead by size - 1, or size + 2 
+        // size - 1 is because SMS_END_CHAR does not show up on the DMA.
+        // size + 2 is for "\n\r" that gets transmitted after we send the command
+        if (sPtr[size - 1] == SMS_END_CHAR[0])
+        {
+            queueHeadExp = incrementIndex(queueHead, size - 1);
+            // Don't add "\n" because already included in string (this is when we are sending a message)
+        }
+        else
+        {
+            queueHeadExp = incrementIndex(queueHead, size + 2);
+            gsm.puts("\n"); //make there be a \r\n in what we send (this is perfect.)
+            //Why not "\r\n"? Previously we had thought the extra \r was added due to \r\n coming
+            // through the command line: scanf only removed the \n as whitespace. However, upon
+            // further investigation we realized this behavior occurs because the gsm.puts function
+            // adds a "\r" at the end of your string, independent of whether it was already present
+            // in the string you sent to it. (Except if you only send "\n", in which case it does
+            // not follow it with a "\r".) Thus we need to simply add "\n" because the "\r" is 
+            // already added by the gsm.puts command.
+        }
+        pc.printf("C:%s\r\n", sPtr); //&debug - to know we have sent this message
+    }
+    else    //Else: error message
+    {
+        pc.printf("Error: AT command exceeded maximum length");
+        gsm_reset();
+    }
+}
+
+//Return true if GSM has sent complete response already
+//If GSM is idle and queue is not empty, return true
+//If the last command was successfully sent, advance queueHead to queueHeadExp
+bool queueHasResponse()
+{
+    if (getGSMIdleBit())
+    {   //If tail has advanced past the end of our last sent command, queue has new data
+        int dataReceived = queueSize(QUEUETAIL) - queueSize(queueHeadExp);
+        if (dataReceived >= 0)
+            queueHead = queueHeadExp;   //Upon equality, last command was successfully sent
+        return (dataReceived > 0);      //Data received only if characters present beyond "equality" point
+    }
+    else
+        return false;   //Still busy; wait until transmission ended
 }
 
 //Find an occurrence of the given string in the buffer.
-//Only advance queueHead until a matching string is found.
+//If advanceQueueHead is true, advance queueHead just until a matching string is found.
 //The given string terminates in NULL (\0)
-bool findInQueue(char* str)
+bool findInQueue(char* str, bool advanceQueueHead)
 {
     //Check that string to find is not empty
     if (*str == NULL) return false;
     
-    while (queueHead != QUEUETAIL)
+    char* head = queueHead;
+    while (head != QUEUETAIL)
     {
         //Does the character match the begin char?
-        if (*queueHead == *str){
+        if (*head == *str){
             //Check the remaining characters
             char* sPos = str;
             char* qPos = 0;
-            for (qPos = queueHead; qPos != QUEUETAIL; qPos = incrementIndex(qPos)){
+            for (qPos = head; qPos != QUEUETAIL; qPos = incrementIndex(qPos)){
                 //Compare the next char
                 if (*qPos == *sPos)
                 {
                     ++sPos; //Increment index (prefix incrementation).
-                    if (*sPos == NULL)   //If finished, update queueHead, return true.
+                    if (*sPos == NULL)   //If finished, update head, return true.
                     {
-                        queueHead = incrementIndex(qPos);
+                        head = incrementIndex(qPos);
+                        if (advanceQueueHead)
+                            queueHead = head;
                         return true;
                     }
                 }
@@ -47,49 +115,14 @@
             }
         }
         //Increment queue index for next iteration
-        queueHead = incrementIndex(queueHead);
+        head = incrementIndex(head);
     }
-    //We never finished, so return false
+    //We never succeeded, so return false
+    if (advanceQueueHead)
+        queueHead = head;
     return false;
 }
 
-//Increment queue index by 1
-char* incrementIndex(char* pointerToIncrement)
-{
-    if((pointerToIncrement + 1) < (buffer + BUFFER_LENGTH))
-        return (pointerToIncrement + 1);
-    else
-        return buffer;
-}
-
-//clear queue
-void flushQueue()
-{
-    queueHead = QUEUETAIL;   
-}
-
-//$debug - print queue elements
-void printQueue()
-{
-    char* qPos = queueHead;
-    pc.printf("Queue:");
-    while (qPos != QUEUETAIL)
-    {
-        //Print the current character
-        if (*qPos == '\n')
-            pc.printf("\\n");
-        else if (*qPos == '\r')
-            pc.printf("\\r");
-        else    
-            pc.printf("%C",*qPos);
-        
-        
-        //Increment index
-        qPos = incrementIndex(qPos);
-    }
-    pc.printf("\n\r");
-}
-
 //Parse through characters until first integer is found
 //Advance qHead until you reach the next non-numeric character
 //Does not read negative integers; returns -1 if unsuccessful
@@ -116,11 +149,77 @@
     return val;
 }
 
+//$debug - print queue elements
+void printQueue()
+{
+    char* qPos = queueHead;
+    pc.printf("Q:");
+    while (qPos != QUEUETAIL)
+    {
+        //Print the current character
+        if (*qPos <= LAST_UNPRINTABLE_CHAR)
+        {
+            if (*qPos == '\n')
+                pc.printf("\\n");
+            else if (*qPos == '\r')
+                pc.printf("\\r");
+            else
+                pc.printf("\0%x", *qPos);
+        }
+        else    
+            pc.printf("%C",*qPos);
+        
+        
+        //Increment index
+        qPos = incrementIndex(qPos);
+    }
+}
+
+
+//Internal functions ---------------------------------------------------------------------------------
+
+//Get the GSM DMA idle bit (if 1, indicates we already received a response)
+bool getGSMIdleBit()
+{
+    return (UART_S1_IDLE_MASK & UART_S1_REG(UART3)) >> UART_S1_IDLE_SHIFT;
+}
+
 //Returns true if the character is numeric
 bool isNumeric(char* qPos)
 {
     return ('0' <= *qPos && *qPos <= '9');
 }
+
+//Increment queue position by 1 (Note: this function is only used by gsmqueue.cpp)
+char* incrementIndex(char* pointerToIncrement)
+{
+    if((pointerToIncrement + 1) < (buffer + BUFFER_LENGTH))
+        return (pointerToIncrement + 1);
+    else
+        return buffer;
+}
+
+//Increment queue position by n (Note: this function is only used by gsmqueue.cpp)
+char* incrementIndex(char* pointerToIncrement, int n)
+{
+    int initialIndex = pointerToIncrement - buffer;
+    int incrementedIndex = (initialIndex + n) % BUFFER_LENGTH;
+    return incrementedIndex + buffer;
+}
+
+//Get size of the queue from reference point of tail parameter
+int queueSize(char* tail)
+{
+    int headDiff = queueHead - buffer;
+    int tailDiff = tail - buffer;
+    return (tailDiff + BUFFER_LENGTH - headDiff) % BUFFER_LENGTH;
+}
+
+//Clear queue (Note: this function is only used by gsmqueue.cpp)
+void flushQueue()
+{
+    queueHead = QUEUETAIL;   
+}
     
 //Reset the GSM DMA idle bit to 0
 void resetGSMIdleBit()
@@ -128,8 +227,3 @@
     UART_S1_REG(UART3) &= ~UART_S1_IDLE_MASK;
 }
 
-//Get the GSM DMA idle bit (if 1, indicates we already received a response)
-bool getGSMIdleBit()
-{
-    return (UART_S1_IDLE_MASK & UART_S1_REG(UART3)) >> UART_S1_IDLE_SHIFT;
-}
\ No newline at end of file