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

GPRS/modem/modem.cpp

Committer:
yihui
Date:
2015-04-03
Revision:
14:3c6454f033ac
Parent:
13:379ce1d51b88

File content as of revision 14:3c6454f033ac:

/*
  modem.cpp
  2015 Copyright (c) Seeed Technology Limited.  All right reserved.
*/

#include "modem.h"
#include <stdarg.h>

#define DEBUG

#ifdef DEBUG
#include "USBSerial.h"
extern USBSerial pc;
#define LOG(args...)        pc.printf(args)
#else
#define LOG(args...)
#endif

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();
}