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
Diff: GPRS/modem/modem.cpp
- 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); -}