Skip to content

Instantly share code, notes, and snippets.

@bittailor
Last active May 30, 2017 03:09
Show Gist options
  • Save bittailor/fd6ab7e75a00221e0ade to your computer and use it in GitHub Desktop.
Save bittailor/fd6ab7e75a00221e0ade to your computer and use it in GitHub Desktop.
#include "GPRSClient.h"
GPRSClient::GPRSClient(Stream& pStream, uint8_t pPowerPin) : mStream(pStream), mPowerPin(pPowerPin) , mConnected(false) {
}
void GPRSClient::begin(const char* pin, const char* apn) {
pinMode(mPowerPin, OUTPUT);
digitalWrite(mPowerPin, LOW);
bool stillRunning = false;
delay(1000);
sendRaw("+++");
delay(500);
sendRaw("AT");
sendRaw("AT");
sendRaw("AT");
stillRunning = stillRunning || (clear() > 0);
if (stillRunning) {
Serial.println(F("Sim 900 still running restart it ..."));
togglePowerPin();
clear(3000);
}
Serial.println(F("Start Sim 900 ..."));
togglePowerPin();
clear(3000);
sendRaw("AT");
sendRaw("AT");
sendRaw("AT");
clear();
sendRaw("ATE0");
clear();
sendRaw("ATE0");
readResponseLine();
sendCmd("CPIN?");
bool needPin = strcmp(readResponseLine(), "+CPIN: READY") != 0;
readResponseLine();
if (needPin) {
Serial.print(F("AT+CPIN=")); Serial.println(pin);
mStream.print("AT+CPIN="); mStream.println(pin);
readResponseLine();
}
sendCmd("CSQ");
readResponseLine();
readResponseLine();
bool ready = false;
while (!ready) {
sendCmd("CREG?");
ready = strcmp(readResponseLine(), "+CREG: 0,1") == 0;
readResponseLine();
if (!ready) {
clear();
}
}
sendCmd("CIPMODE=1");
readResponseLine();
ready = false;
while (!ready) {
sendCmd("CGATT?");
ready = strcmp(readResponseLine(), "+CGATT: 1") == 0;
readResponseLine();
if (!ready) {
clear();
sendCmd("CGATT=1");
readResponseLine();
clear();
}
}
sendCmd("CSTT=\"gprs.swisscom.ch\"");
readResponseLine();
sendCmd("CIICR");
readResponseLine();;
sendCmd("CIFSR");
readResponseLine();
}
int GPRSClient::connect(IPAddress ip, uint16_t port)
{
Serial.print(AT);
Serial.print("CIPSTART=\"TCP\",\"");
ip.printTo(Serial);
Serial.print("\",\"");
Serial.print(port);
Serial.print("\"");
mStream.print(AT);
mStream.print("CIPSTART=\"TCP\",\"");
ip.printTo(mStream);
mStream.print("\",\"");
mStream.print(port);
mStream.print("\"");
if (strcmp(readResponseLine(), OK) == 0) {
if (strcmp(readResponseLine(), "CONNECT") == 0) {
mConnected = true;
return 1;
}
}
readResponseLine();
return -1;
}
int GPRSClient::connect(const char* host, uint16_t port)
{
Serial.print(AT);
Serial.print("CIPSTART=\"TCP\",\"");
Serial.print(host);
Serial.print("\",\"");
Serial.print(port);
Serial.print("\"");
mStream.print(AT);
mStream.print("CIPSTART=\"TCP\",\"");
mStream.print(host);
mStream.print("\",\"");
mStream.print(port);
mStream.println("\"");
if (strcmp(readResponseLine(20000), OK) == 0) {
if (strcmp(readResponseLine(20000), "CONNECT") == 0) {
mConnected = true;
return 1;
}
}
readResponseLine();
return -1;
}
size_t GPRSClient::write(uint8_t data)
{
return mStream.write(data);
}
size_t GPRSClient::write(const uint8_t *buf, size_t size)
{
return mStream.write(buf, size);
}
int GPRSClient::available()
{
return mStream.available();
}
int GPRSClient::read()
{
return mStream.read();
}
int GPRSClient::read(uint8_t *buf, size_t length)
{
return mStream.readBytes(buf, length);
}
int GPRSClient::peek()
{
return mStream.peek();
}
void GPRSClient::flush()
{
return mStream.flush();
}
void GPRSClient::stop()
{
delay(1000);
mStream.println("+++");
delay(500);
readResponseLine();
sendCmd("CIPCLOSE");
readResponseLine();
sendCmd("CIPSHUT");
readResponseLine();
mConnected = false;
}
uint8_t GPRSClient::connected()
{
return mConnected;
}
GPRSClient::operator bool()
{
return mConnected;
}
#ifndef __GPRSCLIENT_H__
#define __GPRSCLIENT_H__
#include <Arduino.h>
#include <Client.h>
#include <SoftwareSerial.h>
class GPRSClient: public Client {
public:
GPRSClient(Stream& pStream, uint8_t pPowerPin);
virtual ~GPRSClient() {}
void begin(const char* pin, const char* apn);
virtual int connect(IPAddress ip, uint16_t port);
virtual int connect(const char* host, uint16_t port);
virtual size_t write(uint8_t data);
virtual size_t write(const uint8_t *buf, size_t length);
virtual int available();
virtual int read();
virtual int read(uint8_t *buf, size_t length);
virtual int peek();
virtual void flush();
virtual void stop();
virtual uint8_t connected();
virtual operator bool();
private:
const char* AT = "AT+";
const char* OK = "OK";
const static int CR = 0xD;
const static int LF = 0xA;
static const size_t RESPONSE_BUFFER_SIZE = 50;
char mResponseBuffer[RESPONSE_BUFFER_SIZE + 1];
Stream& mStream;
uint8_t mPowerPin;
bool mConnected;
void togglePowerPin() {
digitalWrite(mPowerPin, HIGH);
delay(1000);
digitalWrite(mPowerPin, LOW);
}
void sendRaw(const char* cmd) {
Serial.print("send>"); Serial.println(cmd);
mStream.println(cmd);
}
void sendCmd(const char* cmd) {
Serial.print("send>"); Serial.print(AT); Serial.println(cmd);
mStream.print(AT); mStream.println(cmd);
}
void sendCmd(const __FlashStringHelper* cmd) {
Serial.print("send>"); Serial.print(AT); Serial.println(cmd);
mStream.print(AT); mStream.println(cmd);
}
const char* readResponseLine(unsigned long timeout = 5000)
{
memset(mResponseBuffer, '\0', RESPONSE_BUFFER_SIZE + 1);
unsigned long timerEnd = timeout + millis();
size_t sizeRead = 0;
while (1) {
if (mStream.available() >= 2) {
char first = mStream.read();
char second = mStream.read();
if (first == CR && second == LF) {
break;
}
Serial.println("error>Invalid start sequence");
Serial.print("f>>"); Serial.print(first); Serial.println("<<");
Serial.print("s>>"); Serial.print(second); Serial.println("<<");
return "";
}
if (millis() > timerEnd) {
Serial.println("error>timeout");
return "";
}
}
while (1) {
if (mStream.available() >= 2) {
int c = mStream.read();
if (c == CR) {
int next = mStream.read();
if (next == LF) {
break;
}
}
mResponseBuffer[sizeRead++] = c;
if (sizeRead == RESPONSE_BUFFER_SIZE) {
Serial.println("error>buffer too small");
return "";
}
}
if (millis() > timerEnd) {
Serial.println("error>timeout");
return "";
}
}
mResponseBuffer[sizeRead] = 0;
Serial.print("answ>"); Serial.print(mResponseBuffer); Serial.println("<<");
if (strcmp(mResponseBuffer, "Call Ready") == 0) {
readResponseLine();
readResponseLine();
}
return mResponseBuffer;
}
unsigned int clear(unsigned int timeout = 5000) {
unsigned int counter = 0;
Serial.println("clear >>");
unsigned long timerEnd = timeout + millis();
while (1) {
if (mStream.available()) {
counter++;
Serial.write(mStream.read());
}
if (millis() > timerEnd) {
Serial.println("<< done");
return counter;
}
}
}
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment