Last active
May 30, 2017 03:09
-
-
Save bittailor/fd6ab7e75a00221e0ade to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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