a library to use GPRS like ethernet or wifi, which makes it possible to connect to the internet with your GPRS module

Dependencies:   BufferedSerial

Dependents:   ThinkSpeak_Test roam_v1 roam_v2 finalv3

Fork of GPRSInterface by wei zou

Revision:
13:379ce1d51b88
Parent:
9:38800611a613
--- a/GPRS/modem/modem.cpp	Tue Mar 10 03:11:38 2015 +0000
+++ b/GPRS/modem/modem.cpp	Fri Apr 03 15:44:04 2015 +0800
@@ -1,136 +1,134 @@
 /*
   modem.cpp
-  2014 Copyright (c) Seeed Technology Inc.  All right reserved.
-
-  Author:lawliet zou(lawliet.zou@gmail.com)
-  2014-2-24
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+  2015 Copyright (c) Seeed Technology Limited.  All right reserved.
 */
 
 #include "modem.h"
-
-char Modem::readByte(void)
-{
-    return serialModem.getc();
-}
-
-bool Modem::readable()
-{
-    return serialModem.readable();
-}
-
-int Modem::readBuffer(char *buffer,int count, unsigned int timeOut)
-{
-    int i = 0;
-    timeCnt.start();
-    while(1) {
-        while (serialModem.readable()) {
-            char c = serialModem.getc();
-            buffer[i++] = c;
-            if(i >= count)break;
-        }
-        if(i >= count)break;
-        if(timeCnt.read() > timeOut) {
-            timeCnt.stop();
-            timeCnt.reset();
-            break;
-        }
-    }
-    return 0;
-}
-
-void Modem::cleanBuffer(char *buffer, int count)
-{
-    for(int i=0; i < count; i++) {
-        buffer[i] = '\0';
-    }
-}
-
-void Modem::sendCmd(const char* cmd)
-{
-    serialModem.puts(cmd);
-}
-
-void Modem::sendData(const char* data, int len)
-{
-    for (int i = 0; i < len; i++) {
-        serialModem.putc(data[i]);
-    }
-}
-
-void Modem::sendATTest(void)
-{
-    sendCmdAndWaitForResp("AT\r\n","OK",DEFAULT_TIMEOUT,CMD);
-}
+#include <stdarg.h>
+
+#define DEBUG
+
+#ifdef DEBUG
+#include "USBSerial.h"
+extern USBSerial pc;
+#define LOG(args...)        pc.printf(args)
+#else
+#define LOG(args...)
+#endif
 
-bool Modem::respCmp(const char *resp, unsigned int len, unsigned int timeout)
-{
-    int sum=0;
-    timeCnt.start();
-
-    while(1) {
-        if(serialModem.readable()) {
-            char c = serialModem.getc();
-            sum = (c==resp[sum]) ? sum+1 : 0;
-            if(sum == len)break;
-        }
-        if(timeCnt.read() > timeout) {
-            timeCnt.stop();
-            timeCnt.reset();
-            return false;
-        }
-    }
-    timeCnt.stop();
-    timeCnt.reset();
-
-    return true;
-}
-
-int Modem::waitForResp(const char *resp, unsigned int timeout,DataType type)
-{
-    int len = strlen(resp);
-    int sum=0;
-    timeCnt.start();
+int Modem::readline(char *buf, int len, uint32_t timeout)
+{
+    int bytes = 0;
+    uint32_t start = us_ticker_read();
+    timeout = timeout * 1000;               // ms to us
+    
+    while (bytes < len) {
+        if (readable()) {
+            char ch = getc();
+            if (ch == '\n') {
+                if (bytes > 0 && buf[bytes - 1] == '\r') {
+                    bytes--;
+                }
+                
+                if (bytes > 0) {
+                    buf[bytes] = '\0';
+                    
+                    return bytes;
+                }
+            } else {
+                buf[bytes] = ch;
+                bytes++;
+            }
+        } else {
+            if ((uint32_t)(us_ticker_read() - start) > timeout) {
+                LOG("wait for a line - timeout\r\n");
+                return -1;
+            }
+        }
+    }
+    
+    // buffer is not enough
+    LOG("%s %d line buffer is not enough (max_buf_size: %d)!\r\n", __FILE__, __LINE__, len);
+
+    return 0;
+}
+
+int Modem::command(const char* format, ...)
+{
+    
+    char buffer[64];
+    memset(buffer, 0, sizeof(buffer));
+    int r = 0;
+
+    va_list arg;
+    va_start(arg, format);
+    r = vsprintf(buffer, format, arg);
+    // this may not hit the heap but should alert the user anyways
+    if(r > sizeof(buffer)) {
+        error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__, sizeof(buffer), r);
+        va_end(arg);
+        return 0;
+    }
+    va_end(arg);
+    
+    
+    while (!writeable()) {
+    }
+    flush();
+
+    r = BufferedSerial::write(buffer, r);   // send command
+    
+    char response[64] = {0,};
+    readline(response, sizeof(response));       // echo enabled
+    
+    readline(response, sizeof(response));
+    
+    if (strcmp(response, "OK") == 0) {
+        return 0;
+    }
+    
+    LOG("cmd failed - w(%s), r(%s)\r\n", buffer, response);
+
+    return -1;
+}
+
+int Modem::match(const char *str, uint32_t timeout)
+{
+    const char *ptr = str;
+    uint32_t start = us_ticker_read();
+    timeout = timeout * 1000;               // ms to us
+
+    while(*ptr) {
+        if(readable()) {
+            char c = getc();
+            if (*ptr == c) {
+                ptr++;
+            } else {
+                ptr = str;
+            }
+        } else {
+            if ((uint32_t)(us_ticker_read() - start) > timeout) {
+                LOG("wait for [%s] - timeout\r\n", str);
+                return -1;
+            }
+        }
+    }
+
+    return 0;
+}
+
+void Modem::flush()
+{
+    while (readable()) {                    // flush
+        getc();
+    }
+}
+
+uint8_t Modem::read()
+{
+    while (!readable()) {
+    }
+    
+    return getc();
+}
 
-    while(1) {
-        if(serialModem.readable()) {
-            char c = serialModem.getc();
-            sum = (c==resp[sum]) ? sum+1 : 0;
-            if(sum == len)break;
-        }
-        if(timeCnt.read() > timeout) {
-            timeCnt.stop();
-            timeCnt.reset();
-            return -1;
-        }
-    }
-    timeCnt.stop();
-    timeCnt.reset();
-
-    if(type == CMD) {
-        while(serialModem.readable()) {
-            char c = serialModem.getc();
-        }
-    }
-
-    return 0;
-}
-
-int Modem::sendCmdAndWaitForResp(const char* data, const char *resp, unsigned timeout,DataType type)
-{
-    sendCmd(data);
-    return waitForResp(resp,timeout,type);
-}