From 3ea0903fa8713b98f4cc44f25185d7b984ba625a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 11 Mar 2013 12:17:08 +0100 Subject: [PATCH] Added GSM shield library (AVR) --- build/shared/revisions.txt | 1 + libraries/GSM3/GSM.h | 68 ++ libraries/GSM3/GSM3CircularBuffer.cpp | 319 ++++++++++ libraries/GSM3/GSM3CircularBuffer.h | 205 ++++++ libraries/GSM3/GSM3MobileAccessProvider.cpp | 3 + libraries/GSM3/GSM3MobileAccessProvider.h | 68 ++ libraries/GSM3/GSM3MobileCellManagement.cpp | 1 + libraries/GSM3/GSM3MobileCellManagement.h | 53 ++ libraries/GSM3/GSM3MobileClientProvider.cpp | 3 + libraries/GSM3/GSM3MobileClientProvider.h | 156 +++++ libraries/GSM3/GSM3MobileClientService.cpp | 260 ++++++++ libraries/GSM3/GSM3MobileClientService.h | 162 +++++ .../GSM3/GSM3MobileDataNetworkProvider.cpp | 3 + .../GSM3/GSM3MobileDataNetworkProvider.h | 62 ++ libraries/GSM3/GSM3MobileMockupProvider.cpp | 191 ++++++ libraries/GSM3/GSM3MobileMockupProvider.h | 255 ++++++++ libraries/GSM3/GSM3MobileNetworkProvider.cpp | 72 +++ libraries/GSM3/GSM3MobileNetworkProvider.h | 136 ++++ libraries/GSM3/GSM3MobileNetworkRegistry.cpp | 51 ++ libraries/GSM3/GSM3MobileNetworkRegistry.h | 63 ++ libraries/GSM3/GSM3MobileSMSProvider.cpp | 3 + libraries/GSM3/GSM3MobileSMSProvider.h | 91 +++ libraries/GSM3/GSM3MobileServerProvider.cpp | 5 + libraries/GSM3/GSM3MobileServerProvider.h | 95 +++ libraries/GSM3/GSM3MobileServerService.cpp | 159 +++++ libraries/GSM3/GSM3MobileServerService.h | 124 ++++ libraries/GSM3/GSM3MobileVoiceProvider.cpp | 4 + libraries/GSM3/GSM3MobileVoiceProvider.h | 90 +++ libraries/GSM3/GSM3SMSService.cpp | 126 ++++ libraries/GSM3/GSM3SMSService.h | 110 ++++ libraries/GSM3/GSM3ShieldV1.cpp | 96 +++ libraries/GSM3/GSM3ShieldV1.h | 137 ++++ libraries/GSM3/GSM3ShieldV1AccessProvider.cpp | 296 +++++++++ libraries/GSM3/GSM3ShieldV1AccessProvider.h | 116 ++++ libraries/GSM3/GSM3ShieldV1BandManagement.cpp | 67 ++ libraries/GSM3/GSM3ShieldV1BandManagement.h | 96 +++ libraries/GSM3/GSM3ShieldV1BaseProvider.cpp | 27 + libraries/GSM3/GSM3ShieldV1BaseProvider.h | 73 +++ libraries/GSM3/GSM3ShieldV1CellManagement.cpp | 168 +++++ libraries/GSM3/GSM3ShieldV1CellManagement.h | 92 +++ libraries/GSM3/GSM3ShieldV1ClientProvider.cpp | 294 +++++++++ libraries/GSM3/GSM3ShieldV1ClientProvider.h | 181 ++++++ .../GSM3/GSM3ShieldV1DataNetworkProvider.cpp | 363 +++++++++++ .../GSM3/GSM3ShieldV1DataNetworkProvider.h | 140 +++++ .../GSM3/GSM3ShieldV1DirectModemProvider.cpp | 143 +++++ .../GSM3/GSM3ShieldV1DirectModemProvider.h | 118 ++++ libraries/GSM3/GSM3ShieldV1ModemCore.cpp | 198 ++++++ libraries/GSM3/GSM3ShieldV1ModemCore.h | 260 ++++++++ .../GSM3/GSM3ShieldV1ModemVerification.cpp | 79 +++ .../GSM3/GSM3ShieldV1ModemVerification.h | 64 ++ .../GSM3/GSM3ShieldV1MultiClientProvider.cpp | 583 ++++++++++++++++++ .../GSM3/GSM3ShieldV1MultiClientProvider.h | 202 ++++++ .../GSM3/GSM3ShieldV1MultiServerProvider.cpp | 357 +++++++++++ .../GSM3/GSM3ShieldV1MultiServerProvider.h | 136 ++++ libraries/GSM3/GSM3ShieldV1PinManagement.cpp | 201 ++++++ libraries/GSM3/GSM3ShieldV1PinManagement.h | 103 ++++ libraries/GSM3/GSM3ShieldV1SMSProvider.cpp | 293 +++++++++ libraries/GSM3/GSM3ShieldV1SMSProvider.h | 130 ++++ libraries/GSM3/GSM3ShieldV1ScanNetworks.cpp | 126 ++++ libraries/GSM3/GSM3ShieldV1ScanNetworks.h | 75 +++ libraries/GSM3/GSM3ShieldV1ServerProvider.cpp | 205 ++++++ libraries/GSM3/GSM3ShieldV1ServerProvider.h | 126 ++++ libraries/GSM3/GSM3ShieldV1VoiceProvider.cpp | 215 +++++++ libraries/GSM3/GSM3ShieldV1VoiceProvider.h | 137 ++++ libraries/GSM3/GSM3SoftSerial.cpp | 537 ++++++++++++++++ libraries/GSM3/GSM3SoftSerial.h | 174 ++++++ libraries/GSM3/GSM3VoiceCallService.cpp | 144 +++++ libraries/GSM3/GSM3VoiceCallService.h | 102 +++ libraries/GSM3/License.txt | 166 +++++ .../GSMPachubeClient/GSMPachubeClient.ino | 186 ++++++ .../GSMPachubeClientString.ino | 167 +++++ .../GsmTwitterClient/GsmTwitterClient.ino | 162 +++++ .../examples/GsmWebClient/GsmWebClient.ino | 106 ++++ .../examples/GsmWebServer/GsmWebServer.ino | 118 ++++ .../examples/MakeVoiceCall/MakeVoiceCall.ino | 116 ++++ .../GSM3/examples/ReceiveSMS/ReceiveSMS.ino | 98 +++ .../ReceiveVoiceCall/ReceiveVoiceCall.ino | 105 ++++ libraries/GSM3/examples/SendSMS/SendSMS.ino | 110 ++++ .../Tools/BandManagement/BandManagement.ino | 120 ++++ .../Tools/GsmScanNetworks/GsmScanNetworks.ino | 95 +++ .../Tools/PinManagement/PinManagement.ino | 168 +++++ .../GSM3/examples/Tools/TestGPRS/TestGPRS.ino | 204 ++++++ .../examples/Tools/TestModem/TestModem.ino | 77 +++ .../Tools/TestWebServer/TestWebServer.ino | 85 +++ libraries/GSM3/keywords.txt | 72 +++ 85 files changed, 11948 insertions(+) create mode 100644 libraries/GSM3/GSM.h create mode 100644 libraries/GSM3/GSM3CircularBuffer.cpp create mode 100644 libraries/GSM3/GSM3CircularBuffer.h create mode 100644 libraries/GSM3/GSM3MobileAccessProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileAccessProvider.h create mode 100644 libraries/GSM3/GSM3MobileCellManagement.cpp create mode 100644 libraries/GSM3/GSM3MobileCellManagement.h create mode 100644 libraries/GSM3/GSM3MobileClientProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileClientProvider.h create mode 100644 libraries/GSM3/GSM3MobileClientService.cpp create mode 100644 libraries/GSM3/GSM3MobileClientService.h create mode 100644 libraries/GSM3/GSM3MobileDataNetworkProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileDataNetworkProvider.h create mode 100644 libraries/GSM3/GSM3MobileMockupProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileMockupProvider.h create mode 100644 libraries/GSM3/GSM3MobileNetworkProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileNetworkProvider.h create mode 100644 libraries/GSM3/GSM3MobileNetworkRegistry.cpp create mode 100644 libraries/GSM3/GSM3MobileNetworkRegistry.h create mode 100644 libraries/GSM3/GSM3MobileSMSProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileSMSProvider.h create mode 100644 libraries/GSM3/GSM3MobileServerProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileServerProvider.h create mode 100644 libraries/GSM3/GSM3MobileServerService.cpp create mode 100644 libraries/GSM3/GSM3MobileServerService.h create mode 100644 libraries/GSM3/GSM3MobileVoiceProvider.cpp create mode 100644 libraries/GSM3/GSM3MobileVoiceProvider.h create mode 100644 libraries/GSM3/GSM3SMSService.cpp create mode 100644 libraries/GSM3/GSM3SMSService.h create mode 100644 libraries/GSM3/GSM3ShieldV1.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1.h create mode 100644 libraries/GSM3/GSM3ShieldV1AccessProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1AccessProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1BandManagement.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1BandManagement.h create mode 100644 libraries/GSM3/GSM3ShieldV1BaseProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1BaseProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1CellManagement.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1CellManagement.h create mode 100644 libraries/GSM3/GSM3ShieldV1ClientProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1ClientProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1DataNetworkProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1DataNetworkProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1DirectModemProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1DirectModemProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1ModemCore.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1ModemCore.h create mode 100644 libraries/GSM3/GSM3ShieldV1ModemVerification.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1ModemVerification.h create mode 100644 libraries/GSM3/GSM3ShieldV1MultiClientProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1MultiClientProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1MultiServerProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1MultiServerProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1PinManagement.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1PinManagement.h create mode 100644 libraries/GSM3/GSM3ShieldV1SMSProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1SMSProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1ScanNetworks.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1ScanNetworks.h create mode 100644 libraries/GSM3/GSM3ShieldV1ServerProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1ServerProvider.h create mode 100644 libraries/GSM3/GSM3ShieldV1VoiceProvider.cpp create mode 100644 libraries/GSM3/GSM3ShieldV1VoiceProvider.h create mode 100644 libraries/GSM3/GSM3SoftSerial.cpp create mode 100644 libraries/GSM3/GSM3SoftSerial.h create mode 100644 libraries/GSM3/GSM3VoiceCallService.cpp create mode 100644 libraries/GSM3/GSM3VoiceCallService.h create mode 100644 libraries/GSM3/License.txt create mode 100644 libraries/GSM3/examples/GSMPachubeClient/GSMPachubeClient.ino create mode 100644 libraries/GSM3/examples/GSMPachubeClientString/GSMPachubeClientString.ino create mode 100644 libraries/GSM3/examples/GsmTwitterClient/GsmTwitterClient.ino create mode 100644 libraries/GSM3/examples/GsmWebClient/GsmWebClient.ino create mode 100644 libraries/GSM3/examples/GsmWebServer/GsmWebServer.ino create mode 100644 libraries/GSM3/examples/MakeVoiceCall/MakeVoiceCall.ino create mode 100644 libraries/GSM3/examples/ReceiveSMS/ReceiveSMS.ino create mode 100644 libraries/GSM3/examples/ReceiveVoiceCall/ReceiveVoiceCall.ino create mode 100644 libraries/GSM3/examples/SendSMS/SendSMS.ino create mode 100644 libraries/GSM3/examples/Tools/BandManagement/BandManagement.ino create mode 100644 libraries/GSM3/examples/Tools/GsmScanNetworks/GsmScanNetworks.ino create mode 100644 libraries/GSM3/examples/Tools/PinManagement/PinManagement.ino create mode 100644 libraries/GSM3/examples/Tools/TestGPRS/TestGPRS.ino create mode 100644 libraries/GSM3/examples/Tools/TestModem/TestModem.ino create mode 100644 libraries/GSM3/examples/Tools/TestWebServer/TestWebServer.ino create mode 100644 libraries/GSM3/keywords.txt diff --git a/build/shared/revisions.txt b/build/shared/revisions.txt index fce47c728..32448769d 100644 --- a/build/shared/revisions.txt +++ b/build/shared/revisions.txt @@ -8,6 +8,7 @@ * Fixed memory leak when calling Ethernet.begin() multiple times. * Fixed SD example listfiles.ino * Fixed a lot of Esplora examples +* Added GSM library [environment] diff --git a/libraries/GSM3/GSM.h b/libraries/GSM3/GSM.h new file mode 100644 index 000000000..ec2bf6ae2 --- /dev/null +++ b/libraries/GSM3/GSM.h @@ -0,0 +1,68 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3SIMPLIFIERFILE_ +#define _GSM3SIMPLIFIERFILE_ + +// This file simplifies the use of the GSM3 library +// First we include everything. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GSM GSM3ShieldV1AccessProvider +#define GPRS GSM3ShieldV1DataNetworkProvider +#define GSMClient GSM3MobileClientService +#define GSMServer GSM3MobileServerService +#define GSMVoiceCall GSM3VoiceCallService +#define GSM_SMS GSM3SMSService + +#define GSMPIN GSM3ShieldV1PinManagement +#define GSMModem GSM3ShieldV1ModemVerification +#define GSMCell GSM3CellManagement +#define GSMBand GSM3ShieldV1BandManagement +#define GSMScanner GSM3ShieldV1ScanNetworks + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3CircularBuffer.cpp b/libraries/GSM3/GSM3CircularBuffer.cpp new file mode 100644 index 000000000..e64c57120 --- /dev/null +++ b/libraries/GSM3/GSM3CircularBuffer.cpp @@ -0,0 +1,319 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include "GSM3CircularBuffer.h" +#include + +GSM3CircularBuffer::GSM3CircularBuffer(GSM3CircularBufferManager* mgr) +{ + head=0; + tail=0; + cbm=mgr; +} + +int GSM3CircularBuffer::write(char c) +{ + byte aux=(tail+1)& __BUFFERMASK__; + if(aux!=head) + { + theBuffer[tail]=c; + // Lets put an extra zero at the end, so we can + // read chains as we like. + // This is not exactly perfect, we are always 1+ behind the head + theBuffer[aux]=0; + tail=aux; + return 1; + } + return 0; +} + +char GSM3CircularBuffer::read() +{ + char res; + if(head!=tail) + { + res=theBuffer[head]; + head=(head+1)& __BUFFERMASK__; + //if(cbm) + // cbm->spaceAvailable(); + return res; + } + else + { + return 0; + } +} + +char GSM3CircularBuffer::peek(int increment) +{ + char res; + byte num_aux; + + if (tail>head) num_aux = tail-head; + else num_aux = 128 - head + tail; + + if(increment < num_aux) + { + res=theBuffer[head]; + return res; + } + else + { + return 0; + } +} + +void GSM3CircularBufferManager::spaceAvailable(){return;}; + +void GSM3CircularBuffer::flush() +{ + head=tail; +} + +char* GSM3CircularBuffer::nextString() +{ + while(head!=tail) + { + head=(head+1) & __BUFFERMASK__; + if(theBuffer[head]==0) + { + head=(head+1) & __BUFFERMASK__; + return (char*)theBuffer+head; + } + } + return 0; +} + + +bool GSM3CircularBuffer::locate(const char* reference) +{ + + return locate(reference, head, tail, 0, 0); +} + +bool GSM3CircularBuffer::chopUntil(const char* reference, bool movetotheend, bool usehead) +{ + byte from, to; + + if(locate(reference, head, tail, &from, &to)) + { + if(usehead) + { + if(movetotheend) + head=(to+1) & __BUFFERMASK__; + else + head=from; + } + else + { + if(movetotheend) + tail=(to+1) & __BUFFERMASK__; + else + tail=from; + } + return true; + } + else + { + return false; + } +} + +bool GSM3CircularBuffer::locate(const char* reference, byte thishead, byte thistail, byte* from, byte* to) +{ + int refcursor=0; + bool into=false; + byte b2, binit; + bool possible=1; + + if(reference[0]==0) + return true; + + for(byte b1=thishead; b1!=thistail;b1=(b1+1)& __BUFFERMASK__) + { + possible = 1; + b2 = b1; + while (possible&&(b2!=thistail)) + { + if(theBuffer[b2]==reference[refcursor]) + { + if(!into) + binit=b2; + into=true; + refcursor++; + if(reference[refcursor]==0) + { + if(from) + *from=binit; + if(to) + *to=b2; + return true; + } + } + else if (into==true) + { + possible = 0; + into=false; + refcursor=0; + } + b2=(b2+1)& __BUFFERMASK__; + } + } + return false; +} + +bool GSM3CircularBuffer::extractSubstring(const char* from, const char* to, char* buffer, int bufsize) +{ + byte t1; + byte h2; + byte b; + int i; + +//DEBUG +//Serial.println("Beginning extractSubstring"); +//Serial.print("head,tail=");Serial.print(int(head));Serial.print(",");Serial.println(int(tail)); + + if(!locate(from, head, tail, 0, &t1)) + return false; + +//DEBUG +//Serial.println("Located chain from."); + + t1++; //To point the next. + if(!locate(to, t1, tail, &h2, 0)) + return false; + +//DEBUG +//Serial.println("Located chain to."); +/*Serial.print("t1=");Serial.println(int(t1)); +Serial.print("h2=");Serial.println(int(h2));*/ + + + for(i=0,b=t1;i='0')&&(c<='9')) + { + anyfound=true; + res=(res*10)+(int)c-48; + } + else + { + if(negative) + res=(-1)*res; + return res; + } + } + if(negative) + res=(-1)*res; + return res; +} + +void GSM3CircularBuffer::debugBuffer() +{ + byte h1=head; + byte t1=tail; + Serial.println(); + Serial.print(h1); + Serial.print(" "); + Serial.print(t1); + Serial.print('>'); + for(byte b=h1; b!=t1; b=(b+1)& __BUFFERMASK__) + printCharDebug(theBuffer[b]); + Serial.println(); +} + +void GSM3CircularBuffer::printCharDebug(uint8_t c) +{ + if((c>31)&&(c<127)) + Serial.print((char)c); + else + { + Serial.print('%'); + Serial.print(c); + Serial.print('%'); + } +} + +bool GSM3CircularBuffer::retrieveBuffer(char* buffer, int bufsize, int& SizeWritten) +{ + byte b; + int i; + + /*for(i=0,b=head;i +#include + +#ifndef byte +#define byte uint8_t +#endif + +// These values have to be interrelated +// To-Do: may we have just one? (BUFFERMASK) +#define __BUFFERSIZE__ 128 +#define __BUFFERMASK__ 0x7F + +class GSM3CircularBufferManager +{ + public: + + /** If there is spaceAvailable in the buffer, lets send a XON + */ + virtual void spaceAvailable(); +}; + +class GSM3CircularBuffer +{ + private: + // Buffer pointers. + // head=tail means buffer empty + // tail=head-1 means buffer full + // tail=head+1 means just one char (pointed by head) + // REMEMBER. head can be moved only by the main program + // REMEMBER. tail can be moved only by the other thread (interrupts) + // REMEMBER. head and tail can move only FORWARD + volatile byte head; // First written one + volatile byte tail; // Last written one. + + GSM3CircularBufferManager* cbm; // Circular buffer manager + + // The buffer + volatile byte theBuffer[__BUFFERSIZE__]; + + /** Checks if a substring exists in the buffer + @param reference Substring + @param thishead Head + @param thistail Tail + @param from Initial byte position + @param to Final byte position + @return true if exists, in otherwise return false + */ + bool locate(const char* reference, byte thishead, byte thistail, byte* from=0, byte* to=0); + + public: + + /** Constructor + @param mgr Circular buffer manager + */ + GSM3CircularBuffer(GSM3CircularBufferManager* mgr=0); + + // TO-DO.Check if this formule runs too at the buffer limit + + /** Get available bytes in circular buffer + @return available bytes + */ + inline byte availableBytes(){ return ((head-(tail+1))&__BUFFERMASK__);}; + + /** Stored bytes in circular buffer + @return stored bytes + */ + inline byte storedBytes(){ return ((tail-head)&__BUFFERMASK__);}; + + /** Write a character in circular buffer + @param c Character + @return 1 if successful + */ + int write(char c); + + /** Returns a character and moves the pointer + @return character + */ + char read(); + + /** Returns a character but does not move the pointer. + @param increment Increment + @return character + */ + char peek(int increment); + + /** Returns a pointer to the head of the buffer + @return buffer with pointer in head + */ + inline char* firstString(){return (char*)theBuffer+head;}; + + /** Go forward one string + @return buffer with one string advance + */ + char* nextString(); + + /** Flush circular buffer + */ + void flush(); + + /** Get tail + @return tail + */ + inline byte getTail(){return tail;}; + + /** Get head + @return head + */ + inline byte getHead(){return head;}; + + // Only can be executed from the interrupt! + /** Delete circular buffer to the end + @param from Initial byte position + */ + inline void deleteToTheEnd(byte from){tail=from;}; + + /** Checks if a substring exists in the buffer + move=0, dont move, =1,put head at the beginning of the string, =2, put head at the end + @param reference + @return true if exists, in otherwise return false + */ + bool locate(const char* reference); + + /** Locates reference. If found, moves head (or tail) to the beginning (or end) + @param reference + @param movetotheend + @param head + @return true if successful + */ + bool chopUntil(const char* reference, bool movetotheend, bool head=true); + + /** Reads an integer from the head. Stops with first non blank, non number character + @return integer from the head + */ + int readInt(); + + // Caveat: copies the first bytes until buffer is full + + /** Extract a substring from circular buffer + @param from Initial byte position + @param to Final byte position + @param buffer Buffer for copy substring + @param bufsize Buffer size + @return true if successful, false if substring does not exists + */ + bool extractSubstring(const char* from, const char* to, char* buffer, int bufsize); + + /** Retrieve all the contents of buffer from head to tail + @param buffer + @param bufsize + @param SizeWritten + @return true if successful + */ + bool retrieveBuffer(char* buffer, int bufsize, int& SizeWritten); + + /** Debug function to print the buffer after receiving data from the modem. + */ + void debugBuffer(); + + /** Utility: dump character if printable, else, put in %x% + @param c Character + */ + static void printCharDebug(uint8_t c); + + +}; + + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileAccessProvider.cpp b/libraries/GSM3/GSM3MobileAccessProvider.cpp new file mode 100644 index 000000000..02d108081 --- /dev/null +++ b/libraries/GSM3/GSM3MobileAccessProvider.cpp @@ -0,0 +1,3 @@ +#include + +GSM3MobileAccessProvider* theGSM3MobileAccessProvider; \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileAccessProvider.h b/libraries/GSM3/GSM3MobileAccessProvider.h new file mode 100644 index 000000000..21ecd1b01 --- /dev/null +++ b/libraries/GSM3/GSM3MobileAccessProvider.h @@ -0,0 +1,68 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILEACCESSPROVIDER_ +#define _GSM3MOBILEACCESSPROVIDER_ + +enum GSM3_NetworkStatus_t { ERROR, IDLE, CONNECTING, GSM_READY, GPRS_READY, TRANSPARENT_CONNECTED}; + +class GSM3MobileAccessProvider +{ + public: + // Access functions + //Configuration functions. + /** Establish GSM connection + @param pin PIN code + @param restart Determines if hardware restart + @param synchronous Determines sync mode + @return If synchronous, GSM3_NetworkStatus_t. If asynchronous, returns 0. + */ + virtual inline GSM3_NetworkStatus_t begin(char* pin=0,bool restart=true, bool synchronous=true)=0; + + /** Check network access status + @return 1 if Alive, 0 if down + */ + virtual inline int isAccessAlive()=0; + + /** Shutdown the modem (power off really) + @return true if successful + */ + virtual inline bool shutdown()=0; + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + virtual int ready()=0; +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileCellManagement.cpp b/libraries/GSM3/GSM3MobileCellManagement.cpp new file mode 100644 index 000000000..1db20b94a --- /dev/null +++ b/libraries/GSM3/GSM3MobileCellManagement.cpp @@ -0,0 +1 @@ +#include \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileCellManagement.h b/libraries/GSM3/GSM3MobileCellManagement.h new file mode 100644 index 000000000..035dfee99 --- /dev/null +++ b/libraries/GSM3/GSM3MobileCellManagement.h @@ -0,0 +1,53 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILECELLMANAGEMENT_ +#define _GSM3MOBILECELLMANAGEMENT_ + +#include + +class GSM3MobileCellManagement +{ + public: + + virtual inline int getLocation() {return 0;}; + + virtual inline int getICCID() {return 0;}; + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + virtual int ready()=0; +}; + +#endif diff --git a/libraries/GSM3/GSM3MobileClientProvider.cpp b/libraries/GSM3/GSM3MobileClientProvider.cpp new file mode 100644 index 000000000..3636a75d2 --- /dev/null +++ b/libraries/GSM3/GSM3MobileClientProvider.cpp @@ -0,0 +1,3 @@ +#include + +GSM3MobileClientProvider* theGSM3MobileClientProvider; \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileClientProvider.h b/libraries/GSM3/GSM3MobileClientProvider.h new file mode 100644 index 000000000..a771ff46d --- /dev/null +++ b/libraries/GSM3/GSM3MobileClientProvider.h @@ -0,0 +1,156 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_MOBILECLIENTPROVIDER__ +#define __GSM3_MOBILECLIENTPROVIDER__ + +#include +#include + +class GSM3MobileClientProvider +{ + protected: + + uint8_t sockets; + + public: + + /** Constructor */ + GSM3MobileClientProvider(){}; + + /** Minimum socket + @return socket + */ + virtual inline int minSocket()=0; + + /** Maximum socket + @return socket + */ + virtual inline int maxSocket()=0; + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + virtual int ready()=0; + + /** Get status socket client + @param socket Socket + @return 1 if connected + */ + virtual bool getStatusSocketClient(uint8_t socket)=0; + + // Socket management + + /** Get socket + @param socket Socket + @return socket + */ + virtual int getSocket(int socket=-1)=0; + + /** Release socket + @param socket Socket + */ + virtual void releaseSocket(int socket)=0; + + // Client socket functions + + /** Connect to a server via TCP connection + @param server Server name or IP address in a String + @param port Port + @param id_socket Socket + @return 0 if command running, 1 if success, otherwise error + */ + virtual int connectTCPClient(const char* server, int port, int id_socket)=0; + + /** Connect to a server (by IP address) via TCP connection + @param add IP address in IPAddress format + @param port Port + @param id_socket Socket + @return 0 if command running, 1 if success, otherwise error + */ + virtual int connectTCPClient(IPAddress add, int port, int id_socket)=0; + + /** Begin writing through a socket + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + virtual void beginWriteSocket(bool client1Server0, int id_socket)=0; + + /** Write through a socket. MUST go after beginWriteSocket() + @param c character to be written + */ + virtual void writeSocket(uint8_t c)=0; + + /** Write through a socket. MUST go after beginWriteSocket() + @param buf characters to be written (final 0 will not be written) + */ + virtual void writeSocket(const char* buf)=0; + + /** Finish current writing + */ + virtual void endWriteSocket()=0; + + /** Check if there are data to be read in socket. + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if there are data available, 4 if no data, otherwise error + */ + virtual int availableSocket(bool client, int id_socket)=0; + + /** Read data (get a character) available in socket + @return character + */ + virtual int readSocket()=0; + + /** Flush socket + */ + virtual void flushSocket()=0; + + /** Get a character but will not advance the buffer head + @return character + */ + virtual int peekSocket()=0; + + /** Close a socket + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Socket + @return 0 if command running, 1 if success, otherwise error + */ + virtual int disconnectTCP(bool client1Server0, int idsocket)=0; + +}; + +extern GSM3MobileClientProvider* theGSM3MobileClientProvider; + +#endif diff --git a/libraries/GSM3/GSM3MobileClientService.cpp b/libraries/GSM3/GSM3MobileClientService.cpp new file mode 100644 index 000000000..a913f54ba --- /dev/null +++ b/libraries/GSM3/GSM3MobileClientService.cpp @@ -0,0 +1,260 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include +#include + +// While there is only a shield (ShieldV1) we will include it by default +#include +GSM3ShieldV1ClientProvider theShieldV1ClientProvider; + + +#define GSM3MOBILECLIENTSERVICE_CLIENT 0x01 // 1: This side is Client. 0: This side is Server +#define GSM3MOBILECLIENTSERVICE_WRITING 0x02 // 1: TRUE 0: FALSE +#define GSM3MOBILECLIENTSERVICE_SYNCH 0x04 // 1: TRUE, compatible with other clients 0: FALSE + +#define __TOUTBEGINWRITE__ 10000 + + +GSM3MobileClientService::GSM3MobileClientService(bool synch) +{ + flags = GSM3MOBILECLIENTSERVICE_CLIENT; + if(synch) + flags |= GSM3MOBILECLIENTSERVICE_SYNCH; + mySocket=255; +} + +GSM3MobileClientService::GSM3MobileClientService(int socket, bool synch) +{ + // We are creating a socket on an existing, occupied one. + flags=0; + if(synch) + flags |= GSM3MOBILECLIENTSERVICE_SYNCH; + mySocket=socket; + theGSM3MobileClientProvider->getSocket(socket); + +} + +// Returns 0 if last command is still executing +// 1 if success +// >1 if error +int GSM3MobileClientService::ready() +{ + return theGSM3MobileClientProvider->ready(); +} + +int GSM3MobileClientService::connect(IPAddress add, uint16_t port) +{ + if(theGSM3MobileClientProvider==0) + return 2; + + // TODO: ask for the socket id + mySocket=theGSM3MobileClientProvider->getSocket(); + + if(mySocket<0) + return 2; + + int res=theGSM3MobileClientProvider->connectTCPClient(add, port, mySocket); + if(flags & GSM3MOBILECLIENTSERVICE_SYNCH) + res=waitForAnswer(); + + return res; +}; + +int GSM3MobileClientService::connect(const char *host, uint16_t port) +{ + + if(theGSM3MobileClientProvider==0) + return 2; + // TODO: ask for the socket id + mySocket=theGSM3MobileClientProvider->getSocket(); + + if(mySocket<0) + return 2; + + int res=theGSM3MobileClientProvider->connectTCPClient(host, port, mySocket); + if(flags & GSM3MOBILECLIENTSERVICE_SYNCH) + res=waitForAnswer(); + + return res; +} + +int GSM3MobileClientService::waitForAnswer() +{ + unsigned long m; + m=millis(); + int res; + + while(((millis()-m)< __TOUTBEGINWRITE__ )&&(ready()==0)) + delay(100); + + res=ready(); + + // If we get something different from a 1, we are having a problem + if(res!=1) + res=0; + + return res; +} + +void GSM3MobileClientService::beginWrite(bool sync) +{ + flags |= GSM3MOBILECLIENTSERVICE_WRITING; + theGSM3MobileClientProvider->beginWriteSocket(flags & GSM3MOBILECLIENTSERVICE_CLIENT, mySocket); + if(sync) + waitForAnswer(); +} + +size_t GSM3MobileClientService::write(uint8_t c) +{ + if(!(flags & GSM3MOBILECLIENTSERVICE_WRITING)) + beginWrite(true); + theGSM3MobileClientProvider->writeSocket(c); + return 1; +} + +size_t GSM3MobileClientService::write(const uint8_t* buf) +{ + if(!(flags & GSM3MOBILECLIENTSERVICE_WRITING)) + beginWrite(true); + theGSM3MobileClientProvider->writeSocket((const char*)(buf)); + return strlen((const char*)buf); +} + +size_t GSM3MobileClientService::write(const uint8_t* buf, size_t sz) +{ + if(!(flags & GSM3MOBILECLIENTSERVICE_WRITING)) + beginWrite(true); + for(int i=0;iwriteSocket(buf[i]); + return sz; +} + +void GSM3MobileClientService::endWrite(bool sync) +{ + flags ^= GSM3MOBILECLIENTSERVICE_WRITING; + theGSM3MobileClientProvider->endWriteSocket(); + if(sync) + waitForAnswer(); +} + +uint8_t GSM3MobileClientService::connected() +{ + if(mySocket==255) + return 0; + return theGSM3MobileClientProvider->getStatusSocketClient(mySocket); +} + +GSM3MobileClientService::operator bool() +{ + return connected()==1; +}; + +int GSM3MobileClientService::available() +{ + int res; + + // Even if not connected, we are looking for available data + + if(flags & GSM3MOBILECLIENTSERVICE_WRITING) + endWrite(true); + + res=theGSM3MobileClientProvider->availableSocket(flags & GSM3MOBILECLIENTSERVICE_CLIENT,mySocket); + if(flags & GSM3MOBILECLIENTSERVICE_SYNCH) + res=waitForAnswer(); + + return res; +} + +int GSM3MobileClientService::read(uint8_t *buf, size_t size) +{ + int i; + uint8_t c; + + for(i=0;ireadSocket(flags & GSM3MOBILECLIENTSERVICE_CLIENT, (char *)(buf), size, mySocket); + + return res; +*/ +} + +int GSM3MobileClientService::read() +{ + if(flags & GSM3MOBILECLIENTSERVICE_WRITING) + endWrite(true); + int c=theGSM3MobileClientProvider->readSocket(); + return c; +} + +int GSM3MobileClientService::peek() +{ + if(flags & GSM3MOBILECLIENTSERVICE_WRITING) + endWrite(true); + return theGSM3MobileClientProvider->peekSocket(/*mySocket, false*/); +} + +void GSM3MobileClientService::flush() +{ + if(flags & GSM3MOBILECLIENTSERVICE_WRITING) + endWrite(true); + theGSM3MobileClientProvider->flushSocket(/*mySocket*/); + if(flags & GSM3MOBILECLIENTSERVICE_SYNCH) + waitForAnswer(); + +} + +void GSM3MobileClientService::stop() +{ + if(flags & GSM3MOBILECLIENTSERVICE_WRITING) + endWrite(true); + theGSM3MobileClientProvider->disconnectTCP(flags & GSM3MOBILECLIENTSERVICE_CLIENT, mySocket); + theGSM3MobileClientProvider->releaseSocket(mySocket); + mySocket = 0; + if(flags & GSM3MOBILECLIENTSERVICE_SYNCH) + waitForAnswer(); +} + diff --git a/libraries/GSM3/GSM3MobileClientService.h b/libraries/GSM3/GSM3MobileClientService.h new file mode 100644 index 000000000..5a36a975c --- /dev/null +++ b/libraries/GSM3/GSM3MobileClientService.h @@ -0,0 +1,162 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILECLIENTSERVICE_ +#define _GSM3MOBILECLIENTSERVICE_ + +#include +#include + + +class GSM3MobileClientService : public Client +{ + private: + + uint8_t mySocket; + uint8_t flags; + + /** Blocks waiting for an answer + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int waitForAnswer(); + + public: + + /** Constructor + @param synch Sync mode + */ + GSM3MobileClientService(bool synch=true); + + /** Constructor + @param socket Socket + @param synch Sync mode + */ + GSM3MobileClientService(int socket, bool synch); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(); + + // we take this function out as IPAddress is complex to bring to + // version 1. + /** Connect to server by IP address + @param (IPAddress) + @param (uint16_t) + @return returns 0 if last command is still executing, 1 success, 2 if there are no resources + */ + inline int connect(IPAddress, uint16_t); + + /** Connect to server by hostname + @param host Hostname + @param port Port + @return returns 0 if last command is still executing, 1 success, 2 if there are no resources + */ + int connect(const char *host, uint16_t port); + + /** Initialize write in request + @param sync Sync mode + */ + void beginWrite(bool sync=false); + + /** Write a character in request + @param c Character + @return size + */ + size_t write(uint8_t c); + + /** Write a characters buffer in request + @param buf Buffer + @return buffer size + */ + size_t write(const uint8_t *buf); + + /** Write a characters buffer with size in request + @param (uint8_t*) Buffer + @param (size_t) Buffer size + @return buffer size + */ + size_t write(const uint8_t*, size_t); + + /** Finish write request + @param sync Sync mode + */ + void endWrite(bool sync=false); + + /** Check if connected to server + @return 1 if connected + */ + uint8_t connected(); + + operator bool(); + + /** Read from response buffer and copy size specified to buffer + @param buf Buffer + @param size Buffer size + @return bytes read + */ + int read(uint8_t *buf, size_t size); + + /** Read a character from response buffer + @return character + */ + int read(); + + /** Check if exists a response available + @return 1 if exists, 0 if not exists + */ + int available(); + + /** Read a character from response buffer but does not move the pointer. + @return character + */ + int peek(); + + /** Flush response buffer + */ + void flush(); + + /** Stop client + */ + void stop(); + + /** Get socket + @return socket + */ + inline int getSocket(){return (int)mySocket;}; + + +}; + + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileDataNetworkProvider.cpp b/libraries/GSM3/GSM3MobileDataNetworkProvider.cpp new file mode 100644 index 000000000..538f6d439 --- /dev/null +++ b/libraries/GSM3/GSM3MobileDataNetworkProvider.cpp @@ -0,0 +1,3 @@ +#include + +// GSM3MobileDataNetworkProvider* theGSM3MobileDataNetworkProvider; \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileDataNetworkProvider.h b/libraries/GSM3/GSM3MobileDataNetworkProvider.h new file mode 100644 index 000000000..bffd381fa --- /dev/null +++ b/libraries/GSM3/GSM3MobileDataNetworkProvider.h @@ -0,0 +1,62 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILEDATANETWORKPROVIDER_ +#define _GSM3MOBILEDATANETWORKPROVIDER_ + +#include + +// This class is not really useful, but serves as a guideline for programmers +// We keep it but it should never be linked +class GSM3MobileDataNetworkProvider +{ + public: + + /** Attach to GPRS/GSM network + @param networkId APN GPRS + @param user Username + @param pass Password + @return connection status + */ + virtual GSM3_NetworkStatus_t networkAttach(char* networId, char* user, char* pass)=0; + + /** Detach GPRS/GSM network + @return connection status + */ + virtual GSM3_NetworkStatus_t networkDetach()=0; + +}; + +extern GSM3MobileDataNetworkProvider* theGSM3MobileDataNetworkProvider; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileMockupProvider.cpp b/libraries/GSM3/GSM3MobileMockupProvider.cpp new file mode 100644 index 000000000..b39ee26f5 --- /dev/null +++ b/libraries/GSM3/GSM3MobileMockupProvider.cpp @@ -0,0 +1,191 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include +#include +#include + + +GSM3MobileMockupProvider::GSM3MobileMockupProvider() +{ + lineStatus=IDLE; + msgExample="Hello#World"; + msgIndex=0; +}; + +int GSM3MobileMockupProvider::begin(char* pin) +{ + Serial.println("GSM3MobileMockupProvider::begin()"); + return 0; +}; + +int GSM3MobileMockupProvider::ready() +{ + Serial.println("GSM3MobileMockupProvider::ready()"); + return 1; +}; + +int GSM3MobileMockupProvider::beginSMS(const char* number) +{ + Serial.println("SM3MobileMockupProvider::beginSMS()"); + return 0; +}; + +void GSM3MobileMockupProvider::writeSMS(char c) +{ + Serial.print(c); +}; + +int GSM3MobileMockupProvider::endSMS() +{ + Serial.println("GSM3MobileMockupProvider::endSMS()"); +}; + +int GSM3MobileMockupProvider::availableSMS() +{ + Serial.println("GSM3MobileMockupProvider::availableSMS()"); + return 120; +}; + +int GSM3MobileMockupProvider::peek() +{ + return (int)'H'; +}; + +int GSM3MobileMockupProvider::remoteSMSNumber(char* number, int nlength) +{ + if(nlength>=13) + strcpy(number, "+34630538546"); + return 12; +}; + + +void GSM3MobileMockupProvider::flushSMS() +{ + Serial.println("GSM3MobileMockupProvider::flushSMS()"); +}; + +int GSM3MobileMockupProvider::readSMS() +{ + if(msgExample[msgIndex]==0) + { + msgIndex=0; + return 0; + } + else + { + msgIndex++; + return msgExample[msgIndex-1]; + }; +}; + +int GSM3MobileMockupProvider::connectTCPClient(const char* server, int port, int id_socket) +{ + Serial.println("GSM3MobileMockupProvider::connectTCPClient()"); + Serial.print(server);Serial.print(":");Serial.print(port);Serial.print("-");Serial.println(id_socket); +} + +void GSM3MobileMockupProvider::writeSocket(const uint8_t *buf, size_t size, int id_socket) +{ + int i; + for(i=0;i=minSocket())&&(socket<=maxSocket())) + return 1; + else + return 0; +}; +*/ + +int GSM3MobileMockupProvider::readSocket(uint8_t *buf, size_t size, int idsocket) +{ + int i; + int l=strlen(msgExample); + for(i=0;(i12)) + strcpy("192.168.1.1", localIP); + return 1; +}; + +bool GSM3MobileMockupProvider::getSocketModemStatus(uint8_t s) +{ + // Feeling lazy + return true; +} + diff --git a/libraries/GSM3/GSM3MobileMockupProvider.h b/libraries/GSM3/GSM3MobileMockupProvider.h new file mode 100644 index 000000000..59eee4185 --- /dev/null +++ b/libraries/GSM3/GSM3MobileMockupProvider.h @@ -0,0 +1,255 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILEMOCKUPPROVIDER_ +#define _GSM3MOBILEMOCKUPPROVIDER_ + +#include +#include + +class GSM3MobileMockupProvider: public GSM3MobileNetworkProvider +{ + private: + // Introducing this status is quite "heavy". But something like this should + // be added to ShieldV1. Or not. + // Note, in ShieldV1 there is no "RECEIVINGSMS" status. + enum GSM3_modemlinest_e { IDLE, WAITINGANSWER, SENDINGSMS}; + GSM3_modemlinest_e lineStatus; + char* msgExample; + int msgIndex; + + public: + + /** Minimum socket + @return 1 + */ + inline int minSocket(){return 1;}; + + /** Maximum socket + @return 8 + */ + inline int maxSocket(){return 8;}; + + /** Constructor */ + GSM3MobileMockupProvider(); + + /** Get network status + @return network status + */ + inline GSM3_NetworkStatus_t getStatus(){return ERROR;}; + + /** Get voice call status + @return call status + */ + inline GSM3_voiceCall_st getvoiceCallStatus(){return IDLE_CALL;}; + + /** Get last command status + @return Returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(); + inline void closeCommand(int code){}; + + //Configuration functions. + + /** Begin connection + @param pin PIN code + @return + */ + int begin(char* pin=0); + + /** Check if is modem alive + @return 0 + */ + inline int isModemAlive(){return 0;}; + + /** Shutdown the modem (power off really) + @return true if successful + */ + inline bool shutdown(){return false;}; + + //Call functions + + /** Launch a voice call + @param number Phone number to be called + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + inline int voiceCall(const char* number){return 0;}; + + /** Answer a voice call + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + inline int answerCall(){return 0;}; + + /** Hang a voice call + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + inline int hangCall(){return 0;}; + + /** Retrieve phone number of caller + @param buffer Buffer for copy phone number + @param bufsize Buffer size + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + inline int retrieveCallingNumber(char* buffer, int*& bufsize){return 0;}; + + // SMS functions + + /** Begin a SMS to send it + @param number Destination + @return error command if it exists + */ + int beginSMS(const char* number); + + /** End SMS + @return error command if it exists + */ + int endSMS(); + + /** Check if SMS available and prepare it to be read + @return error command if it exists + */ + int availableSMS(); + + /** Read a byte but do not advance the buffer header (circular buffer) + @return character + */ + int peek(); + + /** Delete the SMS from Modem memory and proccess answer + */ + void flushSMS(); + + /** Read sender number phone + @param number Buffer for save number phone + @param nlength Buffer length + @return 1 success, >1 error + */ + int remoteSMSNumber(char* number, int nlength); + + /** Read one char for SMS buffer (advance circular buffer) + @return character + */ + int readSMS(); + + /** Write a SMS character by character + @param c Character + */ + void writeSMS(char c); + + // Socket functions + + /** Connect to a remote TCP server + @param server String with IP or server name + @param port Remote port number + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + int connectTCPClient(const char* server, int port, int id_socket); + + // Attention to parameter rewriting in ShieldV1 + /** Write buffer information into a socket + @param buf Buffer + @param size Buffer size + @param idsocket Socket + */ + void writeSocket(const uint8_t *buf, size_t size, int idsocket); + + // ShieldV1 will have two reading mechanisms: + // Mechanism 1: Call AT+QIRD for size bytes. Put them in the circular buffer, + // fill buf. Take care to xon/xoff effect, as we may copy just a part of the + // incoming bytes. + /** Read socket and put information in a buffer + @param buf Buffer + @param size Buffer size + @param idsocket Socket + @return + */ + int readSocket(uint8_t *buf, size_t size, int idsocket); + + // Mechanism 2 in ShieldV1: + // When called "available()" or "read()" reuse readSocket code to execute + // QIRD SYNCHRONOUSLY. Ask the modem for 1500 bytes but do not copy them anywhere, + // leave data in the circular buffer. Put buffer head at the start of received data. + // Peek() will get a character but will not advance the buffer head. + // Read() will get one character. XON/XOFF will take care of buffer filling + // If Read() gets to the end of the QIRD response, execute again QIRD SYNCHRONOUSLY + // If the user executes flush(), execute read() until there is nothing more to read() + // (the modem gives no way to empty the socket of incoming data) + + /** Check if there are data to be read in socket. + @param idsocket Local socket number + @return 0 if command running, 1 if there are data available, 4 if no data, otherwise error + */ + int availableSocket(int idsocket); + + /** Read data (get a character) available in socket + @param idsocket Socket + @param advance Determines if advance the buffer head + @return character + */ + int readSocket(int idsocket, bool advance=true); + + /** Flush socket + @param idsocket Socket + */ + void flushSocket(int idsocket); + + // This is the same in ShieldV1 + /** Close a socket + @param idsocket Socket + @return 0 if command running, 1 if success, otherwise error + */ + int disconnectTCP(int idsocket); + + // TCP Server. Attention. Changing the int*&. We'll receive a buffer for the IP + // If the pointer ins NULL just forget it + // I think that opening a server does not occupy a socket. Is that true? + /** Establish a TCP connection + @param port Port + @param localIP IP address + @param localIPlength IP address size in characters + @return command error if exists + */ + int connectTCPServer(int port, char* localIP, int* localIPlength); + + // Modem sockets status. Return TRUE if the modem thinks the socket is occupied. + // This should be detected through an unrequisited response + /** Get modem status + @param s Socket + @return modem status (true if connected) + */ + bool getSocketModemStatus(uint8_t s); + + +}; +#endif diff --git a/libraries/GSM3/GSM3MobileNetworkProvider.cpp b/libraries/GSM3/GSM3MobileNetworkProvider.cpp new file mode 100644 index 000000000..a8a91c219 --- /dev/null +++ b/libraries/GSM3/GSM3MobileNetworkProvider.cpp @@ -0,0 +1,72 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include + +GSM3MobileNetworkProvider* theProvider; + +GSM3MobileNetworkProvider::GSM3MobileNetworkProvider() +{ + socketsAsServer=0x0000; +}; + + +int GSM3MobileNetworkProvider::getNewOccupiedSocketAsServer() +{ + int i; + for(i=minSocketAsServer(); i<=maxSocketAsServer(); i++) + { + if ((!(socketsAsServer&(0x0001< +#include +#include +#include + +class GSM3MobileNetworkProvider +{ + private: + + /** Restart hardware + @return 1 if successful + */ + int HWrestart(); + + uint16_t socketsAsServer; // Server socket + + /** Get modem status + @param s Socket + @return modem status (true if connected) + */ + virtual inline bool getSocketAsServerModemStatus(int s){return false;}; + + public: + + /** minSocketAsServer + @return 0 + */ + virtual inline int minSocketAsServer(){return 0;}; + + /** maxSocketAsServer + @return 0 + */ + virtual inline int maxSocketAsServer(){return 0;}; + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + virtual int ready()=0; + + /** Constructor */ + GSM3MobileNetworkProvider(); + + /** Get network status + @return network status + */ + virtual inline GSM3_NetworkStatus_t getStatus(){return ERROR;}; + + /** Get socket client status + @param socket Socket + @return 1 if connected, 0 otherwise + */ + bool getStatusSocketClient(uint8_t socket); + + /** Close a AT command + @param code Close code + */ + virtual inline void closeCommand(int code){}; + + /** Establish a TCP connection + @param port Port + @param localIP IP address + @param localIPlength IP address size in characters + @return command error if exists + */ + virtual inline int connectTCPServer(int port, char* localIP, int localIPlength){return 0;}; + + /** Get local IP address + @param LocalIP Buffer for save IP address + @param LocalIPlength Buffer size + */ + virtual inline int getIP(char* LocalIP, int LocalIPlength){return 0;}; + + /** Get new occupied socket + @return -1 if no new socket has been occupied + */ + int getNewOccupiedSocketAsServer(); + + /** Get socket status as server + @param socket Socket to get status + @return socket status + */ + bool getStatusSocketAsServer(uint8_t socket); + + /** Close a socket + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + int disconnectTCP(bool client1Server0, int idsocket){return 1;}; + + /** Release socket + @param socket Socket + */ + void releaseSocket(int socket){}; + +}; + +extern GSM3MobileNetworkProvider* theProvider; + +#endif diff --git a/libraries/GSM3/GSM3MobileNetworkRegistry.cpp b/libraries/GSM3/GSM3MobileNetworkRegistry.cpp new file mode 100644 index 000000000..5e22f3af8 --- /dev/null +++ b/libraries/GSM3/GSM3MobileNetworkRegistry.cpp @@ -0,0 +1,51 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include + +GSM3MobileNetworkRegistry::GSM3MobileNetworkRegistry() +{ + theProvider=0; +}; + +void GSM3MobileNetworkRegistry::registerMobileNetworkProvider(GSM3MobileNetworkProvider* provider) +{ + theProvider=provider; +} + +GSM3MobileNetworkProvider* GSM3MobileNetworkRegistry::getMobileNetworkProvider() +{ + return theProvider; +} + +GSM3MobileNetworkRegistry theMobileNetworkRegistry; diff --git a/libraries/GSM3/GSM3MobileNetworkRegistry.h b/libraries/GSM3/GSM3MobileNetworkRegistry.h new file mode 100644 index 000000000..de4397725 --- /dev/null +++ b/libraries/GSM3/GSM3MobileNetworkRegistry.h @@ -0,0 +1,63 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILENETWORKREGISTRY_ +#define _GSM3MOBILENETWORKREGISTRY_ +#include + +class GSM3MobileNetworkRegistry +{ + private: + + GSM3MobileNetworkProvider* theProvider; // Network provider + + public: + + /** Constructor */ + GSM3MobileNetworkRegistry(); + + /** Register in mobile network provider + @param provider Provider + */ + void registerMobileNetworkProvider(GSM3MobileNetworkProvider* provider); + + /** Returns network provider object pointer + @return mobile network provider + */ + GSM3MobileNetworkProvider* getMobileNetworkProvider(); + +}; + +extern GSM3MobileNetworkRegistry theMobileNetworkRegistry; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileSMSProvider.cpp b/libraries/GSM3/GSM3MobileSMSProvider.cpp new file mode 100644 index 000000000..b53633083 --- /dev/null +++ b/libraries/GSM3/GSM3MobileSMSProvider.cpp @@ -0,0 +1,3 @@ +#include + +GSM3MobileSMSProvider* theGSM3SMSProvider; diff --git a/libraries/GSM3/GSM3MobileSMSProvider.h b/libraries/GSM3/GSM3MobileSMSProvider.h new file mode 100644 index 000000000..aa7271101 --- /dev/null +++ b/libraries/GSM3/GSM3MobileSMSProvider.h @@ -0,0 +1,91 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILESMSPROVIDER_ +#define _GSM3MOBILESMSPROVIDER_ + +class GSM3MobileSMSProvider +{ + public: + + /** Begin a SMS to send it + @param to Destination + @return error command if it exists + */ + virtual inline int beginSMS(const char* to){return 0;}; + + /** Write a SMS character by character + @param c Character + */ + virtual inline void writeSMS(const char c){}; + + /** End SMS + @return error command if it exists + */ + virtual inline int endSMS(){return 0;}; + + /** Check if SMS available and prepare it to be read + @return number of bytes in a received SMS + */ + virtual inline int availableSMS(){return 0;}; + + /** Read a byte but do not advance the buffer header (circular buffer) + @return character + */ + virtual inline int peekSMS(){return 0;}; + + /** Delete the SMS from Modem memory and proccess answer + */ + virtual inline void flushSMS(){return;}; + + /** Read sender number phone + @param number Buffer for save number phone + @param nlength Buffer length + @return 1 success, >1 error + */ + virtual inline int remoteSMSNumber(char* number, int nlength){return 0;}; + + /** Read one char for SMS buffer (advance circular buffer) + @return character + */ + virtual inline int readSMS(){return 0;}; + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + virtual int ready()=0; +}; + +extern GSM3MobileSMSProvider* theGSM3SMSProvider; + +#endif diff --git a/libraries/GSM3/GSM3MobileServerProvider.cpp b/libraries/GSM3/GSM3MobileServerProvider.cpp new file mode 100644 index 000000000..4739ac7e1 --- /dev/null +++ b/libraries/GSM3/GSM3MobileServerProvider.cpp @@ -0,0 +1,5 @@ + #include + + GSM3MobileServerProvider* theGSM3MobileServerProvider; + + \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileServerProvider.h b/libraries/GSM3/GSM3MobileServerProvider.h new file mode 100644 index 000000000..e4eb9c503 --- /dev/null +++ b/libraries/GSM3/GSM3MobileServerProvider.h @@ -0,0 +1,95 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_MOBILESERVERPROVIDER__ +#define __GSM3_MOBILESERVERPROVIDER__ + + +#include +#include +#include + + +class GSM3MobileServerProvider +{ + /** Get socket status + @param s Socket + @return modem status (true if connected) + */ + virtual bool getSocketAsServerModemStatus(int s)=0; + + public: + + /** minSocketAsServer + @return socket + */ + virtual int minSocketAsServer()=0; + + /** maxSocketAsServer + @return socket + */ + virtual int maxSocketAsServer()=0; + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + virtual int ready()=0; + + /** Constructor */ + GSM3MobileServerProvider(){}; + + /** Connect server to TCP port + @param port TCP port + @return command error if exists + */ + virtual int connectTCPServer(int port)=0; + //virtual int getIP(char* LocalIP, int LocalIPlength)=0; + + /** Get new occupied socket as server + @return return -1 if no new socket has been occupied + */ + virtual int getNewOccupiedSocketAsServer()=0; + + /** Get socket status + @param socket Socket + @return socket status (true if connected) + */ + virtual bool getStatusSocketAsServer(uint8_t socket)=0; + + // virtual int disconnectTCP(bool client1Server0, int idsocket)=0; + +}; + +extern GSM3MobileServerProvider* theGSM3MobileServerProvider; + +#endif diff --git a/libraries/GSM3/GSM3MobileServerService.cpp b/libraries/GSM3/GSM3MobileServerService.cpp new file mode 100644 index 000000000..bf76cfcbb --- /dev/null +++ b/libraries/GSM3/GSM3MobileServerService.cpp @@ -0,0 +1,159 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include +#include + + +#define __TOUTSERVER__ 10000 +#define BUFFERSIZETWEET 100 + +#define GSM3MOBILESERVERSERVICE_SYNCH 0x01 // 1: TRUE, compatible with other clients 0: FALSE + +// While there is only a shield (ShieldV1) we will include it by default +#include +GSM3ShieldV1ServerProvider theShieldV1ServerProvider; + + +GSM3MobileServerService::GSM3MobileServerService(uint8_t port, bool synch) +{ + mySocket=0; + _port=port; + flags = 0; + + // If synchronous + if(synch) + flags |= GSM3MOBILESERVERSERVICE_SYNCH; +} + +// Returns 0 if last command is still executing +// 1 if success +// >1 if error +int GSM3MobileServerService::ready() +{ + return theGSM3MobileServerProvider->ready(); +} + +void GSM3MobileServerService::begin() +{ + if(theGSM3MobileServerProvider==0) + return; + theGSM3MobileServerProvider->connectTCPServer(_port); + + if(flags & GSM3MOBILESERVERSERVICE_SYNCH) + waitForAnswer(); +} + +GSM3MobileClientService GSM3MobileServerService::available(bool synch) +{ + int newSocket; + // In case we are debugging, we'll need to force a look at the buffer + ready(); + + newSocket=theGSM3MobileServerProvider->getNewOccupiedSocketAsServer(); + + // Instatiate new client. If we are synch, the client is synchronous/blocking + GSM3MobileClientService client((uint8_t)(newSocket), (flags & GSM3MOBILESERVERSERVICE_SYNCH)); + + return client; +} + +size_t GSM3MobileServerService::write(uint8_t c) +{ +// Adapt to the new, lean implementation +// theGSM3MobileServerProvider->writeSocket(c); + return 1; +} + +void GSM3MobileServerService::beginWrite() +{ +// Adapt to the new, lean implementation +// theGSM3MobileServerProvider->beginWriteSocket(local1Remote0, mySocket); +} + +size_t GSM3MobileServerService::write(const uint8_t* buf) +{ +// Adapt to the new, lean implementation +// theGSM3MobileServerProvider->writeSocket((const char*)(buf)); + return strlen((const char*)buf); +} + +size_t GSM3MobileServerService::write(const uint8_t* buf, size_t sz) +{ +// Adapt to the new, lean implementation +// theGSM3MobileServerProvider->writeSocket((const char*)(buf)); +} + +void GSM3MobileServerService::endWrite() +{ +// Adapt to the new, lean implementation +// theGSM3MobileServerProvider->endWriteSocket(); +} + +void GSM3MobileServerService::stop() +{ + + // Review, should be the server? + theGSM3MobileClientProvider->disconnectTCP(local1Remote0, mySocket); + if(flags & GSM3MOBILESERVERSERVICE_SYNCH) + waitForAnswer(); + theGSM3MobileClientProvider->releaseSocket(mySocket); + mySocket = -1; +} + + +/*int GSM3MobileServerService::getIP(char* LocalIP, int LocalIPlength) +{ + return theGSM3MobileServerProvider->getIP(LocalIP, LocalIPlength); +}*/ + +int GSM3MobileServerService::waitForAnswer() +{ + unsigned long m; + m=millis(); + int res; + + while(((millis()-m)< __TOUTSERVER__ )&&(ready()==0)) + delay(10); + + res=ready(); + + // If we get something different from a 1, we are having a problem + if(res!=1) + res=0; + + return res; +} + + diff --git a/libraries/GSM3/GSM3MobileServerService.h b/libraries/GSM3/GSM3MobileServerService.h new file mode 100644 index 000000000..12165eed1 --- /dev/null +++ b/libraries/GSM3/GSM3MobileServerService.h @@ -0,0 +1,124 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILESERVERSERVICE_ +#define _GSM3MOBILESERVERSERVICE_ + +#include +#include +#include + +class GSM3MobileServerService : public Server +{ + private: + + uint8_t _port; // Port + uint8_t mySocket; // Actual socket + uint8_t flags; + bool local1Remote0; + + /** Internal utility, used in synchronous calls + @return operation result, 1 if success, 0 otherwise + */ + int waitForAnswer(); + + public: + + /** Constructor + @param port Port + @param synch True if the server acts synchronously + */ + GSM3MobileServerService(uint8_t port, bool synch=true); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(); + + /** Initialize server + */ + void begin(); + + /** Check if there is an incoming client request + @param synch If true, the returned client is synchronous or + blocking. + @return Client if successful, else error + */ + GSM3MobileClientService available(bool synch=true); + + // Just to keep in line with Ethernet. + // Write to every open socket... + //void write(uint8_t); + //void write(const uint8_t *buf, size_t size); + + /** Begin write in socket + */ + void beginWrite(); + + /** Write character in socket + @param c Character + @return size + */ + size_t write(uint8_t c); + + /** Write buffer in socket + @param buf Buffer + @return size + */ + size_t write(const uint8_t *buf); + + /** Write buffer in socket with size + @param buf Buffer + @param sz Buffer size + @return size + */ + size_t write(const uint8_t *buf, size_t sz); + + /** End write in socket + */ + void endWrite(); + + /** Stop server + */ + void stop(); + + // we take this function out as IPAddress is complex to bring to + // version 1. + // inline int connect(IPAddress ip, uint16_t port){return 0;}; + // Returns 2 if there are no resources + //int getIP(char* LocalIP, int LocalIPlength); + +}; + + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3MobileVoiceProvider.cpp b/libraries/GSM3/GSM3MobileVoiceProvider.cpp new file mode 100644 index 000000000..7af4e8fc7 --- /dev/null +++ b/libraries/GSM3/GSM3MobileVoiceProvider.cpp @@ -0,0 +1,4 @@ +#include + + +GSM3MobileVoiceProvider* theGSM3MobileVoiceProvider; diff --git a/libraries/GSM3/GSM3MobileVoiceProvider.h b/libraries/GSM3/GSM3MobileVoiceProvider.h new file mode 100644 index 000000000..2091a1ba7 --- /dev/null +++ b/libraries/GSM3/GSM3MobileVoiceProvider.h @@ -0,0 +1,90 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3MOBILEVOICEPROVIDER_ +#define _GSM3MOBILEVOICEPROVIDER_ + +enum GSM3_voiceCall_st { IDLE_CALL, CALLING, RECEIVINGCALL, TALKING}; + +class GSM3MobileVoiceProvider +{ + public: + + /** Initialize the object relating it to the general infrastructure + @param + @return void + */ + virtual void initialize(){}; + + /** Launch a voice call + @param number Phone number to be called + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + virtual int voiceCall(const char* number)=0; + + /** Answer a voice call + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + virtual int answerCall()=0; + + /** Hang a voice call + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + virtual int hangCall()=0; + + /** Retrieve phone number of caller + @param buffer Buffer for copy phone number + @param bufsize Buffer size + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + virtual int retrieveCallingNumber(char* buffer, int bufsize)=0; + + /** Returns voice call status + @return voice call status + */ + virtual GSM3_voiceCall_st getvoiceCallStatus()=0; + + /** Set voice call status + @param status New status for voice call + */ + virtual void setvoiceCallStatus(GSM3_voiceCall_st status)=0; + + /** Get last command status + @return Returns 0 if last command is still executing, 1 success, >1 error + */ + virtual int ready()=0; +}; + +extern GSM3MobileVoiceProvider* theGSM3MobileVoiceProvider; + +#endif diff --git a/libraries/GSM3/GSM3SMSService.cpp b/libraries/GSM3/GSM3SMSService.cpp new file mode 100644 index 000000000..378dc2cc8 --- /dev/null +++ b/libraries/GSM3/GSM3SMSService.cpp @@ -0,0 +1,126 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include +#include + +// While there is only a shield (ShieldV1) we will include it by default +#include +GSM3ShieldV1SMSProvider theShieldV1SMSProvider; + +#define GSM3SMSSERVICE_SYNCH 0x01 // 1: synchronous 0: asynchronous +#define __TOUT__ 10000 + + +GSM3SMSService::GSM3SMSService(bool synch) +{ + if(synch) + flags |= GSM3SMSSERVICE_SYNCH; +} + +// Returns 0 if last command is still executing +// 1 if success +// >1 if error +int GSM3SMSService::ready() +{ + return theGSM3SMSProvider->ready(); +} + +int GSM3SMSService::beginSMS(const char *number) +{ + return waitForAnswerIfNeeded(theGSM3SMSProvider->beginSMS(number)); +}; + +int GSM3SMSService::endSMS() +{ + return waitForAnswerIfNeeded(theGSM3SMSProvider->endSMS()); +}; + +size_t GSM3SMSService::write(uint8_t c) +{ + theGSM3SMSProvider->writeSMS(c); + return 1; +} + +void GSM3SMSService::flush() +{ + theGSM3SMSProvider->flushSMS(); + waitForAnswerIfNeeded(1); +}; + +int GSM3SMSService::available() +{ + return waitForAnswerIfNeeded(theGSM3SMSProvider->availableSMS()); +}; + +int GSM3SMSService::remoteNumber(char* number, int nlength) +{ + return theGSM3SMSProvider->remoteSMSNumber(number, nlength); + +} + +int GSM3SMSService::read() +{ + return theGSM3SMSProvider->readSMS(); +}; +int GSM3SMSService::peek() +{ + return theGSM3SMSProvider->peekSMS(); +}; + +int GSM3SMSService::waitForAnswerIfNeeded(int returnvalue) +{ + // If synchronous + if(flags & GSM3SMSSERVICE_SYNCH ) + { + unsigned long m; + m=millis(); + // Wait for __TOUT__ + while(((millis()-m)< __TOUT__ )&&(ready()==0)) + delay(100); + // If everything was OK, return 1 + // else (timeout or error codes) return 0; + if(ready()==1) + return 1; + else + return 0; + } + // If not synchronous just kick ahead the coming result + return ready(); +} + + + + + diff --git a/libraries/GSM3/GSM3SMSService.h b/libraries/GSM3/GSM3SMSService.h new file mode 100644 index 000000000..878be114b --- /dev/null +++ b/libraries/GSM3/GSM3SMSService.h @@ -0,0 +1,110 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3SMSSERVICE_ +#define _GSM3SMSSERVICE_ + +#include +#include + +class GSM3SMSService : public Stream +{ + private: + + uint8_t flags; + + /** Makes synchronous the functions, if needed + @param returnvalue Return value + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int waitForAnswerIfNeeded(int returnvalue); + + public: + + /** Constructor + @param synch Determines sync mode + */ + GSM3SMSService(bool synch=true); + + /** Write a character in SMS message + @param c Character + @return size + */ + size_t write(uint8_t c); + + /** Begin a SMS to send it + @param to Destination + @return error command if it exists + */ + int beginSMS(const char* to); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(); + + /** End SMS + @return error command if it exists + */ + int endSMS(); + + /** Check if SMS available and prepare it to be read + @return number of bytes in a received SMS + */ + int available(); + + /** Read sender number phone + @param number Buffer for save number phone + @param nlength Buffer length + @return 1 success, >1 error + */ + int remoteNumber(char* number, int nlength); + + /** Read one char for SMS buffer (advance circular buffer) + @return byte + */ + int read(); + + /** Read a byte but do not advance the buffer header (circular buffer) + @return byte + */ + int peek(); + + /** Delete the SMS from Modem memory and proccess answer + */ + void flush(); + +}; + + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1.cpp b/libraries/GSM3/GSM3ShieldV1.cpp new file mode 100644 index 000000000..d59487406 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1.cpp @@ -0,0 +1,96 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include +#include + +#define __RESETPIN__ 7 +#define __TOUTLOCALCOMS__ 500 +#define __TOUTSHUTDOWN__ 5000 +#define __TOUTMODEMCONFIGURATION__ 5000//equivalent to 30000 because of time in interrupt routine. +#define __TOUTAT__ 1000 +#define __TOUTSMS__ 7000 +#define __TOUTCALL__ 15000 +#define __TOUTGPRS__ 10000 +#define __NCLIENTS_MAX__ 3 + +//Constructor. +GSM3ShieldV1::GSM3ShieldV1(bool db) +{ + theGSM3ShieldV1ModemCore.setCommandCounter(1); + socketsAccepted=0; + theGSM3ShieldV1ModemCore.registerUMProvider(this); + theProvider=this; +} + +//Response management. +void GSM3ShieldV1::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case NONE: + theGSM3ShieldV1ModemCore.gss.cb.deleteToTheEnd(from); + break; + + } +} + +//Function for 2 sec delay inside an interruption. +void GSM3ShieldV1::delayInsideInterrupt2seg() +{ + for (int k=0;k<40;k++) theGSM3ShieldV1ModemCore.gss.tunedDelay(50000); +} + +///////////////////////////////////////////////////////UNSOLICITED RESULT CODE (URC) FUNCTIONS/////////////////////////////////////////////////////////////////// + +//URC recognize. +bool GSM3ShieldV1::recognizeUnsolicitedEvent(byte oldTail) +{ + +int nlength; +char auxLocate [15]; + //POWER DOWN. + prepareAuxLocate(PSTR("POWER DOWN"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + theGSM3ShieldV1ModemCore.gss.cb.flush(); + return true; + } + + + return false; +} + + + diff --git a/libraries/GSM3/GSM3ShieldV1.h b/libraries/GSM3/GSM3ShieldV1.h new file mode 100644 index 000000000..db52f7b0e --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1.h @@ -0,0 +1,137 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_SHIELDV1__ +#define __GSM3_SHIELDV1__ + +#include +#include +#include +#include + + +class GSM3ShieldV1 : public GSM3MobileNetworkProvider, public GSM3ShieldV1BaseProvider +{ + // General code, for modem management + private: + + /** Delay inside an interrupt (2 seconds) + */ + void delayInsideInterrupt2seg(); + + // Code for SMS Service + private: + + + long commandMillis; + bool commandSent; + + const char* pinConfig; //PIN. + char* accessPoint; //APN. + char* userName; //User. + char* passw; //Password. + const char* remoteID; //Server. + + char* dataSocket; //Data socket. + int local_Port; //Local Port. + char* local_IP; //Local IP. + int local_IP_Length; //Local IP length. + + + int socketDataSize; //Size of socket data to be read. + int socketDataSizeWritten; //Number of socket data written in buffer not to overflow the buffer + + int socketsAccepted; //Status for remote clients accepted of closed. + + public: + + /** Constructor **/ + GSM3ShieldV1(bool debug=false); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + /** Parse modem response + @param rsp Returns true if expected response exists + @param string1 Substring expected in response + @param string2 Second substring expected in response + @return true if parsed successful + */ + bool genericParse_rsp2(bool& rsp, char* string1, char* string2); + + /** Recognize URC + @param oldTail + @return true if successful + */ + bool recognizeUnsolicitedEvent(byte oldTail); + + /** Receive answer + @return true if successful + */ + bool answerReceived(); + + /** Receive socket + @param id_socket Socket ID + @return true if successful + */ + bool socketReceived(int id_socket); + + /** Update active ID sockets + @param active Active sockets + @param ID Id for update + */ + void update_activeIDsockets (bool active, int ID); + + /** Assign ID to socket + @param ID Id to assign to socket + @return true if successful + */ + bool assignIDsocket (int& ID); + + /** Close data socket + @return true if successful + */ + bool closedDataSocket(); //Flag closed current data socket. + + //bool writeIncomingCalls(char* bufferForCallerId) If isn't zero, doesn't wait calls +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1AccessProvider.cpp b/libraries/GSM3/GSM3ShieldV1AccessProvider.cpp new file mode 100644 index 000000000..67ae75553 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1AccessProvider.cpp @@ -0,0 +1,296 @@ +#include +#include + +#define __RESETPIN__ 7 +#define __TOUTSHUTDOWN__ 5000 +#define __TOUTMODEMCONFIGURATION__ 5000//equivalent to 30000 because of time in interrupt routine. +#define __TOUTAT__ 1000 + +char _command_AT[] PROGMEM = "AT"; +char _command_CGREG[] PROGMEM = "AT+CGREG?"; + + +GSM3ShieldV1AccessProvider::GSM3ShieldV1AccessProvider(bool debug) +{ + theGSM3ShieldV1ModemCore.setDebug(debug); + +} + +void GSM3ShieldV1AccessProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case MODEMCONFIG: + ModemConfigurationContinue(); + break; + case ALIVETEST: + isModemAliveContinue(); + break; + } +} + +///////////////////////////////////////////////////////CONFIGURATION FUNCTIONS/////////////////////////////////////////////////////////////////// + +// Begin +// Restart or start the modem +// May be synchronous +GSM3_NetworkStatus_t GSM3ShieldV1AccessProvider::begin(char* pin, bool restart, bool synchronous) +{ + pinMode(__RESETPIN__, OUTPUT); + + // If asked for modem restart, restart + if (restart) + HWrestart(); + else + HWstart(); + + theGSM3ShieldV1ModemCore.gss.begin(9600); + // Launch modem configuration commands + ModemConfiguration(pin); + // If synchronous, wait till ModemConfiguration is over + if(synchronous) + { + // if we shorten this delay, the command fails + while(ready()==0) + delay(1000); + } + return getStatus(); +} + +//HWrestart. +int GSM3ShieldV1AccessProvider::HWrestart() +{ + + theGSM3ShieldV1ModemCore.setStatus(IDLE); + digitalWrite(__RESETPIN__, HIGH); + delay(12000); + digitalWrite(__RESETPIN__, LOW); + delay(1000); + return 1; //configandwait(pin); +} + +//HWrestart. +int GSM3ShieldV1AccessProvider::HWstart() +{ + + theGSM3ShieldV1ModemCore.setStatus(IDLE); + digitalWrite(__RESETPIN__, HIGH); + delay(2000); + digitalWrite(__RESETPIN__, LOW); + //delay(1000); + + return 1; //configandwait(pin); +} + +//Initial configuration main function. +int GSM3ShieldV1AccessProvider::ModemConfiguration(char* pin) +{ + theGSM3ShieldV1ModemCore.setPhoneNumber(pin); + theGSM3ShieldV1ModemCore.openCommand(this,MODEMCONFIG); + theGSM3ShieldV1ModemCore.setStatus(CONNECTING); + ModemConfigurationContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Initial configuration continue function. +void GSM3ShieldV1AccessProvider::ModemConfigurationContinue() +{ + bool resp; + + // 1: Send AT + // 2: Wait AT OK and SetPin or CGREG + // 3: Wait Pin OK and CGREG + // 4: Wait CGREG and Flow SW control or CGREG + // 5: Wait IFC OK and SMS Text Mode + // 6: Wait SMS text Mode OK and Calling line identification + // 7: Wait Calling Line Id OK and Echo off + // 8: Wait for OK and COLP command for connecting line identification. + // 9: Wait for OK. + int ct=theGSM3ShieldV1ModemCore.getCommandCounter(); + if(ct==1) + { + // Launch AT + theGSM3ShieldV1ModemCore.setCommandCounter(2); + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_AT); + } + else if(ct==2) + { + // Wait for AT - OK. + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + // OK received + if(theGSM3ShieldV1ModemCore.getPhoneNumber() && (theGSM3ShieldV1ModemCore.getPhoneNumber()[0]!=0)) + { + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CPIN="), false); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + theGSM3ShieldV1ModemCore.genericCommand_rqc(theGSM3ShieldV1ModemCore.getPhoneNumber()); + } + else + { + //DEBUG + //Serial.println("AT+CGREG?"); + theGSM3ShieldV1ModemCore.setCommandCounter(4); + theGSM3ShieldV1ModemCore.takeMilliseconds(); + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_CGREG); + } + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==3) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + theGSM3ShieldV1ModemCore.setCommandCounter(4); + theGSM3ShieldV1ModemCore.takeMilliseconds(); + theGSM3ShieldV1ModemCore.delayInsideInterrupt(2000); + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_CGREG); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==4) + { + char auxLocate1 [12]; + char auxLocate2 [12]; + prepareAuxLocate(PSTR("+CGREG: 0,1"), auxLocate1); + prepareAuxLocate(PSTR("+CGREG: 0,5"), auxLocate2); + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp, auxLocate1, auxLocate2)) + { + if(resp) + { + theGSM3ShieldV1ModemCore.setCommandCounter(5); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+IFC=1,1")); + } + else + { + // If not, launch command again + if(theGSM3ShieldV1ModemCore.takeMilliseconds() > __TOUTMODEMCONFIGURATION__) + { + theGSM3ShieldV1ModemCore.closeCommand(3); + } + else + { + theGSM3ShieldV1ModemCore.delayInsideInterrupt(2000); + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_CGREG); + } + } + } + } + else if(ct==5) + { + // 5: Wait IFC OK + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + //Delay for SW flow control being active. + theGSM3ShieldV1ModemCore.delayInsideInterrupt(2000); + // 9: SMS Text Mode + theGSM3ShieldV1ModemCore.setCommandCounter(6); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CMGF=1")); + } + } + else if(ct==6) + { + // 6: Wait SMS text Mode OK + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + //Calling line identification + theGSM3ShieldV1ModemCore.setCommandCounter(7); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CLIP=1")); + } + } + else if(ct==7) + { + // 7: Wait Calling Line Id OK + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Echo off + theGSM3ShieldV1ModemCore.setCommandCounter(8); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("ATE0")); + } + } + else if(ct==8) + { + // 8: Wait ATEO OK, send COLP + // In Arduino Mega, attention, take away the COLP step + // It looks as we can only have 8 steps + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + theGSM3ShieldV1ModemCore.setCommandCounter(9); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+COLP=1")); + } + } + else if(ct==9) + { + // 9: Wait ATCOLP OK + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if (resp) + { + theGSM3ShieldV1ModemCore.setStatus(GSM_READY); + theGSM3ShieldV1ModemCore.closeCommand(1); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } +} + +//Alive Test main function. +int GSM3ShieldV1AccessProvider::isAccessAlive() +{ + theGSM3ShieldV1ModemCore.setCommandError(0); + theGSM3ShieldV1ModemCore.setCommandCounter(1); + theGSM3ShieldV1ModemCore.openCommand(this,ALIVETEST); + isModemAliveContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Alive Test continue function. +void GSM3ShieldV1AccessProvider::isModemAliveContinue() +{ +bool rsp; +switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_AT); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(rsp)) + { + if (rsp) theGSM3ShieldV1ModemCore.closeCommand(1); + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Shutdown. +bool GSM3ShieldV1AccessProvider::shutdown() +{ + unsigned long m; + bool resp; + char auxLocate [18]; + + // It makes no sense to have an asynchronous shutdown + pinMode(__RESETPIN__, OUTPUT); + digitalWrite(__RESETPIN__, HIGH); + delay(1500); + digitalWrite(__RESETPIN__, LOW); + theGSM3ShieldV1ModemCore.setStatus(IDLE); + theGSM3ShieldV1ModemCore.gss.close(); + + m=millis(); + prepareAuxLocate(PSTR("POWER DOWN"), auxLocate); + while((millis()-m) < __TOUTSHUTDOWN__) + { + delay(1); + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp, auxLocate)) + return resp; + } + return false; +} + diff --git a/libraries/GSM3/GSM3ShieldV1AccessProvider.h b/libraries/GSM3/GSM3ShieldV1AccessProvider.h new file mode 100644 index 000000000..1ddcc8cc3 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1AccessProvider.h @@ -0,0 +1,116 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3SHIELDV1ACCESSPROVIDER_ +#define _GSM3SHIELDV1ACCESSPROVIDER_ + +#include +#include +#include + +class GSM3ShieldV1AccessProvider : public GSM3MobileAccessProvider, public GSM3ShieldV1BaseProvider +{ + private: + + /** Initialize main modem configuration + @param pin PIN code + @return command error if exists + */ + int ModemConfiguration(char* pin); + + /** Continue to modem configuration function + */ + void ModemConfigurationContinue(); + + /** Continue to check if modem alive function + */ + void isModemAliveContinue(); + + + public: + + /** Constructor + @param debug Determines debug mode + */ + + GSM3ShieldV1AccessProvider(bool debug=false); + + /** Start the GSM/GPRS modem, attaching to the GSM network + @param pin SIM PIN number (4 digits in a string, example: "1234"). If + NULL the SIM has no configured PIN. + @param restart Restart the modem. Default is TRUE. The modem receives + a signal through the Ctrl/D7 pin. If it is shut down, it will + start-up. If it is running, it will restart. Takes up to 10 + seconds + @param synchronous If TRUE the call only returns after the Start is complete + or fails. If FALSE the call will return inmediately. You have + to call repeatedly ready() until you get a result. Default is TRUE. + @return If synchronous, GSM3_NetworkStatus_t. If asynchronous, returns 0. + */ + GSM3_NetworkStatus_t begin(char* pin=0,bool restart=true, bool synchronous=true); + + /** Check network access status + @return 1 if Alive, 0 if down + */ + int isAccessAlive(); + + /** Shutdown the modem (power off really) + @return true if successful + */ + bool shutdown(); + + /** Returns 0 if last command is still executing + @return 1 if success, >1 if error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + /** Returns modem status + @return modem network status + */ + inline GSM3_NetworkStatus_t getStatus(){return theGSM3ShieldV1ModemCore.getStatus();}; + + void manageResponse(byte from, byte to); + + /** Restart the modem (will shut down if running) + @return 1 if success, >1 if error + */ + int HWrestart(); + + /** Start the modem (will not shut down if running) + @return 1 if success, >1 if error + */ + int HWstart(); + +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1BandManagement.cpp b/libraries/GSM3/GSM3ShieldV1BandManagement.cpp new file mode 100644 index 000000000..94dec9aea --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1BandManagement.cpp @@ -0,0 +1,67 @@ +#include + +GSM3ShieldV1BandManagement::GSM3ShieldV1BandManagement(bool trace): modem(trace) +{ + quectelStrings[UNDEFINED]=""; + quectelStrings[EGSM_MODE]="\"EGSM_MODE\""; + quectelStrings[DCS_MODE]="\"DCS_MODE\""; + quectelStrings[PCS_MODE]="\"PCS_MODE\""; + quectelStrings[EGSM_DCS_MODE]="\"EGSM_DCS_MODE\""; + quectelStrings[GSM850_PCS_MODE]="\"GSM850_PCS_MODE\""; + quectelStrings[GSM850_EGSM_DCS_PCS_MODE]="\"GSM850_EGSM_DCS_PCS_MODE\""; +} + +GSM3_NetworkStatus_t GSM3ShieldV1BandManagement::begin() +{ + // check modem response + modem.begin(); + + // reset hardware + modem.restartModem(); + + return IDLE; +} + +String GSM3ShieldV1BandManagement::getBand() +{ + String modemResponse=modem.writeModemCommand("AT+QBAND?", 2000); + + for(GSM3GSMBand i=GSM850_EGSM_DCS_PCS_MODE;i>UNDEFINED;i=(GSM3GSMBand)((int)i-1)) + { + if(modemResponse.indexOf(quectelStrings[i])>=0) + return quectelStrings[i]; + } + + Serial.print("Unrecognized modem answer:"); + Serial.println(modemResponse); + + return ""; +} + +bool GSM3ShieldV1BandManagement::setBand(String band) +{ + String command; + String modemResponse; + bool found=false; + + command="AT+QBAND="; + for(GSM3GSMBand i=EGSM_MODE;((i<=GSM850_EGSM_DCS_PCS_MODE)&&(!found));i=(GSM3GSMBand)((int)i+1)) + { + String aux=quectelStrings[i]; + if(aux.indexOf(band)>=0) + { + command+=aux; + found=true; + } + } + + if(!found) + return false; + // Quad-band takes an awful lot of time + modemResponse=modem.writeModemCommand(command, 15000); + + if(modemResponse.indexOf("QBAND")>=0) + return true; + else + return false; +} \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1BandManagement.h b/libraries/GSM3/GSM3ShieldV1BandManagement.h new file mode 100644 index 000000000..919d4ad23 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1BandManagement.h @@ -0,0 +1,96 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3SHIELDV1BANDMANAGEMENT__ +#define __GSM3SHIELDV1BANDMANAGEMENT__ + +// This class executes band management functions for the ShieldV1 +#include + +#define NUMBEROFBANDS 7 +#define GSM_MODE_UNDEFINED "UNDEFINED" +#define GSM_MODE_EGSM "EGSM_MODE" +#define GSM_MODE_DCS "DCS_MODE" +#define GSM_MODE_PCS "PCS_MODE" +#define GSM_MODE_EGSM_DCS "EGSM_DCS_MODE" +#define GSM_MODE_GSM850_PCS "GSM850_PCS_MODE" +#define GSM_MODE_GSM850_EGSM_DCS_PCS "GSM850_EGSM_DCS_PCS_MODE" + +typedef enum GSM3GSMBand {UNDEFINED, EGSM_MODE, DCS_MODE, PCS_MODE, EGSM_DCS_MODE, GSM850_PCS_MODE, GSM850_EGSM_DCS_PCS_MODE}; + +// +// These are the bands and scopes: +// +// E-GSM(900) +// DCS(1800) +// PCS(1900) +// E-GSM(900)+DCS(1800) ex: Europe +// GSM(850)+PCS(1900) Ex: USA, South Am. +// GSM(850)+E-GSM(900)+DCS(1800)+PCS(1900) + +class GSM3ShieldV1BandManagement +{ + private: + + GSM3ShieldV1DirectModemProvider modem; // Direct access to modem + + char* quectelStrings[NUMBEROFBANDS];// = {"\"EGSM_MODE\"", "\"DCS_MODE\"", "\"PCS_MODE\"", + //"\"EGSM_DCS_MODE\"", "\"GSM850_PCS_MODE\"", + //"\"GSM850_EGSM_DCS_PCS_MODE\""}; + + + public: + + /** Constructor + @param trace If true, dumps all AT dialogue to Serial + */ + GSM3ShieldV1BandManagement(bool trace=false); + + /** Forces modem hardware restart, so we begin from scratch + @return always returns IDLE status + */ + GSM3_NetworkStatus_t begin(); + + /** Get current modem work band + @return current modem work band + */ + String getBand(); + + /** Changes the modem operating band + @param band Desired new band + @return true if success, false otherwise + */ + bool setBand(String band); + +}; +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1BaseProvider.cpp b/libraries/GSM3/GSM3ShieldV1BaseProvider.cpp new file mode 100644 index 000000000..d63967be3 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1BaseProvider.cpp @@ -0,0 +1,27 @@ +#include +#include +#include + +// Returns 0 if last command is still executing +// 1 if success +// >1 if error +int GSM3ShieldV1BaseProvider::ready() +{ + theGSM3ShieldV1ModemCore.manageReceivedData(); + + return theGSM3ShieldV1ModemCore.getCommandError(); +}; + +void GSM3ShieldV1BaseProvider::prepareAuxLocate(PROGMEM prog_char str[], char auxLocate[]) +{ + int i=0; + char c; + + do + { + c=pgm_read_byte_near(str + i); + auxLocate[i]=c; + i++; + } while (c!=0); +} + diff --git a/libraries/GSM3/GSM3ShieldV1BaseProvider.h b/libraries/GSM3/GSM3ShieldV1BaseProvider.h new file mode 100644 index 000000000..802d46cbd --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1BaseProvider.h @@ -0,0 +1,73 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3SHIELDV1BASEPROVIDER_ +#define _GSM3SHIELDV1BASEPROVIDER_ + +#include + +enum GSM3_commandType_e { XON, NONE, MODEMCONFIG, ALIVETEST, BEGINSMS, ENDSMS, AVAILABLESMS, FLUSHSMS, + VOICECALL, ANSWERCALL, HANGCALL, RETRIEVECALLINGNUMBER, + ATTACHGPRS, DETACHGPRS, CONNECTTCPCLIENT, DISCONNECTTCP, BEGINWRITESOCKET, ENDWRITESOCKET, + AVAILABLESOCKET, FLUSHSOCKET, CONNECTSERVER, GETIP, GETCONNECTSTATUS, GETLOCATION, GETICCID}; + +class GSM3ShieldV1BaseProvider +{ + public: + + /** Get last command status + @return Returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(); + + /** This function locates strings from PROGMEM in the buffer + @param str PROGMEN + @param auxLocate Buffer where to locate strings + */ + void prepareAuxLocate(PROGMEM prog_char str[], char auxLocate[]); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + virtual void manageResponse(byte from, byte to); + + /** Recognize URC + @param from + @return true if successful (default: false) + */ + virtual bool recognizeUnsolicitedEvent(byte from){return false;}; + +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1CellManagement.cpp b/libraries/GSM3/GSM3ShieldV1CellManagement.cpp new file mode 100644 index 000000000..2af91abff --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1CellManagement.cpp @@ -0,0 +1,168 @@ +#include + +GSM3ShieldV1CellManagement::GSM3ShieldV1CellManagement() +{ +} + +bool GSM3ShieldV1CellManagement::parseQCCID_available(bool& rsp) +{ + char c; + bool iccidFound = false; + int i = 0; + + while(((c = theGSM3ShieldV1ModemCore.theBuffer().read()) != 0) & (i < 19)) + { + if((c < 58) & (c > 47)) + iccidFound = true; + + if(iccidFound) + { + bufferICCID[i] = c; + i++; + } + } + bufferICCID[i]=0; + + return true; +} + +bool GSM3ShieldV1CellManagement::parseQENG_available(bool& rsp) +{ + char c; + char location[50] = ""; + int i = 0; + + if (!(theGSM3ShieldV1ModemCore.theBuffer().chopUntil("+QENG: ", true))) + rsp = false; + else + rsp = true; + + if (!(theGSM3ShieldV1ModemCore.theBuffer().chopUntil("+QENG:", true))) + rsp = false; + else + rsp = true; + + while(((c = theGSM3ShieldV1ModemCore.theBuffer().read()) != 0) & (i < 50)) + { + location[i] = c; + i++; + } + location[i]=0; + + char* res_tok = strtok(location, ","); + res_tok=strtok(NULL, ","); + strcpy(countryCode, res_tok); + res_tok=strtok(NULL, ","); + strcpy(networkCode, res_tok); + res_tok=strtok(NULL, ","); + strcpy(locationArea, res_tok); + res_tok=strtok(NULL, ","); + strcpy(cellId, res_tok); + + return true; +} + +int GSM3ShieldV1CellManagement::getLocation(char *country, char *network, char *area, char *cell) +{ + if((theGSM3ShieldV1ModemCore.getStatus() != GSM_READY) && (theGSM3ShieldV1ModemCore.getStatus() != GPRS_READY)) + return 2; + + countryCode=country; + networkCode=network; + locationArea=area; + cellId=cell; + + theGSM3ShieldV1ModemCore.openCommand(this,GETLOCATION); + getLocationContinue(); + + unsigned long timeOut = millis(); + while(((millis() - timeOut) < 5000) & (ready() == 0)); + + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +void GSM3ShieldV1CellManagement::getLocationContinue() +{ + bool resp; + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.gss.tunedDelay(3000); + delay(3000); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QENG=1"), false); + theGSM3ShieldV1ModemCore.print("\r"); + break; + case 2: + if (theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + theGSM3ShieldV1ModemCore.gss.tunedDelay(3000); + delay(3000); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QENG?"), false); + theGSM3ShieldV1ModemCore.print("\r"); + } + else theGSM3ShieldV1ModemCore.closeCommand(1); + break; + case 3: + if (resp) + { + parseQENG_available(resp); + theGSM3ShieldV1ModemCore.closeCommand(3); + } + else theGSM3ShieldV1ModemCore.closeCommand(2); + break; + } +} + +int GSM3ShieldV1CellManagement::getICCID(char *iccid) +{ + if((theGSM3ShieldV1ModemCore.getStatus() != GSM_READY) && (theGSM3ShieldV1ModemCore.getStatus() != GPRS_READY)) + return 2; + + bufferICCID=iccid; + theGSM3ShieldV1ModemCore.openCommand(this,GETICCID); + getICCIDContinue(); + + unsigned long timeOut = millis(); + while(((millis() - timeOut) < 5000) & (ready() == 0)); + + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +void GSM3ShieldV1CellManagement::getICCIDContinue() +{ + bool resp; + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.setCommandCounter(2); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QCCID"), false); + theGSM3ShieldV1ModemCore.print("\r"); + break; + case 2: + if (theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + parseQCCID_available(resp); + theGSM3ShieldV1ModemCore.closeCommand(2); + } + else theGSM3ShieldV1ModemCore.closeCommand(1); + break; + } +} + +void GSM3ShieldV1CellManagement::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case NONE: + theGSM3ShieldV1ModemCore.gss.cb.deleteToTheEnd(from); + break; + case GETLOCATION: + getLocationContinue(); + break; + case GETICCID: + getICCIDContinue(); + break; + } +} \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1CellManagement.h b/libraries/GSM3/GSM3ShieldV1CellManagement.h new file mode 100644 index 000000000..78307da3b --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1CellManagement.h @@ -0,0 +1,92 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_SHIELDV1CELLMANAGEMENT__ +#define __GSM3_SHIELDV1CELLMANAGEMENT__ + +#include +#include +#include + +class GSM3ShieldV1CellManagement : public GSM3MobileCellManagement, public GSM3ShieldV1BaseProvider +{ + public: + + /** Constructor + */ + GSM3ShieldV1CellManagement(); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + /** getLocation + @return current cell location + */ + int getLocation(char *country, char *network, char *area, char *cell); + + /** getICCID + */ + int getICCID(char *iccid); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + private: + + char *countryCode; + char *networkCode; + char *locationArea; + char *cellId; + + char *bufferICCID; + + /** Continue to getLocation function + */ + void getLocationContinue(); + + /** Continue to getICCID function + */ + void getICCIDContinue(); + + bool parseQENG_available(bool& rsp); + + bool parseQCCID_available(bool& rsp); + +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1ClientProvider.cpp b/libraries/GSM3/GSM3ShieldV1ClientProvider.cpp new file mode 100644 index 000000000..92d3e8577 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ClientProvider.cpp @@ -0,0 +1,294 @@ +#include +#include + +GSM3ShieldV1ClientProvider::GSM3ShieldV1ClientProvider() +{ + theGSM3MobileClientProvider=this; +}; + +//Response management. +void GSM3ShieldV1ClientProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case NONE: + theGSM3ShieldV1ModemCore.gss.cb.deleteToTheEnd(from); + break; + case CONNECTTCPCLIENT: + connectTCPClientContinue(); + break; + case FLUSHSOCKET: + flushSocketContinue(); + break; + } +} + +//Connect TCP main function. +int GSM3ShieldV1ClientProvider::connectTCPClient(const char* server, int port, int id_socket) +{ + theGSM3ShieldV1ModemCore.setPort(port); + idSocket = id_socket; + + theGSM3ShieldV1ModemCore.setPhoneNumber((char*)server); + theGSM3ShieldV1ModemCore.openCommand(this,CONNECTTCPCLIENT); + theGSM3ShieldV1ModemCore.registerUMProvider(this); + connectTCPClientContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +int GSM3ShieldV1ClientProvider::connectTCPClient(IPAddress add, int port, int id_socket) +{ + remoteIP=add; + theGSM3ShieldV1ModemCore.setPhoneNumber(0); + return connectTCPClient(0, port, id_socket); +} + +//Connect TCP continue function. +void GSM3ShieldV1ClientProvider::connectTCPClientContinue() +{ + bool resp; + // 0: Dot or DNS notation activation + // 1: Disable SW flow control + // 2: Waiting for IFC OK + // 3: Start-up TCP connection "AT+QIOPEN" + // 4: Wait for connection OK + // 5: Wait for CONNECT + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIDNSIP="), false); + if ((theGSM3ShieldV1ModemCore.getPhoneNumber()!=0)&& + ((*(theGSM3ShieldV1ModemCore.getPhoneNumber())<'0')||((*(theGSM3ShieldV1ModemCore.getPhoneNumber())>'9')))) + { + theGSM3ShieldV1ModemCore.print('1'); + theGSM3ShieldV1ModemCore.print('\r'); + } + else + { + theGSM3ShieldV1ModemCore.print('0'); + theGSM3ShieldV1ModemCore.print('\r'); + } + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + //Response received + if(resp) + { + // AT+QIOPEN + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIOPEN="),false); + theGSM3ShieldV1ModemCore.print("\"TCP\",\""); + if(theGSM3ShieldV1ModemCore.getPhoneNumber()!=0) + { + theGSM3ShieldV1ModemCore.print(theGSM3ShieldV1ModemCore.getPhoneNumber()); + } + else + { + remoteIP.printTo(theGSM3ShieldV1ModemCore); + } + theGSM3ShieldV1ModemCore.print('"'); + theGSM3ShieldV1ModemCore.print(','); + theGSM3ShieldV1ModemCore.print(theGSM3ShieldV1ModemCore.getPort()); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + + case 3: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Response received + if(resp) + { + // OK Received + // Great. Go for the next step + theGSM3ShieldV1ModemCore.setCommandCounter(4); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + case 4: + char auxLocate [12]; + prepareAuxLocate(PSTR("CONNECT\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp,auxLocate)) + { + // Response received + if(resp) + { + // Received CONNECT OK + // Great. We're done + theGSM3ShieldV1ModemCore.setStatus(TRANSPARENT_CONNECTED); + theGSM3ShieldV1ModemCore.theBuffer().chopUntil(auxLocate, true); + theGSM3ShieldV1ModemCore.closeCommand(1); + } + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + + } +} + +//Disconnect TCP main function. +int GSM3ShieldV1ClientProvider::disconnectTCP(bool client1Server0, int id_socket) +{ + // id Socket does not really mean anything, in this case we have + // only one socket running + theGSM3ShieldV1ModemCore.openCommand(this,DISCONNECTTCP); + + // If we are not closed, launch the command +//[ZZ] if(theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED) +// { + delay(1000); + theGSM3ShieldV1ModemCore.print("+++"); + delay(1000); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QICLOSE")); + theGSM3ShieldV1ModemCore.setStatus(GPRS_READY); +// } + // Looks like it runs everytime, so we simply flush to death and go on + do + { + // Empty the local buffer, and tell the modem to XON + // If meanwhile we receive a DISCONNECT we should detect it as URC. + theGSM3ShieldV1ModemCore.theBuffer().flush(); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + // Give some time for the buffer to refill + delay(100); + theGSM3ShieldV1ModemCore.closeCommand(1); + }while(theGSM3ShieldV1ModemCore.theBuffer().storedBytes()>0); + + theGSM3ShieldV1ModemCore.unRegisterUMProvider(this); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + + +//Write socket first chain main function. +void GSM3ShieldV1ClientProvider::beginWriteSocket(bool client1Server0, int id_socket) +{ +} + + +//Write socket next chain function. +void GSM3ShieldV1ClientProvider::writeSocket(const char* buf) +{ + if(theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED) + theGSM3ShieldV1ModemCore.print(buf); +} + +//Write socket character function. +void GSM3ShieldV1ClientProvider::writeSocket(uint8_t c) +{ + if(theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED) + theGSM3ShieldV1ModemCore.print((char)c); +} + +//Write socket last chain main function. +void GSM3ShieldV1ClientProvider::endWriteSocket() +{ +} + + +//Available socket main function. +int GSM3ShieldV1ClientProvider::availableSocket(bool client1Server0, int id_socket) +{ + + if(!(theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED)) + theGSM3ShieldV1ModemCore.closeCommand(4); + + if(theGSM3ShieldV1ModemCore.theBuffer().storedBytes()) + theGSM3ShieldV1ModemCore.closeCommand(1); + else + theGSM3ShieldV1ModemCore.closeCommand(4); + + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +int GSM3ShieldV1ClientProvider::readSocket() +{ + char charSocket; + + if(theGSM3ShieldV1ModemCore.theBuffer().availableBytes()==0) + { + return 0; + } + + charSocket = theGSM3ShieldV1ModemCore.theBuffer().read(); + + if(theGSM3ShieldV1ModemCore.theBuffer().availableBytes()==100) + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + + return charSocket; + +} + +//Read socket main function. +int GSM3ShieldV1ClientProvider::peekSocket() +{ + return theGSM3ShieldV1ModemCore.theBuffer().peek(0); +} + + +//Flush SMS main function. +void GSM3ShieldV1ClientProvider::flushSocket() +{ + theGSM3ShieldV1ModemCore.openCommand(this,FLUSHSOCKET); + + flushSocketContinue(); +} + +//Send SMS continue function. +void GSM3ShieldV1ClientProvider::flushSocketContinue() +{ + // If we have incomed data + if(theGSM3ShieldV1ModemCore.theBuffer().storedBytes()>0) + { + // Empty the local buffer, and tell the modem to XON + // If meanwhile we receive a DISCONNECT we should detect it as URC. + theGSM3ShieldV1ModemCore.theBuffer().flush(); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + } + else + { + //We're done + theGSM3ShieldV1ModemCore.closeCommand(1); + } +} + +// URC recognize. +// Yes, we recognize "closes" in client mode +bool GSM3ShieldV1ClientProvider::recognizeUnsolicitedEvent(byte oldTail) +{ + char auxLocate [12]; + prepareAuxLocate(PSTR("CLOSED"), auxLocate); + + if((theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED) & theGSM3ShieldV1ModemCore.theBuffer().chopUntil(auxLocate, false, false)) + { + theGSM3ShieldV1ModemCore.setStatus(GPRS_READY); + theGSM3ShieldV1ModemCore.unRegisterUMProvider(this); + return true; + } + + return false; +} + +int GSM3ShieldV1ClientProvider::getSocket(int socket) +{ + return 0; +} + +void GSM3ShieldV1ClientProvider::releaseSocket(int socket) +{ + +} + +bool GSM3ShieldV1ClientProvider::getStatusSocketClient(uint8_t socket) +{ + return (theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED); + +}; + + + diff --git a/libraries/GSM3/GSM3ShieldV1ClientProvider.h b/libraries/GSM3/GSM3ShieldV1ClientProvider.h new file mode 100644 index 000000000..fa2f8b58a --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ClientProvider.h @@ -0,0 +1,181 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_SHIELDV1CLIENTPROVIDER__ +#define __GSM3_SHIELDV1CLIENTPROVIDER__ + +#include +#include + +class GSM3ShieldV1ClientProvider : public GSM3MobileClientProvider, public GSM3ShieldV1BaseProvider +{ + private: + + int remotePort; //Current operation remote port. + IPAddress remoteIP; // Remote IP address + int idSocket; // Remote ID socket. + + + /** Continue to connect TCP client function + */ + void connectTCPClientContinue(); + + /** Continue to available socket function + */ + void availableSocketContinue(); + + /** Continue to flush socket function + */ + void flushSocketContinue(); + + public: + + /** Constructor */ + GSM3ShieldV1ClientProvider(); + + /** minSocket + @return 0 + */ + int minSocket(){return 0;}; + + /** maxSocket + @return 0 + */ + int maxSocket(){return 0;}; + + /** Connect to a remote TCP server + @param server String with IP or server name + @param port Remote port number + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + int connectTCPClient(const char* server, int port, int id_socket); + + /** Connect to a remote TCP server + @param add Remote IP address + @param port Remote port number + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + int connectTCPClient(IPAddress add, int port, int id_socket); + + /** Begin writing through a socket + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + void beginWriteSocket(bool client1Server0, int id_socket); + + /** Write through a socket. MUST go after beginWriteSocket() + @param buf characters to be written (final 0 will not be written) + */ + void writeSocket(const char* buf); + + /** Write through a socket. MUST go after beginWriteSocket() + @param c character to be written + */ + void writeSocket(uint8_t c); + + /** Finish current writing + */ + void endWriteSocket(); + + /** Check if there are data to be read in socket. + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if there are data available, 4 if no data, otherwise error + */ + int availableSocket(bool client, int id_socket); // With "available" and "readSocket" ask the modem for 1500 bytes. + + /** Read data (get a character) available in socket + @return character + */ + int readSocket(); //If Read() gets to the end of the QIRD response, execute again QIRD SYNCHRONOUSLY + + /** Flush socket + */ + void flushSocket(); + + /** Get a character but will not advance the buffer head + @return character + */ + int peekSocket(); + + /** Close a socket + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Socket + @return 0 if command running, 1 if success, otherwise error + */ + int disconnectTCP(bool client1Server0, int id_socket); + + /** Recognize unsolicited event + @param oldTail + @return true if successful + */ + bool recognizeUnsolicitedEvent(byte from); + + /** Manages modem response + @param from Initial byte position + @param to Final byte position + */ + void manageResponse(byte from, byte to); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + // Client socket management, just to be compatible + // with the Multi option + + /** Get socket + @param socket Socket + @return socket + */ + int getSocket(int socket=-1); + + /** Release socket + @param socket Socket + */ + void releaseSocket(int socket); + + /** Get socket client status + @param socket Socket + @return 1 if connected, 0 otherwise + */ + bool getStatusSocketClient(uint8_t socket); + +}; + + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1DataNetworkProvider.cpp b/libraries/GSM3/GSM3ShieldV1DataNetworkProvider.cpp new file mode 100644 index 000000000..aaffdba6e --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1DataNetworkProvider.cpp @@ -0,0 +1,363 @@ +#include +#include + +char _command_CGATT[] PROGMEM = "AT+CGATT="; +char _command_SEPARATOR[] PROGMEM = "\",\""; + +//Attach GPRS main function. +GSM3_NetworkStatus_t GSM3ShieldV1DataNetworkProvider::attachGPRS(char* apn, char* user_name, char* password, bool synchronous) +{ + user = user_name; + passwd = password; + // A sad use of byte reuse + theGSM3ShieldV1ModemCore.setPhoneNumber(apn); + + theGSM3ShieldV1ModemCore.openCommand(this,ATTACHGPRS); + theGSM3ShieldV1ModemCore.setStatus(CONNECTING); + + attachGPRSContinue(); + + // If synchronous, wait till attach is over, or not. + if(synchronous) + { + // if we shorten this delay, the command fails + while(ready()==0) + delay(100); + } + + return theGSM3ShieldV1ModemCore.getStatus(); +} + +//Atthach GPRS continue function. +void GSM3ShieldV1DataNetworkProvider::attachGPRSContinue() +{ + bool resp; + // 1: Attach to GPRS service "AT+CGATT=1" + // 2: Wait attach OK and Set the context 0 as FGCNT "AT+QIFGCNT=0" + // 3: Wait context OK and Set bearer type as GPRS, APN, user name and pasword "AT+QICSGP=1..." + // 4: Wait bearer OK and Enable the function of MUXIP "AT+QIMUX=1" + // 5: Wait for disable MUXIP OK and Set the session mode as non transparent "AT+QIMODE=0" + // 6: Wait for session mode OK and Enable notification when data received "AT+QINDI=1" + // 8: Wait domain name OK and Register the TCP/IP stack "AT+QIREGAPP" + // 9: Wait for Register OK and Activate FGCNT "AT+QIACT" + // 10: Wait for activate OK + + int ct=theGSM3ShieldV1ModemCore.getCommandCounter(); + if(ct==1) + { + //AT+CGATT + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_CGATT,false); + theGSM3ShieldV1ModemCore.print(1); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + } + else if(ct==2) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + //AT+QIFGCNT + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIFGCNT=0")); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==3) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + // Great. Go for the next step + //DEBUG + //Serial.println("AT+QICSGP."); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QICSGP=1,\""),false); + theGSM3ShieldV1ModemCore.print(theGSM3ShieldV1ModemCore.getPhoneNumber()); + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_SEPARATOR,false); + theGSM3ShieldV1ModemCore.print(user); + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_SEPARATOR,false); + theGSM3ShieldV1ModemCore.print(passwd); + theGSM3ShieldV1ModemCore.print("\"\r"); + theGSM3ShieldV1ModemCore.setCommandCounter(4); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==4) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + // AT+QIMUX=1 for multisocket + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIMUX=0")); + theGSM3ShieldV1ModemCore.setCommandCounter(5); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==5) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + //AT+QIMODE=0 for multisocket + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIMODE=1")); + theGSM3ShieldV1ModemCore.setCommandCounter(6); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==6) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + // AT+QINDI=1 + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QINDI=1")); + theGSM3ShieldV1ModemCore.setCommandCounter(8); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==8) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + // AT+QIREGAPP + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIREGAPP")); + theGSM3ShieldV1ModemCore.setCommandCounter(9); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==9) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if(resp) + { + // AT+QIACT + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIACT")); + theGSM3ShieldV1ModemCore.setCommandCounter(10); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + else if(ct==10) + { + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if (resp) + { + theGSM3ShieldV1ModemCore.setStatus(GPRS_READY); + theGSM3ShieldV1ModemCore.closeCommand(1); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + } +} + +//Detach GPRS main function. +GSM3_NetworkStatus_t GSM3ShieldV1DataNetworkProvider::detachGPRS(bool synchronous) +{ + theGSM3ShieldV1ModemCore.openCommand(this,DETACHGPRS); + theGSM3ShieldV1ModemCore.setStatus(CONNECTING); + detachGPRSContinue(); + + if(synchronous) + { + while(ready()==0) + delay(1); + } + + return theGSM3ShieldV1ModemCore.getStatus(); +} + +void GSM3ShieldV1DataNetworkProvider::detachGPRSContinue() +{ + bool resp; + // 1: Detach to GPRS service "AT+CGATT=0" + // 2: Wait dettach +PDP DEACT + // 3: Wait for OK + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //AT+CGATT=0 + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_CGATT,false); + theGSM3ShieldV1ModemCore.print(0); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + char auxLocate[12]; + prepareAuxLocate(PSTR("+PDP DEACT"), auxLocate); + if(theGSM3ShieldV1ModemCore.theBuffer().locate(auxLocate)) + { + if(resp) + { + // Received +PDP DEACT; + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + case 3: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // OK received + if (resp) + { + theGSM3ShieldV1ModemCore.setStatus(GSM_READY); + theGSM3ShieldV1ModemCore.closeCommand(1); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//QILOCIP parse. +bool GSM3ShieldV1DataNetworkProvider::parseQILOCIP_rsp(char* LocalIP, int LocalIPlength, bool& rsp) +{ + if (!(theGSM3ShieldV1ModemCore.theBuffer().extractSubstring("\r\n","\r\n", LocalIP, LocalIPlength))) + rsp = false; + else + rsp = true; + return true; +} + +//Get IP main function. +int GSM3ShieldV1DataNetworkProvider::getIP(char* LocalIP, int LocalIPlength) +{ + theGSM3ShieldV1ModemCore.setPhoneNumber(LocalIP); + theGSM3ShieldV1ModemCore.setPort(LocalIPlength); + theGSM3ShieldV1ModemCore.openCommand(this,GETIP); + getIPContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +void GSM3ShieldV1DataNetworkProvider::getIPContinue() +{ + + bool resp; + // 1: Read Local IP "AT+QILOCIP" + // 2: Waiting for IP. + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //AT+QILOCIP + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QILOCIP")); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(parseQILOCIP_rsp(theGSM3ShieldV1ModemCore.getPhoneNumber(), theGSM3ShieldV1ModemCore.getPort(), resp)) + { + if (resp) + theGSM3ShieldV1ModemCore.closeCommand(1); + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + theGSM3ShieldV1ModemCore.theBuffer().flush(); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + break; + } +} + +//Get IP with IPAddress object +IPAddress GSM3ShieldV1DataNetworkProvider::getIPAddress() { + char ip_temp[15]=""; + getIP(ip_temp, 15); + unsigned long m=millis(); + + while((millis()-m)<10*1000 && (!ready())){ + // wait for a response from the modem: + delay(100); + } + IPAddress ip; + inet_aton(ip_temp, ip); + return ip; +} + +int GSM3ShieldV1DataNetworkProvider::inet_aton(const char* aIPAddrString, IPAddress& aResult) +{ + // See if we've been given a valid IP address + const char* p =aIPAddrString; + while (*p && + ( (*p == '.') || (*p >= '0') || (*p <= '9') )) + { + p++; + } + + if (*p == '\0') + { + // It's looking promising, we haven't found any invalid characters + p = aIPAddrString; + int segment =0; + int segmentValue =0; + while (*p && (segment < 4)) + { + if (*p == '.') + { + // We've reached the end of a segment + if (segmentValue > 255) + { + // You can't have IP address segments that don't fit in a byte + return 0; + } + else + { + aResult[segment] = (byte)segmentValue; + segment++; + segmentValue = 0; + } + } + else + { + // Next digit + segmentValue = (segmentValue*10)+(*p - '0'); + } + p++; + } + // We've reached the end of address, but there'll still be the last + // segment to deal with + if ((segmentValue > 255) || (segment > 3)) + { + // You can't have IP address segments that don't fit in a byte, + // or more than four segments + return 0; + } + else + { + aResult[segment] = (byte)segmentValue; + return 1; + } + } + else + { + return 0; + } +} + +//Response management. +void GSM3ShieldV1DataNetworkProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case ATTACHGPRS: + attachGPRSContinue(); + break; + case DETACHGPRS: + detachGPRSContinue(); + break; + case GETIP: + getIPContinue(); + break; + } +} diff --git a/libraries/GSM3/GSM3ShieldV1DataNetworkProvider.h b/libraries/GSM3/GSM3ShieldV1DataNetworkProvider.h new file mode 100644 index 000000000..012a0ca54 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1DataNetworkProvider.h @@ -0,0 +1,140 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3SHIELDV1DATANETWORKPROVIDER_ +#define _GSM3SHIELDV1DATANETWORKPROVIDER_ + +#include +#include +#include +#include + +class GSM3ShieldV1DataNetworkProvider : public GSM3MobileDataNetworkProvider, public GSM3ShieldV1BaseProvider +{ + private: + + char* user; // Username for GPRS + char* passwd; // Password for GPRS + + /** Continue to attach GPRS function + */ + void attachGPRSContinue(); + + /** Continue to detach GPRS function + */ + void detachGPRSContinue(); + + /** Parse QILOCIP response + @param LocalIP Buffer for save local IP address + @param LocalIPlength Buffer size + @param rsp Returns true if expected response exists + @return true if command executed correctly + */ + bool parseQILOCIP_rsp(char* LocalIP, int LocalIPlength, bool& rsp); + + /** Continue to get IP function + */ + void getIPContinue(); + + /** Implementation of inet_aton standard function + @param aIPAddrString IP address in characters buffer + @param aResult IP address in IPAddress format + @return 1 if the address is successfully converted, or 0 if the conversion failed + */ + int inet_aton(const char* aIPAddrString, IPAddress& aResult); + + public: + + /** Attach to GPRS/GSM network + @param networkId APN GPRS + @param user Username + @param pass Password + @return connection status + */ + GSM3_NetworkStatus_t networkAttach(char* networkId, char* user, char* pass) + { + return attachGPRS(networkId, user, pass); + }; + + /** Detach GPRS/GSM network + @return connection status + */ + GSM3_NetworkStatus_t networkDetach(){ return detachGPRS();}; + + /** Attach to GPRS service + @param apn APN GPRS + @param user_name Username + @param password Password + @param synchronous Sync mode + @return connection status + */ + GSM3_NetworkStatus_t attachGPRS(char* apn, char* user_name, char* password, bool synchronous=true); + + /** Detach GPRS service + @param synchronous Sync mode + @return connection status + */ + GSM3_NetworkStatus_t detachGPRS(bool synchronous=true); + + /** Returns 0 if last command is still executing + @return 1 if success, >1 if error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + /** Get network status (connection) + @return status + */ + inline GSM3_NetworkStatus_t getStatus(){return theGSM3ShieldV1ModemCore.getStatus();}; + + /** Get actual assigned IP address + @param LocalIP Buffer for copy IP address + @param LocalIPlength Buffer length + @return command error if exists + */ + int getIP(char* LocalIP, int LocalIPlength); + + /** Get actual assigned IP address in IPAddress format + @return IP address in IPAddress format + */ + IPAddress getIPAddress(); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1DirectModemProvider.cpp b/libraries/GSM3/GSM3ShieldV1DirectModemProvider.cpp new file mode 100644 index 000000000..47aa52b07 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1DirectModemProvider.cpp @@ -0,0 +1,143 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include +#include +#include + +#define __RESETPIN__ 7 + +//Constructor +GSM3ShieldV1DirectModemProvider::GSM3ShieldV1DirectModemProvider(bool t) +{ + trace=t; +}; + +void GSM3ShieldV1DirectModemProvider::begin() +{ + theGSM3ShieldV1ModemCore.gss.begin(9600); +} + +void GSM3ShieldV1DirectModemProvider::restartModem() +{ + pinMode(__RESETPIN__, OUTPUT); + digitalWrite(__RESETPIN__, HIGH); + delay(12000); + digitalWrite(__RESETPIN__, LOW); + delay(1000); + +} + +//To enable the debug process +void GSM3ShieldV1DirectModemProvider::connect() +{ + theGSM3ShieldV1ModemCore.registerActiveProvider(this); +} + +//To disable the debug process +void GSM3ShieldV1DirectModemProvider::disconnect() +{ + theGSM3ShieldV1ModemCore.registerActiveProvider(0); +} + +//Write to the modem by means of SoftSerial +size_t GSM3ShieldV1DirectModemProvider::write(uint8_t c) +{ + theGSM3ShieldV1ModemCore.write(c); +} + +//Detect if data to be read +int/*bool*/ GSM3ShieldV1DirectModemProvider::available() +{ + if (theGSM3ShieldV1ModemCore.gss.cb.peek(1)) return 1; + else return 0; +} + +//Read data +int/*char*/ GSM3ShieldV1DirectModemProvider::read() +{ + int dataRead; + dataRead = theGSM3ShieldV1ModemCore.gss.cb.read(); + //In case last char in xof mode. + if (!(theGSM3ShieldV1ModemCore.gss.cb.peek(0))) { + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + delay(100); + } + return dataRead; +} + +//Peek data +int/*char*/ GSM3ShieldV1DirectModemProvider::peek() +{ + return theGSM3ShieldV1ModemCore.gss.cb.peek(0); +} + +//Flush data +void GSM3ShieldV1DirectModemProvider::flush() +{ + return theGSM3ShieldV1ModemCore.gss.cb.flush(); +} + +String GSM3ShieldV1DirectModemProvider::writeModemCommand(String ATcommand, int responseDelay) +{ + + if(trace) + Serial.println(ATcommand); + + // Flush other texts + flush(); + + //Enter debug mode. + connect(); + //Send the AT command. + println(ATcommand); + + delay(responseDelay); + + //Get response data from modem. + String result = ""; + if(trace) + theGSM3ShieldV1ModemCore.gss.cb.debugBuffer(); + + while (available()) + { + char c = read(); + result += c; + } + if(trace) + Serial.println(result); + //Leave the debug mode. + disconnect(); + return result; +} \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1DirectModemProvider.h b/libraries/GSM3/GSM3ShieldV1DirectModemProvider.h new file mode 100644 index 000000000..2d20412b4 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1DirectModemProvider.h @@ -0,0 +1,118 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ + +#ifndef __GSM3DIRECTMODEMPROVIDER__ +#define __GSM3DIRECTMODEMPROVIDER__ + +#include +#include +#include +#include +#include + +class GSM3ShieldV1DirectModemProvider : public GSM3ShieldV1BaseProvider, public Stream +{ + private: + + bool trace; + + public: + + /** Constructor + @param trace if true, dumps all AT dialogue to Serial + */ + GSM3ShieldV1DirectModemProvider(bool trace=false); + + /** + */ + void begin(); + + /** + */ + void restartModem(); + + /** Enable the debug process. + */ + void connect(); + + /** Disable the debug process. + */ + void disconnect(); + + /** Debug write to modem by means of SoftSerial. + @param c Character + @return size + */ + size_t write(uint8_t c); + + /** Check for incoming bytes in buffer + @return + */ + int available(); + + /** Read from circular buffer + @return character + */ + int read(); + + /** Read from circular buffer, but do not delete it + @return character + */ + int peek(); + + /** Empty circular buffer + */ + void flush(); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to){}; + + /** Recognize unsolicited event + @param from + @return true if successful + */ + bool recognizeUnsolicitedEvent(byte from){return false;}; + + /** Send AT command to modem + @param command AT command + @param delay Time to wait for response + @return response from modem + */ + String writeModemCommand(String command, int delay); +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1ModemCore.cpp b/libraries/GSM3/GSM3ShieldV1ModemCore.cpp new file mode 100644 index 000000000..c90ff4dd4 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ModemCore.cpp @@ -0,0 +1,198 @@ +#include +#include + +GSM3ShieldV1ModemCore theGSM3ShieldV1ModemCore; + +char* __ok__="OK"; + +GSM3ShieldV1ModemCore::GSM3ShieldV1ModemCore() : gss() +{ + gss.registerMgr(this); + _dataInBufferFrom=0; + _dataInBufferTo=0; + commandError=1; + commandCounter=0; + ongoingCommand=NONE; + takeMilliseconds(); + + for(int i=0;irecognizeUnsolicitedEvent(from); + } + if((!recognized)&&(activeProvider)) + activeProvider->manageResponse(from, to); +} + + +void GSM3ShieldV1ModemCore::openCommand(GSM3ShieldV1BaseProvider* provider, GSM3_commandType_e c) +{ + activeProvider=provider; + commandError=0; + commandCounter=1; + ongoingCommand=c; + _dataInBufferFrom=0; + _dataInBufferTo=0; + +}; + +size_t GSM3ShieldV1ModemCore::writePGM(PROGMEM prog_char str[], bool CR) +{ + int i=0; + char c; + + do + { + c=pgm_read_byte_near(str + i); + if(c!=0) + write(c); + i++; + } while (c!=0); + if(CR) + print("\r"); + + return 1; +} + +size_t GSM3ShieldV1ModemCore::write(uint8_t c) +{ + if(_debug) + GSM3CircularBuffer::printCharDebug(c); + return gss.write(c); +} + +unsigned long GSM3ShieldV1ModemCore::takeMilliseconds() +{ + unsigned long now=millis(); + unsigned long delta; + delta=now-milliseconds; + milliseconds=now; + return delta; +} + +void GSM3ShieldV1ModemCore::delayInsideInterrupt(unsigned long milliseconds) +{ + for (unsigned long k=0;k +#include +#include +#include + +#define UMPROVIDERS 3 + +class GSM3ShieldV1ModemCore : public GSM3SoftSerialMgr, public Print +{ + private: + + // Phone number, used when calling, sending SMS and reading calling numbers + // Also PIN in modem configuration + // Also APN + // Also remote server + char* phoneNumber; + + // Working port. Port used in the ongoing command, while opening a server + // Also for IP address length + int port; + + // 0 = ongoing + // 1 = OK + // 2 = Error. Incorrect state + // 3 = Unexpected modem message + // 4 = OK but not available data. + uint8_t commandError; + + // Counts the steps by the command + uint8_t commandCounter; + + // Presently ongoing command + GSM3_commandType_e ongoingCommand; + + // Enable/disable debug + bool _debug; + byte _dataInBufferFrom; + byte _dataInBufferTo; + + // This is the modem (known) status + GSM3_NetworkStatus_t _status; + + GSM3ShieldV1BaseProvider* UMProvider[UMPROVIDERS]; + GSM3ShieldV1BaseProvider* activeProvider; + + // Private function for anage message + void manageMsgNow(byte from, byte to); + + unsigned long milliseconds; + + public: + + /** Constructor */ + GSM3ShieldV1ModemCore(); + + GSM3SoftSerial gss; // Direct access to modem + + /** Get phone number + @return phone number + */ + char *getPhoneNumber(){return phoneNumber;}; + + /** Establish a new phone number + @param n Phone number + */ + void setPhoneNumber(char *n){phoneNumber=n;}; + + /** Get port used + @return port + */ + int getPort(){return port;}; + + /** Establish a new port for use + @param p Port + */ + void setPort(int p){port=p;}; + + /** Get command error + @return command error + */ + uint8_t getCommandError(){return commandError;}; + + /** Establish a command error + @param n Command error + */ + void setCommandError(uint8_t n){commandError=n;}; + + /** Get command counter + @return command counter + */ + uint8_t getCommandCounter(){return commandCounter;}; + + /** Set command counter + @param c Initial value + */ + void setCommandCounter(uint8_t c){commandCounter=c;}; + + /** Get ongoing command + @return command + */ + GSM3_commandType_e getOngoingCommand(){return ongoingCommand;}; + + /** Set ongoing command + @param c New ongoing command + */ + void setOngoingCommand(GSM3_commandType_e c){ongoingCommand=c;}; + + /** Open command + @param activeProvider Active provider + @param c Command for open + */ + void openCommand(GSM3ShieldV1BaseProvider* activeProvider, GSM3_commandType_e c); + + /** Close command + @param code Close code + */ + void closeCommand(int code); + + // These functions allow writing to the SoftwareSerial + // If debug is set, dump to the console + + /** Write a character in serial + @param c Character + @return size + */ + size_t write(uint8_t c); + + /** Write PGM + @param str Buffer for write + @param CR Carriadge return adding automatically + @return size + */ + virtual size_t writePGM(PROGMEM prog_char str[], bool CR=true); + + /** Establish debug mode + @param db Boolean that indicates debug on or off + */ + void setDebug(bool db){_debug=db;}; + + /** Generic response parser + @param rsp Returns true if expected response exists + @param string Substring expected in response + @param string2 Second substring expected in response + @return true if parsed correctly + */ + bool genericParse_rsp(bool& rsp, char* string=0, char* string2=0); + + /** Generates a generic AT command request from PROGMEM prog_char buffer + @param str Buffer with AT command + @param addCR Carriadge return adding automatically + */ + void genericCommand_rq(PROGMEM prog_char str[], bool addCR=true); + + /** Generates a generic AT command request from a simple char buffer + @param str Buffer with AT command + @param addCR Carriadge return adding automatically + */ + void genericCommand_rqc(const char* str, bool addCR=true); + + /** Generates a generic AT command request from characters buffer + @param str Buffer with AT command + @param addCR Carriadge return adding automatically + */ + void genericCommand_rq(const char* str, bool addCR=true); + + /** Returns the circular buffer + @return circular buffer + */ + inline GSM3CircularBuffer& theBuffer(){return gss.cb;}; + + /** Establish a new network status + @param status Network status + */ + inline void setStatus(GSM3_NetworkStatus_t status) { _status = status; }; + + /** Returns actual network status + @return network status + */ + inline GSM3_NetworkStatus_t getStatus() { return _status; }; + + /** Register provider as willing to receive unsolicited messages + @param provider Pointer to provider able to receive unsolicited messages + */ + void registerUMProvider(GSM3ShieldV1BaseProvider* provider); + + /** unegister provider as willing to receive unsolicited messages + @param provider Pointer to provider able to receive unsolicited messages + */ + void unRegisterUMProvider(GSM3ShieldV1BaseProvider* provider); + + + /** Register a provider as "dialoguing" talking in facto with the modem + @param provider Pointer to provider receiving responses + */ + void registerActiveProvider(GSM3ShieldV1BaseProvider* provider){activeProvider=provider;}; + + /** Needed to manage the SoftSerial. Receives the call when received data + If _debugging, no code is called + @param from Starting byte to read + @param to Last byte to read + */ + void manageMsg(byte from, byte to); + + /** If _debugging, this call is assumed to be made out of interrupts + Prints incoming info and calls manageMsgNow + */ + void manageReceivedData(); + + /** Chronometer. Measure milliseconds from last call + @return milliseconds from las time function was called + */ + unsigned long takeMilliseconds(); + + /** Delay for interrupts + @param milliseconds Delay time in milliseconds + */ + void delayInsideInterrupt(unsigned long milliseconds); + +}; + +extern GSM3ShieldV1ModemCore theGSM3ShieldV1ModemCore; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1ModemVerification.cpp b/libraries/GSM3/GSM3ShieldV1ModemVerification.cpp new file mode 100644 index 000000000..e5d190fb0 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ModemVerification.cpp @@ -0,0 +1,79 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ + +#include + +// constructor +GSM3ShieldV1ModemVerification::GSM3ShieldV1ModemVerification() +{ +}; + +// reset the modem for direct access +int GSM3ShieldV1ModemVerification::begin() +{ + int result=0; + String modemResponse; + + // check modem response + modemAccess.begin(); + + // reset hardware + modemAccess.restartModem(); + + modemResponse=modemAccess.writeModemCommand("AT", 1000); + if(modemResponse.indexOf("OK")>=0) + result=1; + modemResponse=modemAccess.writeModemCommand("ATE0", 1000); + return result; +} + +// get IMEI +String GSM3ShieldV1ModemVerification::getIMEI() +{ + String number; + // AT command for obtain IMEI + String modemResponse = modemAccess.writeModemCommand("AT+GSN", 2000); + // Parse and check response + char res_to_compare[modemResponse.length()]; + modemResponse.toCharArray(res_to_compare, modemResponse.length()); + if(strstr(res_to_compare,"OK") == NULL) + { + return NULL; + } + else + { + number = modemResponse.substring(1, 17); + return number; + } +} diff --git a/libraries/GSM3/GSM3ShieldV1ModemVerification.h b/libraries/GSM3/GSM3ShieldV1ModemVerification.h new file mode 100644 index 000000000..e03980e03 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ModemVerification.h @@ -0,0 +1,64 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3SHIELDV1MODEMVERIFICATION_ +#define _GSM3SHIELDV1MODEMVERIFICATION_ + +#include +#include + +class GSM3ShieldV1ModemVerification +{ + + private: + + GSM3ShieldV1DirectModemProvider modemAccess; + GSM3ShieldV1AccessProvider gsm; // Access provider to GSM/GPRS network + + public: + + /** Constructor */ + GSM3ShieldV1ModemVerification(); + + /** Check modem response and restart it + */ + int begin(); + + /** Obtain modem IMEI (command AT) + @return modem IMEI number + */ + String getIMEI(); + +}; + +#endif; \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1MultiClientProvider.cpp b/libraries/GSM3/GSM3ShieldV1MultiClientProvider.cpp new file mode 100644 index 000000000..797424f03 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1MultiClientProvider.cpp @@ -0,0 +1,583 @@ +#include +#include + +char _command_MultiQISRVC[] PROGMEM = "AT+QISRVC="; + +#define __TOUTFLUSH__ 10000 + +GSM3ShieldV1MultiClientProvider::GSM3ShieldV1MultiClientProvider() +{ + theGSM3MobileClientProvider=this; + theGSM3ShieldV1ModemCore.registerUMProvider(this); +}; + +//Response management. +void GSM3ShieldV1MultiClientProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case XON: + if (flagReadingSocket) + { +// flagReadingSocket = 0; + fullBufferSocket = (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()<3); + } + else theGSM3ShieldV1ModemCore.setOngoingCommand(NONE); + break; + case NONE: + theGSM3ShieldV1ModemCore.gss.cb.deleteToTheEnd(from); + break; + case CONNECTTCPCLIENT: + connectTCPClientContinue(); + break; + case DISCONNECTTCP: + disconnectTCPContinue(); + break; + case BEGINWRITESOCKET: + beginWriteSocketContinue(); + break; + case ENDWRITESOCKET: + endWriteSocketContinue(); + break; + case AVAILABLESOCKET: + availableSocketContinue(); + break; + case FLUSHSOCKET: + fullBufferSocket = (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()<3); + flushSocketContinue(); + break; + } +} + +//Connect TCP main function. +int GSM3ShieldV1MultiClientProvider::connectTCPClient(const char* server, int port, int id_socket) +{ + theGSM3ShieldV1ModemCore.setPort(port); + idSocket = id_socket; + + theGSM3ShieldV1ModemCore.setPhoneNumber((char*)server); + theGSM3ShieldV1ModemCore.openCommand(this,CONNECTTCPCLIENT); + connectTCPClientContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +int GSM3ShieldV1MultiClientProvider::connectTCPClient(IPAddress add, int port, int id_socket) +{ + remoteIP=add; + theGSM3ShieldV1ModemCore.setPhoneNumber(0); + return connectTCPClient(0, port, id_socket); +} + +//Connect TCP continue function. +void GSM3ShieldV1MultiClientProvider::connectTCPClientContinue() +{ + bool resp; + // 0: Dot or DNS notation activation + // 1: Disable SW flow control + // 2: Waiting for IFC OK + // 3: Start-up TCP connection "AT+QIOPEN" + // 4: Wait for connection OK + // 5: Wait for CONNECT + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIDNSIP="), false); + if ((theGSM3ShieldV1ModemCore.getPhoneNumber()!=0)&& + ((*(theGSM3ShieldV1ModemCore.getPhoneNumber())<'0')||((*(theGSM3ShieldV1ModemCore.getPhoneNumber())>'9')))) + { + theGSM3ShieldV1ModemCore.print('1'); + theGSM3ShieldV1ModemCore.print('\r'); + } + else + { + theGSM3ShieldV1ModemCore.print('0'); + theGSM3ShieldV1ModemCore.print('\r'); + } + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + //Response received + if(resp) + { + // AT+QIOPEN + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIOPEN="),false); + theGSM3ShieldV1ModemCore.print(idSocket); + theGSM3ShieldV1ModemCore.print(",\"TCP\",\""); + if(theGSM3ShieldV1ModemCore.getPhoneNumber()!=0) + { + theGSM3ShieldV1ModemCore.print(theGSM3ShieldV1ModemCore.getPhoneNumber()); + } + else + { + remoteIP.printTo(theGSM3ShieldV1ModemCore); + } + theGSM3ShieldV1ModemCore.print('"'); + theGSM3ShieldV1ModemCore.print(','); + theGSM3ShieldV1ModemCore.print(theGSM3ShieldV1ModemCore.getPort()); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + + case 3: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Response received + if(resp) + { + // OK Received + // Great. Go for the next step + theGSM3ShieldV1ModemCore.setCommandCounter(4); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + case 4: + char auxLocate [12]; + prepareAuxLocate(PSTR("CONNECT OK"), auxLocate); + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp,auxLocate)) + { + // Response received + if(resp) + { + // Received CONNECT OK + // Great. We're done + theGSM3ShieldV1ModemCore.closeCommand(1); + } + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + + } +} + +//Disconnect TCP main function. +int GSM3ShieldV1MultiClientProvider::disconnectTCP(bool client1Server0, int id_socket) +{ + idSocket = id_socket; + + // First of all, we will flush the socket synchronously + unsigned long m; + m=millis(); + flushSocket(); + while(((millis()-m)< __TOUTFLUSH__ )&&(ready()==0)) + delay(10); + + // Could not flush the communications... strange + if(ready()==0) + { + theGSM3ShieldV1ModemCore.setCommandError(2); + return theGSM3ShieldV1ModemCore.getCommandError(); + } + + // Set up the command + client1_server0 = client1Server0; + flagReadingSocket=0; + theGSM3ShieldV1ModemCore.openCommand(this,DISCONNECTTCP); + disconnectTCPContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Disconnect TCP continue function +void GSM3ShieldV1MultiClientProvider::disconnectTCPContinue() +{ + bool resp; + // 1: Send AT+QISRVC + // 2: "AT+QICLOSE" + // 3: Wait for OK + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_MultiQISRVC, false); + if (client1_server0) theGSM3ShieldV1ModemCore.print('1'); + else theGSM3ShieldV1ModemCore.print('2'); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + // Parse response to QISRVC + theGSM3ShieldV1ModemCore.genericParse_rsp(resp); + if(resp) + { + // Send QICLOSE command + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QICLOSE="),false); + theGSM3ShieldV1ModemCore.print(idSocket); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else + theGSM3ShieldV1ModemCore.closeCommand(3); + break; + case 3: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + theGSM3ShieldV1ModemCore.setCommandCounter(0); + if (resp) + theGSM3ShieldV1ModemCore.closeCommand(1); + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Write socket first chain main function. +void GSM3ShieldV1MultiClientProvider::beginWriteSocket(bool client1Server0, int id_socket) +{ + idSocket = id_socket; + client1_server0 = client1Server0; + theGSM3ShieldV1ModemCore.openCommand(this,BEGINWRITESOCKET); + beginWriteSocketContinue(); +} + +//Write socket first chain continue function. +void GSM3ShieldV1MultiClientProvider::beginWriteSocketContinue() +{ + bool resp; + // 1: Send AT+QISRVC + // 2: Send AT+QISEND + // 3: wait for > and Write text + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + // AT+QISRVC + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_MultiQISRVC, false); + if (client1_server0) + theGSM3ShieldV1ModemCore.print('1'); + else + theGSM3ShieldV1ModemCore.print('2'); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Response received + if(resp) + { + // AT+QISEND + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QISEND="), false); + theGSM3ShieldV1ModemCore.print(idSocket); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else + { + theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + break; + case 3: + char aux[2]; + aux[0]='>'; + aux[1]=0; + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp, aux)) + { + if(resp) + { + // Received ">" + theGSM3ShieldV1ModemCore.closeCommand(1); + } + else + { + theGSM3ShieldV1ModemCore.closeCommand(3); + } + } + break; + } +} + +//Write socket next chain function. +void GSM3ShieldV1MultiClientProvider::writeSocket(const char* buf) +{ + theGSM3ShieldV1ModemCore.print(buf); +} + +//Write socket character function. +void GSM3ShieldV1MultiClientProvider::writeSocket(char c) +{ + theGSM3ShieldV1ModemCore.print(c); +} + +//Write socket last chain main function. +void GSM3ShieldV1MultiClientProvider::endWriteSocket() +{ + theGSM3ShieldV1ModemCore.openCommand(this,ENDWRITESOCKET); + endWriteSocketContinue(); +} + +//Write socket last chain continue function. +void GSM3ShieldV1MultiClientProvider::endWriteSocketContinue() +{ + bool resp; + // 1: Write text (ctrl-Z) + // 2: Wait for OK + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.write(26); // Ctrl-Z + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // OK received + if (resp) theGSM3ShieldV1ModemCore.closeCommand(1); + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Available socket main function. +int GSM3ShieldV1MultiClientProvider::availableSocket(bool client1Server0, int id_socket) +{ + if(flagReadingSocket==1) + { + theGSM3ShieldV1ModemCore.setCommandError(1); + return 1; + } + client1_server0 = client1Server0; + idSocket = id_socket; + theGSM3ShieldV1ModemCore.openCommand(this,AVAILABLESOCKET); + availableSocketContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Available socket continue function. +void GSM3ShieldV1MultiClientProvider::availableSocketContinue() +{ + bool resp; + // 1: AT+QIRD + // 2: Wait for OK and Next necessary AT+QIRD + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QIRD=0,"),false); + if (client1_server0) + theGSM3ShieldV1ModemCore.print('1'); + else + theGSM3ShieldV1ModemCore.print('2'); + theGSM3ShieldV1ModemCore.print(','); + theGSM3ShieldV1ModemCore.print(idSocket); + theGSM3ShieldV1ModemCore.print(",1500"); + // theGSM3ShieldV1ModemCore.print(",120"); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(parseQIRD_head(resp)) + { + if (!resp) + { + theGSM3ShieldV1ModemCore.closeCommand(4); + } + else + { + flagReadingSocket=1; + theGSM3ShieldV1ModemCore.closeCommand(1); + } + } + else + { + theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Read Socket Parse head. +bool GSM3ShieldV1MultiClientProvider::parseQIRD_head(bool& rsp) +{ + char _qird [8]; + prepareAuxLocate(PSTR("+QIRD:"), _qird); + fullBufferSocket = (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()<3); + if(theGSM3ShieldV1ModemCore.theBuffer().locate(_qird)) + { + theGSM3ShieldV1ModemCore.theBuffer().chopUntil(_qird, true); + // Saving more memory, reuse _qird + _qird[0]='\n'; + _qird[1]=0; + theGSM3ShieldV1ModemCore.theBuffer().chopUntil(_qird, true); + rsp = true; + return true; + } + else if(theGSM3ShieldV1ModemCore.theBuffer().locate("OK")) + { + rsp = false; + return true; + } + else + { + rsp = false; + return false; + } +} +/* +//Read socket main function. +int GSM3ShieldV1MultiClientProvider::readSocket() +{ + char charSocket; + charSocket = theGSM3ShieldV1ModemCore.theBuffer().read(); + //Case buffer not full + if (!fullBufferSocket) + { + //The last part of the buffer after data is CRLFOKCRLF + if (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()==125) + { + //Start again availableSocket function. + flagReadingSocket=0; + theGSM3ShieldV1ModemCore.openCommand(this,AVAILABLESOCKET); + availableSocketContinue(); + } + } + else if (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()==127) + { + // The buffer is full, no more action is possible until we have read() + theGSM3ShieldV1ModemCore.theBuffer().flush(); + flagReadingSocket = 1; + theGSM3ShieldV1ModemCore.openCommand(this,XON); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + //A small delay to assure data received after xon. + delay(10); + } + //To distinguish the case no more available data in socket. + if (ready()==1) + return charSocket; + else + return 0; +} +*/ +int GSM3ShieldV1MultiClientProvider::readSocket() +{ + char charSocket; + + if(theGSM3ShieldV1ModemCore.theBuffer().availableBytes()==0) + { + Serial.println();Serial.println("*"); + return 0; + } + + charSocket = theGSM3ShieldV1ModemCore.theBuffer().read(); + //Case buffer not full + if (!fullBufferSocket) + { + //The last part of the buffer after data is CRLFOKCRLF + if (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()==125) + { + //Start again availableSocket function. + flagReadingSocket=0; + theGSM3ShieldV1ModemCore.openCommand(this,AVAILABLESOCKET); + availableSocketContinue(); + } + } + else if (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()>=100) + { + // The buffer was full, we have to let the data flow again + // theGSM3ShieldV1ModemCore.theBuffer().flush(); + flagReadingSocket = 1; + theGSM3ShieldV1ModemCore.openCommand(this,XON); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + //A small delay to assure data received after xon. + delay(100); + if(theGSM3ShieldV1ModemCore.theBuffer().availableBytes() >=6) + fullBufferSocket=false; + } + + return charSocket; + +} + +//Read socket main function. +int GSM3ShieldV1MultiClientProvider::peekSocket() +{ + return theGSM3ShieldV1ModemCore.theBuffer().peek(0); +} + + +//Flush SMS main function. +void GSM3ShieldV1MultiClientProvider::flushSocket() +{ + flagReadingSocket=0; + theGSM3ShieldV1ModemCore.openCommand(this,FLUSHSOCKET); + flushSocketContinue(); +} + +//Send SMS continue function. +void GSM3ShieldV1MultiClientProvider::flushSocketContinue() +{ + bool resp; + // 1: Deleting SMS + // 2: wait for OK + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //DEBUG + //Serial.println("Flushing Socket."); + theGSM3ShieldV1ModemCore.theBuffer().flush(); + if (fullBufferSocket) + { + //Serial.println("Buffer flushed."); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + } + else + { + //Serial.println("Socket flushed completely."); + theGSM3ShieldV1ModemCore.closeCommand(1); + } + break; + } +} + +//URC recognize. +// Momentarily, we will not recognize "closes" in client mode +bool GSM3ShieldV1MultiClientProvider::recognizeUnsolicitedEvent(byte oldTail) +{ + return false; +} + +int GSM3ShieldV1MultiClientProvider::getSocket(int socket) +{ + if(socket==-1) + { + int i; + for(i=minSocket(); i<=maxSocket(); i++) + { + if (!(sockets&(0x0001<8) + return 0; + if(sockets&(0x0001< +#include + +class GSM3ShieldV1MultiClientProvider : public GSM3MobileClientProvider, public GSM3ShieldV1BaseProvider +{ + private: + + int remotePort; // Current operation remote port + int idSocket; // Remote ID socket + IPAddress remoteIP; // Remote IP address + + uint16_t sockets; + + /** Continue to connect TCP client function + */ + void connectTCPClientContinue(); + + /** Continue to disconnect TCP client function + */ + void disconnectTCPContinue(); + + /** Continue to begin socket for write function + */ + void beginWriteSocketContinue(); + + /** Continue to end write socket function + */ + void endWriteSocketContinue(); + + /** Continue to available socket function + */ + void availableSocketContinue(); + + /** Continue to flush socket function + */ + void flushSocketContinue(); + + // GATHER! + bool flagReadingSocket; //In case socket data being read, update fullBufferSocket in the next buffer. + bool fullBufferSocket; //To detect if the socket data being read needs another buffer. + bool client1_server0; //1 Client, 0 Server. + + /** Parse QIRD response + @param rsp Returns true if expected response exists + @return true if command executed correctly + */ + bool parseQIRD_head(bool& rsp); + + public: + + /** Constructor */ + GSM3ShieldV1MultiClientProvider(); + + /** Minimum socket + @return 0 + */ + int minSocket(){return 0;}; + + /** Maximum socket + @return 5 + */ + int maxSocket(){return 5;}; + + /** Connect to a remote TCP server + @param server String with IP or server name + @param port Remote port number + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + int connectTCPClient(const char* server, int port, int id_socket); + + /** Connect to a remote TCP server + @param add Remote IP address + @param port Remote port number + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + int connectTCPClient(IPAddress add, int port, int id_socket); + + /** Begin writing through a socket + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + void beginWriteSocket(bool client1Server0, int id_socket); + + /** Write through a socket. MUST go after beginWriteSocket() + @param buf characters to be written (final 0 will not be written) + */ + void writeSocket(const char* buf); + + /** Write through a socket. MUST go after beginWriteSocket() + @param c character to be written + */ + void writeSocket(char c); + + /** Finish current writing + */ + void endWriteSocket(); + + /** Check if there are data to be read in socket. + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if there are data available, 4 if no data, otherwise error + */ + int availableSocket(bool client, int id_socket); // With "available" and "readSocket" ask the modem for 1500 bytes. + + /** Read a character from socket + @return socket + */ + int readSocket(); //If Read() gets to the end of the QIRD response, execute again QIRD SYNCHRONOUSLY + + /** Flush socket + */ + void flushSocket(); + + /** Get a character but will not advance the buffer head + @return character + */ + int peekSocket(); + + /** Close a socket + @param client1Server0 1 if modem acts as client, 0 if acts as server + @param id_socket Local socket number + @return 0 if command running, 1 if success, otherwise error + */ + int disconnectTCP(bool client1Server0, int id_socket); + + /** Recognize unsolicited event + @param from + @return true if successful + */ + bool recognizeUnsolicitedEvent(byte from); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + /** Get client socket + @param socket + @return socket + */ + int getSocket(int socket=-1); + + /** Release socket + @param socket Socket for release + */ + void releaseSocket(int socket); + + /** Get socket client status + @param socket Socket + @return socket client status + */ + bool getStatusSocketClient(uint8_t socket); + +}; + + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1MultiServerProvider.cpp b/libraries/GSM3/GSM3ShieldV1MultiServerProvider.cpp new file mode 100644 index 000000000..6a915f29d --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1MultiServerProvider.cpp @@ -0,0 +1,357 @@ +#include +#include +#include + +#define __NCLIENTS_MAX__ 3 + +char _command_QILOCIP[] PROGMEM = "AT+QILOCIP"; + +GSM3ShieldV1MultiServerProvider::GSM3ShieldV1MultiServerProvider() +{ + theGSM3MobileServerProvider=this; + socketsAsServer=0; + socketsAccepted=0; + theGSM3ShieldV1ModemCore.registerUMProvider(this); +}; + +//Response management. +void GSM3ShieldV1MultiServerProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case NONE: + theGSM3ShieldV1ModemCore.gss.cb.deleteToTheEnd(from); + break; + case CONNECTSERVER: + connectTCPServerContinue(); + break; + case GETIP: + getIPContinue(); + break; + } +} + +//Connect Server main function. +int GSM3ShieldV1MultiServerProvider::connectTCPServer(int port) +{ + // We forget about LocalIP as it has no real use, the modem does whatever it likes + theGSM3ShieldV1ModemCore.setPort(port); + theGSM3ShieldV1ModemCore.openCommand(this,CONNECTSERVER); + connectTCPServerContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Connect Server continue function. +void GSM3ShieldV1MultiServerProvider::connectTCPServerContinue() +{ + + bool resp; + // 1: Read Local IP "AT+QILOCIP" + // 2: Waiting for IP and Set local port "AT+QILPORT" + // 3: Waiting for QILPOR OK andConfigure as server "AT+QISERVER" + // 4: Wait for SERVER OK + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //"AT+QILOCIP." + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_QILOCIP); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + //Not IP storing but the command is necessary. + //if(parseQILOCIP_rsp(local_IP, local_IP_Length, resp)) + // This awful trick saves some RAM bytes + char aux[3]; + aux[0]='\r';aux[1]='\n';aux[2]=0; + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp, aux)) + { + //Response received + if(resp) + { + // Great. Go for the next step + // AT+QILPORT + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QILPORT=\"TCP\","),false); + theGSM3ShieldV1ModemCore.print( theGSM3ShieldV1ModemCore.getPort()); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + case 3: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Response received + if(resp) + { + // OK received + // Great. Go for the next step + // AT+QISERVER + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QISERVER=0,"),false); + theGSM3ShieldV1ModemCore.print(__NCLIENTS_MAX__); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(4); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + case 4: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Response received + // OK received, kathapoon, chessespoon + if (resp) theGSM3ShieldV1ModemCore.closeCommand(1); + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//QILOCIP parse. +bool GSM3ShieldV1MultiServerProvider::parseQILOCIP_rsp(char* LocalIP, int LocalIPlength, bool& rsp) +{ + if (!(theGSM3ShieldV1ModemCore.theBuffer().extractSubstring("\r\n","\r\n", LocalIP, LocalIPlength))) + rsp = false; + else + rsp = true; + return true; +} + +//Get IP main function. +int GSM3ShieldV1MultiServerProvider::getIP(char* LocalIP, int LocalIPlength) +{ + theGSM3ShieldV1ModemCore.setPhoneNumber(LocalIP); + theGSM3ShieldV1ModemCore.setPort(LocalIPlength); + theGSM3ShieldV1ModemCore.openCommand(this,GETIP); + getIPContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +void GSM3ShieldV1MultiServerProvider::getIPContinue() +{ + + bool resp; + // 1: Read Local IP "AT+QILOCIP" + // 2: Waiting for IP. + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //AT+QILOCIP + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_QILOCIP); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(parseQILOCIP_rsp(theGSM3ShieldV1ModemCore.getPhoneNumber(), theGSM3ShieldV1ModemCore.getPort(), resp)) + { + if (resp) + theGSM3ShieldV1ModemCore.closeCommand(1); + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +bool GSM3ShieldV1MultiServerProvider::getSocketAsServerModemStatus(int s) +{ + if (socketsAccepted&(0x0001< +#include + +class GSM3ShieldV1MultiServerProvider : public GSM3MobileServerProvider, public GSM3ShieldV1BaseProvider +{ + private: + + // Used sockets + uint8_t socketsAsServer; + uint8_t socketsAccepted; + + /** Continue to connect TCP server function + */ + void connectTCPServerContinue(); + + /** Continue to get IP function + */ + void getIPContinue(); + + /** Release socket + @param socket Socket + */ + void releaseSocket(int socket); + + /** Parse QILOCIP response + @param LocalIP Buffer for save local IP address + @param LocalIPlength Buffer size + @param rsp Returns if expected response exists + @return true if command executed correctly + */ + bool parseQILOCIP_rsp(char* LocalIP, int LocalIPlength, bool& rsp); + + public: + + /** Constructor */ + GSM3ShieldV1MultiServerProvider(); + + /** minSocketAsServer + @return 0 + */ + int minSocketAsServer(){return 0;}; + + /** maxSocketAsServer + @return 0 + */ + int maxSocketAsServer(){return 4;}; + + /** Get modem status + @param s + @return modem status (true if connected) + */ + bool getSocketAsServerModemStatus(int s); + + /** Get new occupied socket as server + @return command error if exists + */ + int getNewOccupiedSocketAsServer(); + + /** Connect server to TCP port + @param port TCP port + @return command error if exists + */ + int connectTCPServer(int port); + + /** Get server IP address + @param LocalIP Buffer for copy IP address + @param LocalIPlength Length of buffer + @return command error if exists + */ + int getIP(char* LocalIP, int LocalIPlength); + +// int disconnectTCP(bool client1Server0, int id_socket); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + /** Get socket status as server + @param socket Socket to get status + @return socket status + */ + bool getStatusSocketAsServer(uint8_t socket); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + /** Recognize unsolicited event + @param oldTail + @return true if successful + */ + bool recognizeUnsolicitedEvent(byte oldTail); + + +}; + +#endif diff --git a/libraries/GSM3/GSM3ShieldV1PinManagement.cpp b/libraries/GSM3/GSM3ShieldV1PinManagement.cpp new file mode 100644 index 000000000..0c0c74960 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1PinManagement.cpp @@ -0,0 +1,201 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ + +#include + +// constructor +GSM3ShieldV1PinManagement::GSM3ShieldV1PinManagement() +{ +}; + +// reset the modem for direct access +void GSM3ShieldV1PinManagement::begin() +{ + // reset hardware + gsm.HWrestart(); + + pin_used = false; + + // check modem response + modemAccess.writeModemCommand("AT", 1000); + modemAccess.writeModemCommand("ATE0", 1000); +} + +/* + Check PIN status +*/ +int GSM3ShieldV1PinManagement::isPIN() +{ + String res = modemAccess.writeModemCommand("AT+CPIN?",1000); + // Check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "READY") != NULL) + return 0; + else if(strstr(res_to_compare, "SIM PIN") != NULL) + return 1; + else if(strstr(res_to_compare, "SIM PUK") != NULL) + return -1; + else + return -2; +} + +/* + Check PIN code +*/ +int GSM3ShieldV1PinManagement::checkPIN(String pin) +{ + String res = modemAccess.writeModemCommand("AT+CPIN=" + pin,1000); + // check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "OK") == NULL) + return -1; + else + return 0; +} + +/* + Check PUK code +*/ +int GSM3ShieldV1PinManagement::checkPUK(String puk, String pin) +{ + String res = modemAccess.writeModemCommand("AT+CPIN=\"" + puk + "\",\"" + pin + "\"",1000); + // check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "OK") == NULL) + return -1; + else + return 0; +} + +/* + Change PIN code +*/ +void GSM3ShieldV1PinManagement::changePIN(String old, String pin) +{ + String res = modemAccess.writeModemCommand("AT+CPWD=\"SC\",\"" + old + "\",\"" + pin + "\"",2000); + Serial.println(res); + // check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "OK") != NULL) + Serial.println("Pin changed succesfully."); + else + Serial.println("ERROR"); +} + +/* + Switch PIN status +*/ +void GSM3ShieldV1PinManagement::switchPIN(String pin) +{ + String res = modemAccess.writeModemCommand("AT+CLCK=\"SC\",2",1000); + // check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "0") != NULL) + { + res = modemAccess.writeModemCommand("AT+CLCK=\"SC\",1,\"" + pin + "\"",1000); + // check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "OK") == NULL) + { + Serial.println("ERROR"); + pin_used = false; + } + else + { + Serial.println("OK. PIN lock on."); + pin_used = true; + } + } + else if(strstr(res_to_compare, "1") != NULL) + { + res = modemAccess.writeModemCommand("AT+CLCK=\"SC\",0,\"" + pin + "\"",1000); + // check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "OK") == NULL) + { + Serial.println("ERROR"); + pin_used = true; + } + else + { + Serial.println("OK. PIN lock off."); + pin_used = false; + } + } + else + { + Serial.println("ERROR"); + } +} + +/* + Check registrer +*/ +int GSM3ShieldV1PinManagement::checkReg() +{ + delay(5000); + String res = modemAccess.writeModemCommand("AT+CREG?",1000); + // check response + char res_to_compare[res.length()]; + res.toCharArray(res_to_compare, res.length()); + if(strstr(res_to_compare, "1") != NULL) + return 0; + else if(strstr(res_to_compare, "5") != NULL) + return 1; + else + return -1; +} + +/* + Return if PIN lock is used +*/ +bool GSM3ShieldV1PinManagement::getPINUsed() +{ + return pin_used; +} + +/* + Set if PIN lock is used +*/ +void GSM3ShieldV1PinManagement::setPINUsed(bool used) +{ + pin_used = used; +} \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1PinManagement.h b/libraries/GSM3/GSM3ShieldV1PinManagement.h new file mode 100644 index 000000000..ce43cdd14 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1PinManagement.h @@ -0,0 +1,103 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3SHIELDV1PINMANAGEMENT_ +#define _GSM3SHIELDV1PINMANAGEMENT_ + +#include +#include + +class GSM3ShieldV1PinManagement +{ + + private: + + GSM3ShieldV1AccessProvider gsm; // GSM access required for network register with PIN code + GSM3ShieldV1DirectModemProvider modemAccess; + bool pin_used; // determines if pin lock is activated + + public: + + /** Constructor */ + GSM3ShieldV1PinManagement(); + + /** Check modem response and restart it + */ + void begin(); + + /** Check if PIN lock or PUK lock is activated + @return 0 if PIN lock is off, 1 if PIN lock is on, -1 if PUK lock is on, -2 if error exists + */ + int isPIN(); + + /** Check if PIN code is correct and valid + @param pin PIN code + @return 0 if is correct, -1 if is incorrect + */ + int checkPIN(String pin); + + /** Check if PUK code is correct and establish new PIN code + @param puk PUK code + @param pin New PIN code + @return 0 if successful, otherwise return -1 + */ + int checkPUK(String puk, String pin); + + /** Change PIN code + @param old Old PIN code + @param pin New PIN code + */ + void changePIN(String old, String pin); + + /** Change PIN lock status + @param pin PIN code + */ + void switchPIN(String pin); + + /** Check if modem was registered in GSM/GPRS network + @return 0 if modem was registered, 1 if modem was registered in roaming, -1 if error exists + */ + int checkReg(); + + /** Return if PIN lock is used + @return true if PIN lock is used, otherwise, return false + */ + bool getPINUsed(); + + /** Set PIN lock status + @param used New PIN lock status + */ + void setPINUsed(bool used); +}; + +#endif; \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1SMSProvider.cpp b/libraries/GSM3/GSM3ShieldV1SMSProvider.cpp new file mode 100644 index 000000000..9ed075e7b --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1SMSProvider.cpp @@ -0,0 +1,293 @@ +#include +#include + +GSM3ShieldV1SMSProvider::GSM3ShieldV1SMSProvider() +{ + theGSM3SMSProvider=this; +}; + +//Send SMS begin function. +int GSM3ShieldV1SMSProvider::beginSMS(const char* to) +{ + if((theGSM3ShieldV1ModemCore.getStatus() != GSM_READY)&&(theGSM3ShieldV1ModemCore.getStatus() != GPRS_READY)) + return 2; + + theGSM3ShieldV1ModemCore.setPhoneNumber((char*)to); + theGSM3ShieldV1ModemCore.openCommand(this,BEGINSMS); + beginSMSContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Send SMS continue function. +void GSM3ShieldV1SMSProvider::beginSMSContinue() +{ + bool resp; + // 1: Send AT + // 2: wait for > and write text + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.setCommandCounter(2); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CMGS=\""), false); + theGSM3ShieldV1ModemCore.print(theGSM3ShieldV1ModemCore.getPhoneNumber()); + theGSM3ShieldV1ModemCore.print("\"\r"); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp, ">")) + { + if (resp) theGSM3ShieldV1ModemCore.closeCommand(1); + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Send SMS write function. +void GSM3ShieldV1SMSProvider::writeSMS(char c) +{ + theGSM3ShieldV1ModemCore.write(c); +} + +//Send SMS begin function. +int GSM3ShieldV1SMSProvider::endSMS() +{ + theGSM3ShieldV1ModemCore.openCommand(this,ENDSMS); + endSMSContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Send SMS continue function. +void GSM3ShieldV1SMSProvider::endSMSContinue() +{ + bool resp; + // 1: Send #26 + // 2: wait for OK + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.setCommandCounter(2); + theGSM3ShieldV1ModemCore.write(26); + theGSM3ShieldV1ModemCore.print("\r"); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if (resp) + theGSM3ShieldV1ModemCore.closeCommand(1); + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Available SMS main function. +int GSM3ShieldV1SMSProvider::availableSMS() +{ + flagReadingSMS = 0; + theGSM3ShieldV1ModemCore.openCommand(this,AVAILABLESMS); + availableSMSContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Available SMS continue function. +void GSM3ShieldV1SMSProvider::availableSMSContinue() +{ + // 1: AT+CMGL="REC UNREAD",1 + // 2: Receive +CMGL: _id_ ... READ","_numero_" ... \n_mensaje_\nOK + // 3: Send AT+CMGD= _id_ + // 4: Receive OK + // 5: Remaining SMS text in case full buffer. + // This implementation really does not care much if the modem aswers trash to CMGL + bool resp; + //int msglength_aux; + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CMGL=\"REC UNREAD\",1")); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(parseCMGL_available(resp)) + { + if (!resp) theGSM3ShieldV1ModemCore.closeCommand(4); + else theGSM3ShieldV1ModemCore.closeCommand(1); + } + break; + } + +} + +//SMS available parse. +bool GSM3ShieldV1SMSProvider::parseCMGL_available(bool& rsp) +{ + fullBufferSMS = (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()<=4); + if (!(theGSM3ShieldV1ModemCore.theBuffer().chopUntil("+CMGL:", true))) + rsp = false; + else + rsp = true; + idSMS=theGSM3ShieldV1ModemCore.theBuffer().readInt(); + + //If there are 2 SMS in buffer, response is ...CRLFCRLF+CMGL + twoSMSinBuffer = theGSM3ShieldV1ModemCore.theBuffer().locate("\r\n\r\n+"); + + checkSecondBuffer = 0; + + return true; +} + +//remoteNumber SMS function. +int GSM3ShieldV1SMSProvider::remoteSMSNumber(char* number, int nlength) +{ + theGSM3ShieldV1ModemCore.theBuffer().extractSubstring("READ\",\"", "\"", number, nlength); + + return 1; +} + +//remoteNumber SMS function. +int GSM3ShieldV1SMSProvider::readSMS() +{ + char charSMS; + //First char. + if (!flagReadingSMS) + { + flagReadingSMS = 1; + theGSM3ShieldV1ModemCore.theBuffer().chopUntil("\n", true); + } + charSMS = theGSM3ShieldV1ModemCore.theBuffer().read(); + + //Second Buffer. + if (checkSecondBuffer) + { + checkSecondBuffer = 0; + twoSMSinBuffer = theGSM3ShieldV1ModemCore.theBuffer().locate("\r\n\r\n+"); + } + + //Case the last char in buffer. + if ((!twoSMSinBuffer)&&fullBufferSMS&&(theGSM3ShieldV1ModemCore.theBuffer().availableBytes()==127)) + { + theGSM3ShieldV1ModemCore.theBuffer().flush(); + fullBufferSMS = 0; + checkSecondBuffer = 1; + theGSM3ShieldV1ModemCore.openCommand(this,XON); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + delay(10); + + return charSMS; + } + //Case two SMS in buffer + else if (twoSMSinBuffer) + { + if (theGSM3ShieldV1ModemCore.theBuffer().locate("\r\n\r\n+")) + { + return charSMS; + } + else + { + theGSM3ShieldV1ModemCore.theBuffer().flush(); + theGSM3ShieldV1ModemCore.openCommand(this,XON); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + delay(10); + return 0; + } + } + //Case 1 SMS and buffer not full + else if (!fullBufferSMS) + { + if (theGSM3ShieldV1ModemCore.theBuffer().locate("\r\n\r\nOK")) + { + return charSMS; + } + else + { + theGSM3ShieldV1ModemCore.theBuffer().flush(); + theGSM3ShieldV1ModemCore.openCommand(this,XON); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + delay(10); + return 0; + } + } + //Case to read all the chars in buffer to the end. + else + { + return charSMS; + } +} + +//Read socket main function. +int GSM3ShieldV1SMSProvider::peekSMS() +{ + if (!flagReadingSMS) + { + flagReadingSMS = 1; + theGSM3ShieldV1ModemCore.theBuffer().chopUntil("\n", true); + } + + return theGSM3ShieldV1ModemCore.theBuffer().peek(0); +} + +//Flush SMS main function. +void GSM3ShieldV1SMSProvider::flushSMS() +{ + + //With this, sms data can fill up to 2x128+5x128 bytes. + for (int aux = 0;aux<5;aux++) + { + theGSM3ShieldV1ModemCore.theBuffer().flush(); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + delay(10); + } + + theGSM3ShieldV1ModemCore.openCommand(this,FLUSHSMS); + flushSMSContinue(); +} + +//Send SMS continue function. +void GSM3ShieldV1SMSProvider::flushSMSContinue() +{ + bool resp; + // 1: Deleting SMS + // 2: wait for OK + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.setCommandCounter(2); + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CMGD="), false); + theGSM3ShieldV1ModemCore.print(idSMS); + theGSM3ShieldV1ModemCore.print("\r"); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + if (resp) theGSM3ShieldV1ModemCore.closeCommand(1); + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +void GSM3ShieldV1SMSProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { +/* case XON: + if (flagReadingSocket) + { +// flagReadingSocket = 0; + fullBufferSocket = (theGSM3ShieldV1ModemCore.theBuffer().availableBytes()<3); + } + else theGSM3ShieldV1ModemCore.openCommand(this,NONE); + break; +*/ case NONE: + theGSM3ShieldV1ModemCore.gss.cb.deleteToTheEnd(from); + break; + case BEGINSMS: + beginSMSContinue(); + break; + case ENDSMS: + endSMSContinue(); + break; + case AVAILABLESMS: + availableSMSContinue(); + break; + case FLUSHSMS: + flushSMSContinue(); + break; + } +} diff --git a/libraries/GSM3/GSM3ShieldV1SMSProvider.h b/libraries/GSM3/GSM3ShieldV1SMSProvider.h new file mode 100644 index 000000000..408da338e --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1SMSProvider.h @@ -0,0 +1,130 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_SHIELDV1SMSPROVIDER__ +#define __GSM3_SHIELDV1SMSPROVIDER__ + +#include +#include +#include + + +class GSM3ShieldV1SMSProvider : public GSM3MobileSMSProvider, public GSM3ShieldV1BaseProvider +{ + public: + GSM3ShieldV1SMSProvider(); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + /** Begin a SMS to send it + @param to Destination + @return error command if it exists + */ + inline int beginSMS(const char* to); + + /** Write a SMS character by character + @param c Character + */ + inline void writeSMS(char c); + + /** End SMS + @return error command if it exists + */ + inline int endSMS(); + + /** Check if SMS available and prepare it to be read + @return number of bytes in a received SMS + */ + int availableSMS(); + + /** Read a byte but do not advance the buffer header (circular buffer) + @return character + */ + int peekSMS(); + + /** Delete the SMS from Modem memory and proccess answer + */ + void flushSMS(); + + /** Read sender number phone + @param number Buffer for save number phone + @param nlength Buffer length + @return 1 success, >1 error + */ + int remoteSMSNumber(char* number, int nlength); //Before reading the SMS, read the phone number. + + /** Read one char for SMS buffer (advance circular buffer) + @return character + */ + int readSMS(); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + private: + + int idSMS; // Id from current SMS being read. + bool flagReadingSMS; // To detect first SMS char if not yet reading. + bool fullBufferSMS; // To detect if the SMS being read needs another buffer. + bool twoSMSinBuffer; // To detect if the buffer has more than 1 SMS. + bool checkSecondBuffer; // Pending to detect if the second buffer has more than 1 SMS. + + /** Continue to begin SMS function + */ + void beginSMSContinue(); + + /** Continue to end SMS function + */ + void endSMSContinue(); + + /** Continue to available SMS function + */ + void availableSMSContinue(); + + /** Continue to flush SMS function + */ + void flushSMSContinue(); + + /** Parse CMGL response + @param rsp Returns true if expected response exists + @return true if command executed correctly + */ + bool parseCMGL_available(bool& rsp); +}; +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1ScanNetworks.cpp b/libraries/GSM3/GSM3ShieldV1ScanNetworks.cpp new file mode 100644 index 000000000..23da8a6b4 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ScanNetworks.cpp @@ -0,0 +1,126 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ + +#include + +GSM3ShieldV1ScanNetworks::GSM3ShieldV1ScanNetworks(bool trace): modem(trace) +{ +} + +GSM3_NetworkStatus_t GSM3ShieldV1ScanNetworks::begin() +{ + modem.begin(); + modem.restartModem(); + // check modem response + modem.writeModemCommand("AT", 1000); + modem.writeModemCommand("ATE0", 1000); + return IDLE; +} + +String GSM3ShieldV1ScanNetworks::getCurrentCarrier() +{ + String modemResponse = modem.writeModemCommand("AT+COPS?", 2000); + + // Parse and check response + char res_to_split[modemResponse.length()]; + modemResponse.toCharArray(res_to_split, modemResponse.length()); + if(strstr(res_to_split,"ERROR") == NULL){ + // Tokenizer + char *ptr_token; + ptr_token = strtok(res_to_split, "\""); + ptr_token = strtok(NULL, "\""); + String final_result = ptr_token; + return final_result; + }else{ + return NULL; + } +} + +String GSM3ShieldV1ScanNetworks::getSignalStrength() +{ + String modemResponse = modem.writeModemCommand("AT+CSQ", 2000); + char res_to_split[modemResponse.length()]; + modemResponse.toCharArray(res_to_split, modemResponse.length()); + if((strstr(res_to_split,"ERROR") == NULL) | (strstr(res_to_split,"99") == NULL)){ + // Tokenizer + char *ptr_token; + ptr_token = strtok(res_to_split, ":"); + ptr_token = strtok(NULL, ":"); + ptr_token = strtok(ptr_token, ","); + String final_result = ptr_token; + final_result.trim(); + return final_result; + }else{ + return NULL; + } +} + +String GSM3ShieldV1ScanNetworks::readNetworks() +{ + String modemResponse = modem.writeModemCommand("AT+COPS=?",20000); + String result; + bool inQuotes=false; + int quoteCounter=0; + for(int i=0; i +#include + +class GSM3ShieldV1ScanNetworks +{ + private: + GSM3ShieldV1DirectModemProvider modem; + + public: + + /** Constructor + @param trace if true, dumps all AT dialogue to Serial + @return - + */ + GSM3ShieldV1ScanNetworks(bool trace=false); + + /** begin (forces modem hardware restart, so we begin from scratch) + @return Always returns IDLE status + */ + GSM3_NetworkStatus_t begin(); + + /** Read current carrier + @return Current carrier + */ + String getCurrentCarrier(); + + /** Obtain signal strength + @return Signal Strength + */ + String getSignalStrength(); + + /** Search available carriers + @return A string with list of networks available + */ + String readNetworks(); +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1ServerProvider.cpp b/libraries/GSM3/GSM3ShieldV1ServerProvider.cpp new file mode 100644 index 000000000..77f543674 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ServerProvider.cpp @@ -0,0 +1,205 @@ +#include +#include +#include + +GSM3ShieldV1ServerProvider::GSM3ShieldV1ServerProvider() +{ + theGSM3MobileServerProvider=this; +}; + +//Response management. +void GSM3ShieldV1ServerProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case NONE: + theGSM3ShieldV1ModemCore.gss.cb.deleteToTheEnd(from); + break; + case CONNECTSERVER: + connectTCPServerContinue(); + break; + /*case GETIP: + getIPContinue(); + break;*/ + } +} + +//Connect Server main function. +int GSM3ShieldV1ServerProvider::connectTCPServer(int port) +{ + // We forget about LocalIP as it has no real use, the modem does whatever it likes + theGSM3ShieldV1ModemCore.setPort(port); + theGSM3ShieldV1ModemCore.openCommand(this,CONNECTSERVER); + // From this moment on we wait for a call + connectTCPServerContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Connect Server continue function. +void GSM3ShieldV1ServerProvider::connectTCPServerContinue() +{ + + bool resp; + // 1: Read Local IP "AT+QILOCIP" + // 2: Waiting for IP and Set local port "AT+QILPORT" + // 3: Waiting for QILPOR OK andConfigure as server "AT+QISERVER" + // 4: Wait for SERVER OK + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //"AT+QILOCIP." + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QILOCIP")); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + //Not IP storing but the command is necessary. + //if(parseQILOCIP_rsp(local_IP, local_IP_Length, resp)) + // This awful trick saves some RAM bytes + char aux[3]; + aux[0]='\r';aux[1]='\n';aux[2]=0; + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp, aux)) + { + //Response received + if(resp) + { + // Great. Go for the next step + // AT+QILPORT + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QILPORT=\"TCP\","),false); + theGSM3ShieldV1ModemCore.print( theGSM3ShieldV1ModemCore.getPort()); + theGSM3ShieldV1ModemCore.print('\r'); + theGSM3ShieldV1ModemCore.setCommandCounter(3); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + case 3: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Response received + if(resp) + { + // OK received + // Great. Go for the next step + // AT+QISERVER + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+QISERVER"),true); + theGSM3ShieldV1ModemCore.setCommandCounter(4); + } + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + case 4: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + // Response received + // OK received, kathapoon, chessespoon + if (resp) + { + theGSM3ShieldV1ModemCore.registerUMProvider(this); + theGSM3ShieldV1ModemCore.closeCommand(1); + } + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//QILOCIP parse. +/*bool GSM3ShieldV1ServerProvider::parseQILOCIP_rsp(char* LocalIP, int LocalIPlength, bool& rsp) +{ + if (!(theGSM3ShieldV1ModemCore.theBuffer().extractSubstring("\r\n","\r\n", LocalIP, LocalIPlength))) + rsp = false; + else + rsp = true; + return true; +} + +//Get IP main function. +int GSM3ShieldV1ServerProvider::getIP(char* LocalIP, int LocalIPlength) +{ + theGSM3ShieldV1ModemCore.setPhoneNumber(LocalIP); + theGSM3ShieldV1ModemCore.setPort(LocalIPlength); + theGSM3ShieldV1ModemCore.openCommand(this,GETIP); + getIPContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +void GSM3ShieldV1ServerProvider::getIPContinue() +{ + + bool resp; + // 1: Read Local IP "AT+QILOCIP" + // 2: Waiting for IP. + + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //AT+QILOCIP + theGSM3ShieldV1ModemCore.genericCommand_rq(_command_MonoQILOCIP); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(parseQILOCIP_rsp(theGSM3ShieldV1ModemCore.getPhoneNumber(), theGSM3ShieldV1ModemCore.getPort(), resp)) + { + if (resp) + theGSM3ShieldV1ModemCore.closeCommand(1); + else + theGSM3ShieldV1ModemCore.closeCommand(3); + } + theGSM3ShieldV1ModemCore.theBuffer().flush(); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + break; + } +}*/ + +bool GSM3ShieldV1ServerProvider::getSocketAsServerModemStatus(int s) +{ + if(theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED) + return true; + else + return false; +} + + +//URC recognize. +bool GSM3ShieldV1ServerProvider::recognizeUnsolicitedEvent(byte oldTail) +{ + + int nlength; + char auxLocate [15]; + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.setStatus(GPRS_READY); + } + + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("CONNECT\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.theBuffer().chopUntil(auxLocate, true); + theGSM3ShieldV1ModemCore.gss.spaceAvailable(); + theGSM3ShieldV1ModemCore.setStatus(TRANSPARENT_CONNECTED); + return true; + } + + return false; +} + +bool GSM3ShieldV1ServerProvider::getStatusSocketAsServer(uint8_t socket) +{ + return(theGSM3ShieldV1ModemCore.getStatus()==TRANSPARENT_CONNECTED); +}; + +void GSM3ShieldV1ServerProvider::releaseSocket(int socket) +{ +} + +int GSM3ShieldV1ServerProvider::getNewOccupiedSocketAsServer() +{ + return 0; +} \ No newline at end of file diff --git a/libraries/GSM3/GSM3ShieldV1ServerProvider.h b/libraries/GSM3/GSM3ShieldV1ServerProvider.h new file mode 100644 index 000000000..93fcd89a5 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1ServerProvider.h @@ -0,0 +1,126 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_SHIELDV1SERVERPROVIDER__ +#define __GSM3_SHIELDV1SERVERPROVIDER__ + +#include +#include + +class GSM3ShieldV1ServerProvider : public GSM3MobileServerProvider, public GSM3ShieldV1BaseProvider +{ + private: + + /** Continue to connect to server with TCP protocol function + */ + void connectTCPServerContinue(); + + /** Continue to get IP address function + */ + //void getIPContinue(); + + /** Parse QILOCIP response + @param LocalIP Buffer for save local IP address + @param LocalIPlength Buffer size + @param rsp Returns if expected response exists + @return true if command executed correctly + */ + //bool parseQILOCIP_rsp(char* LocalIP, int LocalIPlength, bool& rsp); + + /** Release socket + @param socket Socket + */ + void releaseSocket(int socket); + + public: + + /** Constructor */ + GSM3ShieldV1ServerProvider(); + + /** minSocketAsServer + @return 0 + */ + int minSocketAsServer(){return 0;}; + + /** maxSocketAsServer + @return 0 + */ + int maxSocketAsServer(){return 0;}; + + /** Get modem status + @param s Socket + @return modem status (true if connected) + */ + bool getSocketAsServerModemStatus(int s); + + /** Get new occupied socket as server + @return return -1 if no new socket has been occupied + */ + int getNewOccupiedSocketAsServer(); + + /** Connect server to TCP port + @param port TCP port + @return command error if exists + */ + int connectTCPServer(int port); + + //int getIP(char* LocalIP, int LocalIPlength); +// int disconnectTCP(bool client1Server0, int id_socket); + + /** Get last command status + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + /** Get socket status as server + @param socket Socket to get status + @return socket status + */ + bool getStatusSocketAsServer(uint8_t socket); + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + /** Recognize unsolicited event + @param oldTail + @return true if successful + */ + bool recognizeUnsolicitedEvent(byte oldTail); + + +}; + +#endif diff --git a/libraries/GSM3/GSM3ShieldV1VoiceProvider.cpp b/libraries/GSM3/GSM3ShieldV1VoiceProvider.cpp new file mode 100644 index 000000000..98a50b900 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1VoiceProvider.cpp @@ -0,0 +1,215 @@ +#include +#include + +GSM3ShieldV1VoiceProvider::GSM3ShieldV1VoiceProvider() + { + phonelength=0; + theGSM3MobileVoiceProvider=this; + } + + void GSM3ShieldV1VoiceProvider::initialize() + { + theGSM3ShieldV1ModemCore.registerUMProvider(this); + } + +//Voice Call main function. +int GSM3ShieldV1VoiceProvider::voiceCall(const char* to) +{ + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("ATD"),false); + theGSM3ShieldV1ModemCore.print(to); + theGSM3ShieldV1ModemCore.print(";\r"); + setvoiceCallStatus(CALLING); + return 1; +} + +//Retrieve calling number main function. +int GSM3ShieldV1VoiceProvider::retrieveCallingNumber (char* buffer, int bufsize) +{ + theGSM3ShieldV1ModemCore.setPhoneNumber(buffer); + phonelength = bufsize; + theGSM3ShieldV1ModemCore.setCommandError(0); + theGSM3ShieldV1ModemCore.setCommandCounter(1); + theGSM3ShieldV1ModemCore.openCommand(this,RETRIEVECALLINGNUMBER); + retrieveCallingNumberContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Retrieve calling number Continue function. +void GSM3ShieldV1VoiceProvider::retrieveCallingNumberContinue() +{ + // 1: AT+CLCC + // 2: Receive +CLCC: 1,1,4,0,0,"num",129,"" + // This implementation really does not care much if the modem aswers trash to CMGL + bool resp; + //int msglength_aux; + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("AT+CLCC")); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(parseCLCC(theGSM3ShieldV1ModemCore.getPhoneNumber(), phonelength)) + { + theGSM3ShieldV1ModemCore.closeCommand(1); + } + break; + } +} + +//CLCC parse. +bool GSM3ShieldV1VoiceProvider::parseCLCC(char* number, int nlength) +{ + theGSM3ShieldV1ModemCore.theBuffer().extractSubstring("+CLCC: 1,1,4,0,0,\"","\"", number, nlength); + theGSM3ShieldV1ModemCore.theBuffer().flush(); + return true; +} + +//Answer Call main function. +int GSM3ShieldV1VoiceProvider::answerCall() +{ + theGSM3ShieldV1ModemCore.setCommandError(0); + theGSM3ShieldV1ModemCore.setCommandCounter(1); + theGSM3ShieldV1ModemCore.openCommand(this,ANSWERCALL); + answerCallContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Answer Call continue function. +void GSM3ShieldV1VoiceProvider::answerCallContinue() +{ + // 1: ATA + // 2: Waiting for OK + + // This implementation really does not care much if the modem aswers trash to CMGL + bool resp; + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + // ATA ; + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("ATA")); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + setvoiceCallStatus(TALKING); + if (resp) theGSM3ShieldV1ModemCore.closeCommand(1); + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Hang Call main function. +int GSM3ShieldV1VoiceProvider::hangCall() +{ + theGSM3ShieldV1ModemCore.setCommandError(0); + theGSM3ShieldV1ModemCore.setCommandCounter(1); + theGSM3ShieldV1ModemCore.openCommand(this,HANGCALL); + hangCallContinue(); + return theGSM3ShieldV1ModemCore.getCommandError(); +} + +//Hang Call continue function. +void GSM3ShieldV1VoiceProvider::hangCallContinue() +{ + // 1: ATH + // 2: Waiting for OK + + bool resp; + switch (theGSM3ShieldV1ModemCore.getCommandCounter()) { + case 1: + //ATH + theGSM3ShieldV1ModemCore.genericCommand_rq(PSTR("ATH")); + theGSM3ShieldV1ModemCore.setCommandCounter(2); + break; + case 2: + if(theGSM3ShieldV1ModemCore.genericParse_rsp(resp)) + { + setvoiceCallStatus(IDLE_CALL); + if (resp) theGSM3ShieldV1ModemCore.closeCommand(1); + else theGSM3ShieldV1ModemCore.closeCommand(3); + } + break; + } +} + +//Response management. +void GSM3ShieldV1VoiceProvider::manageResponse(byte from, byte to) +{ + switch(theGSM3ShieldV1ModemCore.getOngoingCommand()) + { + case ANSWERCALL: + answerCallContinue(); + break; + case HANGCALL: + hangCallContinue(); + break; + case RETRIEVECALLINGNUMBER: + retrieveCallingNumberContinue(); + break; + + } +} + +//URC recognize. +bool GSM3ShieldV1VoiceProvider::recognizeUnsolicitedEvent(byte oldTail) +{ + + int nlength; + char auxLocate [15]; + //RING. + prepareAuxLocate(PSTR("RING"), auxLocate); + if(theGSM3ShieldV1ModemCore.theBuffer().locate(auxLocate)) + { + // RING + setvoiceCallStatus(RECEIVINGCALL); + theGSM3ShieldV1ModemCore.theBuffer().flush(); + return true; + } + + //CALL ACEPTED. + prepareAuxLocate(PSTR("+COLP:"), auxLocate); + if(theGSM3ShieldV1ModemCore.theBuffer().locate(auxLocate)) + { + //DEBUG + //Serial.println("Call Accepted."); + setvoiceCallStatus(TALKING); + theGSM3ShieldV1ModemCore.theBuffer().flush(); + return true; + } + + //NO CARRIER. + prepareAuxLocate(PSTR("NO CARRIER"), auxLocate); + if(theGSM3ShieldV1ModemCore.theBuffer().locate(auxLocate)) + { + //DEBUG + //Serial.println("NO CARRIER received."); + setvoiceCallStatus(IDLE_CALL); + theGSM3ShieldV1ModemCore.theBuffer().flush(); + return true; + } + + //BUSY. + prepareAuxLocate(PSTR("BUSY"), auxLocate); + if(theGSM3ShieldV1ModemCore.theBuffer().locate(auxLocate)) + { + //DEBUG + //Serial.println("BUSY received."); + setvoiceCallStatus(IDLE_CALL); + theGSM3ShieldV1ModemCore.theBuffer().flush(); + return true; + } + + //CALL RECEPTION. + prepareAuxLocate(PSTR("+CLIP:"), auxLocate); + if(theGSM3ShieldV1ModemCore.theBuffer().locate(auxLocate)) + { + theGSM3ShieldV1ModemCore.theBuffer().flush(); + setvoiceCallStatus(RECEIVINGCALL); + return true; + } + + return false; +} + + diff --git a/libraries/GSM3/GSM3ShieldV1VoiceProvider.h b/libraries/GSM3/GSM3ShieldV1VoiceProvider.h new file mode 100644 index 000000000..b96138533 --- /dev/null +++ b/libraries/GSM3/GSM3ShieldV1VoiceProvider.h @@ -0,0 +1,137 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ + +#ifndef _GSM3SHIELDV1VOICEPROVIDER_ +#define _GSM3SHIELDV1VOICEPROVIDER_ + +#include +#include +#include + +class GSM3ShieldV1VoiceProvider : public GSM3MobileVoiceProvider, public GSM3ShieldV1BaseProvider +{ + public: + + /** Constructor */ + GSM3ShieldV1VoiceProvider(); + + /** initilizer, links with modem provider */ + void initialize(); + + + /** Manages modem response + @param from Initial byte of buffer + @param to Final byte of buffer + */ + void manageResponse(byte from, byte to); + + //Call functions. + + /** Launch a voice call + @param number Phone number to be called + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + int voiceCall(const char* number); + + /** Answer a voice call + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + int answerCall(); + + /** Hang a voice call + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + int hangCall(); + + /** Retrieve phone number of caller + @param buffer Buffer for copy phone number + @param bufsize Buffer size + @return If asynchronous, returns 0. If synchronous, 1 if success, other if error + */ + int retrieveCallingNumber(char* buffer, int bufsize); + + /** Get last command status + @return Returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(){return GSM3ShieldV1BaseProvider::ready();}; + + /** Recognize URC + @param oldTail + @return true if successful + */ + bool recognizeUnsolicitedEvent(byte oldTail); + + /** Returns voice call status + @return voice call status + */ + GSM3_voiceCall_st getvoiceCallStatus(){ready(); return _voiceCallstatus;}; + + /** Set voice call status + @param status New status for voice call + */ + void setvoiceCallStatus(GSM3_voiceCall_st status) { _voiceCallstatus = status; }; + + + private: + + int phonelength; // Phone number length + + GSM3_voiceCall_st _voiceCallstatus; // The voiceCall status + + /** Continue to voice call function + */ + void voiceCallContinue(); + + /** Continue to answer call function + */ + void answerCallContinue(); + + /** Continue to hang call function + */ + void hangCallContinue(); + + /** Continue to retrieve calling number function + */ + void retrieveCallingNumberContinue(); + + /** Parse CLCC response from buffer + @param number Number initial for extract substring of response + @param nlength Substring length + @return true if successful + */ + bool parseCLCC(char* number, int nlength); + +}; + +#endif diff --git a/libraries/GSM3/GSM3SoftSerial.cpp b/libraries/GSM3/GSM3SoftSerial.cpp new file mode 100644 index 000000000..f6e03de3a --- /dev/null +++ b/libraries/GSM3/GSM3SoftSerial.cpp @@ -0,0 +1,537 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include "GSM3SoftSerial.h" +#include +#include +#include "pins_arduino.h" +#include +#include + +#if defined(__AVR_ATmega328__) +#define __TXPIN__ 3 +#define __RXPIN__ 2 +#define __RXINT__ 3 +#elif defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1280__) +#define __TXPIN__ 3 +#define __RXPIN__ 10 +#define __RXINT__ 4 +#elif defined(__AVR_ATmega32U4__) +#define __TXPIN__ 3 +#define __RXPIN__ 8 +#define __RXINT__ 3 +#endif + +#define __XON__ 0x11 +#define __XOFF__ 0x13 + +#define _GSMSOFTSERIALFLAGS_ESCAPED_ 0x01 +#define _GSMSOFTSERIALFLAGS_SENTXOFF_ 0x02 + +// +// Lookup table +// +#define __PARAGRAPHGUARD__ 50 +typedef struct _DELAY_TABLE +{ + long baud; + unsigned short rx_delay_centering; + unsigned short rx_delay_intrabit; + unsigned short rx_delay_stopbit; + unsigned short tx_delay; +} DELAY_TABLE; + +#if F_CPU == 16000000 + +static const DELAY_TABLE PROGMEM table[] = +{ + // baud rxcenter rxintra rxstop tx + { 115200, 1, 17, 17, 12, }, + { 57600, 10, 37, 37, 33, }, + { 38400, 25, 57, 57, 54, }, + { 31250, 31, 70, 70, 68, }, + { 28800, 34, 77, 77, 74, }, + { 19200, 54, 117, 117, 114, }, + { 14400, 74, 156, 156, 153, }, + { 9600, 114, 236, 236, 233, }, + { 4800, 233, 474, 474, 471, }, + { 2400, 471, 950, 950, 947, }, + { 1200, 947, 1902, 1902, 1899, }, + { 300, 3804, 7617, 7617, 7614, }, +}; + +const int XMIT_START_ADJUSTMENT = 5; + +#elif F_CPU == 8000000 + +static const DELAY_TABLE table[] PROGMEM = +{ + // baud rxcenter rxintra rxstop tx + { 115200, 1, 5, 5, 3, }, + { 57600, 1, 15, 15, 13, }, + { 38400, 2, 25, 26, 23, }, + { 31250, 7, 32, 33, 29, }, + { 28800, 11, 35, 35, 32, }, + { 19200, 20, 55, 55, 52, }, + { 14400, 30, 75, 75, 72, }, + { 9600, 50, 114, 114, 112, }, + { 4800, 110, 233, 233, 230, }, + { 2400, 229, 472, 472, 469, }, + { 1200, 467, 948, 948, 945, }, + { 300, 1895, 3805, 3805, 3802, }, +}; + +const int XMIT_START_ADJUSTMENT = 4; + +#elif F_CPU == 20000000 + +// 20MHz support courtesy of the good people at macegr.com. +// Thanks, Garrett! + +static const DELAY_TABLE PROGMEM table[] = +{ + // baud rxcenter rxintra rxstop tx + { 115200, 3, 21, 21, 18, }, + { 57600, 20, 43, 43, 41, }, + { 38400, 37, 73, 73, 70, }, + { 31250, 45, 89, 89, 88, }, + { 28800, 46, 98, 98, 95, }, + { 19200, 71, 148, 148, 145, }, + { 14400, 96, 197, 197, 194, }, + { 9600, 146, 297, 297, 294, }, + { 4800, 296, 595, 595, 592, }, + { 2400, 592, 1189, 1189, 1186, }, + { 1200, 1187, 2379, 2379, 2376, }, + { 300, 4759, 9523, 9523, 9520, }, +}; + +const int XMIT_START_ADJUSTMENT = 6; + +#else + +#error This version of GSM3SoftSerial supports only 20, 16 and 8MHz processors + +#endif + +GSM3SoftSerial* GSM3SoftSerial::_activeObject=0; + +GSM3SoftSerial::GSM3SoftSerial(): + _rx_delay_centering(0), + _rx_delay_intrabit(0), + _rx_delay_stopbit(0), + _tx_delay(0), + cb(this) +{ + setTX(); + setRX(); + //comStatus=0; + //waitingAnswer=false; +} + +int GSM3SoftSerial::begin(long speed) +{ + _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0; + + for (unsigned i=0; ifinalWrite(0x77); + return this->finalWrite(0xEE); + } + + if(c==0x13) + { + this->finalWrite(0x77); + return this->finalWrite(0xEC); + } + + if(c==0x77) + { + this->finalWrite(0x77); + return this->finalWrite(0x88); + } + + return this->finalWrite(c); +} + +size_t GSM3SoftSerial::finalWrite(uint8_t c) +{ + + uint8_t oldSREG = SREG; + cli(); // turn off interrupts for a clean txmit + + // Write the start bit + tx_pin_write(LOW); + tunedDelay(_tx_delay + XMIT_START_ADJUSTMENT); + + // Write each of the 8 bits + for (byte mask = 0x01; mask; mask <<= 1) + { + if (c & mask) // choose bit + tx_pin_write(HIGH); // send 1 + else + tx_pin_write(LOW); // send 0 + tunedDelay(_tx_delay); + } + + tx_pin_write(HIGH); // restore pin to natural state + + SREG = oldSREG; // turn interrupts back on + tunedDelay(_tx_delay); + + return 1; +} + +/*inline*/ void GSM3SoftSerial::tunedDelay(uint16_t delay) { + uint8_t tmp=0; + + asm volatile("sbiw %0, 0x01 \n\t" + "ldi %1, 0xFF \n\t" + "cpi %A0, 0xFF \n\t" + "cpc %B0, %1 \n\t" + "brne .-10 \n\t" + : "+r" (delay), "+a" (tmp) + : "0" (delay) + ); +} + +void GSM3SoftSerial::tx_pin_write(uint8_t pin_state) +{ + // Direct port manipulation is faster than digitalWrite/Read + if (pin_state == LOW) + *_transmitPortRegister &= ~_transmitBitMask; + else + *_transmitPortRegister |= _transmitBitMask; +} + +void GSM3SoftSerial::setTX() +{ + pinMode(__TXPIN__, OUTPUT); + digitalWrite(__TXPIN__, HIGH); + // For digital port direct manipulation + _transmitBitMask = digitalPinToBitMask(__TXPIN__); + uint8_t port = digitalPinToPort(__TXPIN__); + _transmitPortRegister = portOutputRegister(port); +} + +void GSM3SoftSerial::setRX() +{ + pinMode(__RXPIN__, INPUT); + digitalWrite(__RXPIN__, HIGH); // pullup for normal logic! + // For digital port direct manipulation + _receiveBitMask = digitalPinToBitMask(__RXPIN__); + uint8_t port = digitalPinToPort(__RXPIN__); + _receivePortRegister = portInputRegister(port); + +#ifdef __AVR_ATmega32U4__ +//#define __RXINT__ 1 + attachInterrupt(__RXINT__, GSM3SoftSerial::handle_interrupt, FALLING); +#endif + // This line comes from the High Middle Ages... + // attachInterrupt(__RXINT__, GSM3SoftSerial::handle_interrupt, FALLING); +} + +void GSM3SoftSerial::handle_interrupt() +{ + if(_activeObject) + _activeObject->recv(); +} + +uint8_t GSM3SoftSerial::rx_pin_read() +{ + // Digital port manipulation + return *_receivePortRegister & _receiveBitMask; +} + +void GSM3SoftSerial::recv() +{ + +#if GCC_VERSION < 40302 +// Work-around for avr-gcc 4.3.0 OSX version bug +// Preserve the registers that the compiler misses +// (courtesy of Arduino forum user *etracer*) + asm volatile( + "push r18 \n\t" + "push r19 \n\t" + "push r20 \n\t" + "push r21 \n\t" + "push r22 \n\t" + "push r23 \n\t" + "push r26 \n\t" + "push r27 \n\t" + ::); +#endif + + bool firstByte=true; + byte thisHead; + + uint8_t d = 0; + bool morebytes=false; + //bool fullbuffer=(cb.availableBytes()<3); + bool fullbuffer; + bool capturado_fullbuffer = 0; + int i; + byte oldTail; + + // If RX line is high, then we don't see any start bit + // so interrupt is probably not for us + if (!rx_pin_read()) + { + do + { + oldTail=cb.getTail(); + // Wait approximately 1/2 of a bit width to "center" the sample + tunedDelay(_rx_delay_centering); + + fullbuffer=(cb.availableBytes()<6); + + + if(fullbuffer&&(!capturado_fullbuffer)) + tx_pin_write(LOW); + + + // Read each of the 8 bits + for (uint8_t i=0x1; i; i <<= 1) + { + tunedDelay(_rx_delay_intrabit); + uint8_t noti = ~i; + if (rx_pin_read()) + d |= i; + else // else clause added to ensure function timing is ~balanced + d &= noti; + + if(fullbuffer&&(!capturado_fullbuffer)) + { + if((uint8_t)__XOFF__ & i) + tx_pin_write(HIGH); + else + tx_pin_write(LOW); + } + } + + if(fullbuffer&&(!capturado_fullbuffer)) + { + tunedDelay(_rx_delay_intrabit); + tx_pin_write(HIGH); + } + + // So, we know the buffer is full, and we have sent a XOFF + if (fullbuffer) + { + capturado_fullbuffer =1; + _flags |=_GSMSOFTSERIALFLAGS_SENTXOFF_; + } + + + // skip the stop bit + if (!fullbuffer) tunedDelay(_rx_delay_stopbit); + + if(keepThisChar(&d)) + { + cb.write(d); + if(firstByte) + { + firstByte=false; + thisHead=cb.getTail(); + } + } + + + // This part is new. It is used to detect the end of a "paragraph" + // Caveat: the old fashion would let processor a bit of time between bytes, + // that here is lost + // This active waiting avoids drifting + morebytes=false; + // TO-DO. This PARAGRAPHGUARD is empyric. We should test it for every speed + for(i=0;i<__PARAGRAPHGUARD__;i++) + { + tunedDelay(1); + if(!rx_pin_read()) + { + morebytes=true; + break; + } + } + }while(morebytes); + // If we find a line feed, we are at the end of a paragraph + // check! + + if (fullbuffer) + { + // And... go handle it! + if(mgr) + mgr->manageMsg(thisHead, cb.getTail()); + } + else if(d==10) + { + // And... go handle it! + if(mgr) + mgr->manageMsg(thisHead, cb.getTail()); + } + else if (d==32) + { + // And... go handle it! + if(mgr) + mgr->manageMsg(thisHead, cb.getTail()); + } + } + +#if GCC_VERSION < 40302 +// Work-around for avr-gcc 4.3.0 OSX version bug +// Restore the registers that the compiler misses + asm volatile( + "pop r27 \n\t" + "pop r26 \n\t" + "pop r23 \n\t" + "pop r22 \n\t" + "pop r21 \n\t" + "pop r20 \n\t" + "pop r19 \n\t" + "pop r18 \n\t" + ::); +#endif +} + +bool GSM3SoftSerial::keepThisChar(uint8_t* c) +{ + // Horrible things for Quectel XON/XOFF + // 255 is the answer to a XOFF + // It comes just once + if((*c==255)&&(_flags & _GSMSOFTSERIALFLAGS_SENTXOFF_)) + { + _flags ^= _GSMSOFTSERIALFLAGS_SENTXOFF_; + return false; + } + + // 0x77, w, is the escape character + if(*c==0x77) + { + _flags |= _GSMSOFTSERIALFLAGS_ESCAPED_; + return false; + } + + // and these are the escaped codes + if(_flags & _GSMSOFTSERIALFLAGS_ESCAPED_) + { + if(*c==0xEE) + *c=0x11; + else if(*c==0xEC) + *c=0x13; + else if(*c==0x88) + *c=0x77; + + _flags ^= _GSMSOFTSERIALFLAGS_ESCAPED_; + return true; + } + + return true; +} + +void GSM3SoftSerial::spaceAvailable() +{ + // If there is spaceAvailable in the buffer, lets send a XON + finalWrite((byte)__XON__); +} + + +// This is here to avoid problems with Arduino compiler +void GSM3SoftSerialMgr::manageMsg(byte from, byte to){}; + +//#define PCINT1_vect _VECTOR(2) +//#undef PCINT1_vect + +#if defined(PCINT0_vect) +ISR(PCINT0_vect) +{ + GSM3SoftSerial::handle_interrupt(); +} +#endif + +#if defined(PCINT1_vect) +ISR(PCINT1_vect) +{ + GSM3SoftSerial::handle_interrupt(); +} +#endif + +#if defined(PCINT2_vect) +ISR(PCINT2_vect) +{ + GSM3SoftSerial::handle_interrupt(); +} +#endif + +#if defined(PCINT3_vect) +ISR(PCINT3_vect) +{ + GSM3SoftSerial::handle_interrupt(); +} +#endif + diff --git a/libraries/GSM3/GSM3SoftSerial.h b/libraries/GSM3/GSM3SoftSerial.h new file mode 100644 index 000000000..c35ef6848 --- /dev/null +++ b/libraries/GSM3/GSM3SoftSerial.h @@ -0,0 +1,174 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef __GSM3_SOFTSERIAL__ +#define __GSM3_SOFTSERIAL__ + +// An adaptation of NewSoftSerial for Modem Shields +// Assumes directly that Serial is attached to Pins 2 and 3, not inverse +// We are implementing it because NewSoftSerial does not deal correctly with floods +// of data +#include "GSM3CircularBuffer.h" +#include + +/* +#define _COMSTATUS_ANSWERRECEIVED_ 0x100 +#define _COMSTATUS_SMSRECEIVED_ 0x80 +#define _COMSTATUS_CALLRECEIVED_ 0x40 + +// PLEASE, when accessing the sockets use "for" and >> (bitwise operator) +#define _COMSTATUS_SOCKET6RECEIVED_ 0x20 +#define _COMSTATUS_SOCKET5RECEIVED_ 0x10 +#define _COMSTATUS_SOCKET4RECEIVED_ 0x08 +#define _COMSTATUS_SOCKET3RECEIVED_ 0x04 +#define _COMSTATUS_SOCKET2RECEIVED_ 0x02 +#define _COMSTATUS_SOCKET1RECEIVED_ 0x01 + +#define __CALLTABLEMASK__ 0x3 +*/ + +class GSM3SoftSerialMgr +{ + public: + + /** Manages soft serial message + @param from Initial byte + @param to Final byte + */ + virtual void manageMsg(byte from, byte to); +}; + +// This class manages software serial communications +// Changing it so it doesn't know about modems or whatever + +class GSM3SoftSerial : public GSM3CircularBufferManager +{ + private: + + uint8_t _receiveBitMask; + volatile uint8_t *_receivePortRegister; + uint8_t _transmitBitMask; + volatile uint8_t *_transmitPortRegister; + + static GSM3SoftSerial* _activeObject; + GSM3SoftSerialMgr* mgr; + + uint16_t _rx_delay_centering; + uint16_t _rx_delay_intrabit; + uint16_t _rx_delay_stopbit; + uint16_t _tx_delay; + uint8_t _flags; + + /** Write in tx_pin + @param pin_state Pin state + */ + void tx_pin_write(uint8_t pin_state); + + /** Set transmission + */ + void setTX(); + + /** Set receiver + */ + void setRX(); + + /** Receive + */ + void recv(); + + /** Read from rx_pin + @return receive bit mask + */ + uint8_t rx_pin_read(); + + void setComsReceived(); + + /** Write a character in serial connection, final action after escaping + @param c Character + @return 1 if succesful, 0 if transmission delay = 0 + */ + virtual size_t finalWrite(uint8_t); + + /** Decide, attending to escapes, if the received character should we + kept, forgotten, or changed + @param c Character, may be changed + @return 1 if shall be kept, 0 if forgotten + */ + bool keepThisChar(uint8_t* c); + + // Checks the buffer for well-known events. + //bool recognizeUnsolicitedEvent(byte oldTail); + + public: + + /** Tuned delay in microcontroller + @param delay Time to delay + */ + static /*inline */void tunedDelay(uint16_t delay); + + GSM3CircularBuffer cb; // Circular buffer + + /** Register serial manager + @param manager Serial manager + */ + inline void registerMgr(GSM3SoftSerialMgr* manager){mgr=manager;}; + + /** If there is spaceAvailable in the buffer, lets send a XON + */ + void spaceAvailable(); + + /** Write a character in serial connection + @param c Character + @return 1 if succesful, 0 if transmission delay = 0 + */ + virtual size_t write(uint8_t); + + /** Constructor */ + GSM3SoftSerial(); + + /** Establish serial connection + @param speed Baudrate + @return + */ + int begin(long speed); + + /** Manage interruptions + */ + static inline void handle_interrupt(); + + /** Close serial connection + */ + void close(); +}; + +#endif \ No newline at end of file diff --git a/libraries/GSM3/GSM3VoiceCallService.cpp b/libraries/GSM3/GSM3VoiceCallService.cpp new file mode 100644 index 000000000..fefb0f043 --- /dev/null +++ b/libraries/GSM3/GSM3VoiceCallService.cpp @@ -0,0 +1,144 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#include +#include + +#include +GSM3ShieldV1VoiceProvider theShieldV1VoiceProvider; + +// While there is only a shield (ShieldV1) we will include it by default + +#define GSM3VOICECALLSERVICE_SYNCH 0x01 // 1: synchronous 0: asynchronous +#define __TOUT__ 10000 + + + + +GSM3VoiceCallService::GSM3VoiceCallService(bool synch) +{ + if(synch) + flags |= GSM3VOICECALLSERVICE_SYNCH; + theGSM3MobileVoiceProvider->initialize(); +} + +GSM3_voiceCall_st GSM3VoiceCallService::getvoiceCallStatus() +{ + if(theGSM3MobileVoiceProvider==0) + return IDLE_CALL; + + return theGSM3MobileVoiceProvider->getvoiceCallStatus(); +} + +int GSM3VoiceCallService::ready() +{ + if(theGSM3MobileVoiceProvider==0) + return 0; + + return theGSM3MobileVoiceProvider->ready(); +} + +int GSM3VoiceCallService::voiceCall(const char* to, unsigned long timeout) +{ + if(theGSM3MobileVoiceProvider==0) + return 0; + + if(flags & GSM3VOICECALLSERVICE_SYNCH ) + { + theGSM3MobileVoiceProvider->voiceCall(to); + unsigned long m; + m=millis(); + // Wait an answer for timeout + while(((millis()-m)< timeout )&&(getvoiceCallStatus()==CALLING)) + delay(100); + + if(getvoiceCallStatus()==TALKING) + return 1; + else + return 0; + } + else + { + return theGSM3MobileVoiceProvider->voiceCall(to); + } + +} + +int GSM3VoiceCallService::answerCall() +{ + if(theGSM3MobileVoiceProvider==0) + return 0; + + return waitForAnswerIfNeeded(theGSM3MobileVoiceProvider->answerCall()); +} + +int GSM3VoiceCallService::hangCall() +{ + if(theGSM3MobileVoiceProvider==0) + return 0; + + return waitForAnswerIfNeeded(theGSM3MobileVoiceProvider->hangCall()); +} + +int GSM3VoiceCallService::retrieveCallingNumber(char* buffer, int bufsize) +{ + if(theGSM3MobileVoiceProvider==0) + return 0; + + return waitForAnswerIfNeeded(theGSM3MobileVoiceProvider->retrieveCallingNumber(buffer, bufsize)); +} + +int GSM3VoiceCallService::waitForAnswerIfNeeded(int returnvalue) +{ + // If synchronous + if(flags & GSM3VOICECALLSERVICE_SYNCH ) + { + unsigned long m; + m=millis(); + // Wait for __TOUT__ + while(((millis()-m)< __TOUT__ )&&(ready()==0)) + delay(100); + // If everything was OK, return 1 + // else (timeout or error codes) return 0; + if(ready()==1) + return 1; + else + return 0; + } + // If not synchronous just kick ahead the coming result + return ready(); +} + + + + diff --git a/libraries/GSM3/GSM3VoiceCallService.h b/libraries/GSM3/GSM3VoiceCallService.h new file mode 100644 index 000000000..089d5797a --- /dev/null +++ b/libraries/GSM3/GSM3VoiceCallService.h @@ -0,0 +1,102 @@ +/* +This file is part of the GSM3 communications library for Arduino +-- Multi-transport communications platform +-- Fully asynchronous +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 +-- Voice calls +-- SMS +-- TCP/IP connections +-- HTTP basic clients + +This library has been developed by Telefónica Digital - PDI - +- Physical Internet Lab, as part as its collaboration with +Arduino and the Open Hardware Community. + +September-December 2012 + +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 + +The latest version of this library can always be found at +https://github.com/BlueVia/Official-Arduino +*/ +#ifndef _GSM3VOICECALLSERVICE_ +#define _GSM3VOICECALLSERVICE_ + +#include +#include + +class GSM3VoiceCallService +{ + private: + uint8_t flags; + + /** Make synchronous the functions, if needed + @param returnvalue Return value + @return returns 0 if last command is still executing, 1 success, >1 error + */ + int waitForAnswerIfNeeded(int returnvalue); + + public: + /** Service creation + @param synch If true, the service calls are synchronois + */ + GSM3VoiceCallService(bool synch=true); + + /** Voice call status + @return Status of the voice call, as described in GSM3MobileVoiceProvider.h + { IDLE_CALL, CALLING, RECEIVINGCALL, TALKING}; + */ + GSM3_voiceCall_st getvoiceCallStatus(); + + /** Get last command status + @return Returns 0 if last command is still executing, 1 success, >1 error + */ + int ready(); + + /** Place a voice call. If asynchronous, returns while ringing. If synchronous + returns if the call is stablished or cancelled. + @param to Receiver number. Country extension can be used or not. + Char buffer should not be released or used until command is over + @param timeout In millisecods. Time ringing before closing the call. + Only used in synchronous mode. + If zero, ring undefinitely + @return In asynchronous mode returns 0 if last command is still executing, 1 success, >1 error + In synchronous mode returns 1 if the call is placed, 0 if not. + */ + int voiceCall(const char* to, unsigned long timeout=30000); + + /** Accept an incoming voice call + @return In asynchronous mode returns 0 if last command is still executing, 1 success, >1 error + In synchronous mode returns 1 if the call is answered, 0 if not. + */ + int answerCall(); + + /** Hang a stablished call or an incoming ring + @return In asynchronous mode returns 0 if last command is still executing, 1 success, >1 error + In synchronous mode returns 1 if the call is answered, 0 if not. + */ + int hangCall(); + + /** Retrieve the calling number, put it in buffer + @param buffer pointer to the buffer memory + @param bufsize size of available memory area, at least should be 10 characters + @return In asynchronous mode returns 0 if last command is still executing, 1 success, >1 error + In synchronous mode returns 1 if the number is correcty taken 0 if not + */ + int retrieveCallingNumber(char* buffer, int bufsize); +}; + + +#endif \ No newline at end of file diff --git a/libraries/GSM3/License.txt b/libraries/GSM3/License.txt new file mode 100644 index 000000000..fb6d90b9f --- /dev/null +++ b/libraries/GSM3/License.txt @@ -0,0 +1,166 @@ +GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + diff --git a/libraries/GSM3/examples/GSMPachubeClient/GSMPachubeClient.ino b/libraries/GSM3/examples/GSMPachubeClient/GSMPachubeClient.ino new file mode 100644 index 000000000..445aab59e --- /dev/null +++ b/libraries/GSM3/examples/GSMPachubeClient/GSMPachubeClient.ino @@ -0,0 +1,186 @@ +/* + GSM Pachube client + + This sketch connects an analog sensor to Pachube (http://www.pachube.com) + using a Telefonica GSM/GPRS shield. + + This example has been updated to use version 2.0 of the Pachube.com API. + To make it work, create a feed with a datastream, and give it the ID + sensor1. Or change the code below to match your feed. + + Circuit: + * Analog sensor attached to analog in 0 + * GSM shield attached to an Arduino + * SIM card with a data plan + + created 4 March 2012 + by Tom Igoe + and adapted for GSM shield by David Del Peral + + This code is in the public domain. + + http://arduino.cc/en/Tutorial/GSMExamplesPachubeClient + + */ + +// libraries +#include + +// Pachube Client data +#define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here +#define FEEDID 00000 // replace your feed ID +#define USERAGENT "My Project" // user agent is the project name + +// PIN Number +#define PINNUMBER "" + +// APN data +#define GPRS_APN "GPRS_APN" // replace your GPRS APN +#define GPRS_LOGIN "login" // replace with your GPRS login +#define GPRS_PASSWORD "password" // replace with your GPRS password + +// initialize the library instance: +GSMClient client; +GPRS gprs; +GSM gsmAccess; + +// if you don't want to use DNS (and reduce your sketch size) +// use the numeric IP instead of the name for the server: +// IPAddress server(216,52,233,121); // numeric IP for api.pachube.com +char server[] = "api.pachube.com"; // name address for pachube API + +unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds +boolean lastConnected = false; // state of the connection last time through the main loop +const unsigned long postingInterval = 10*1000; //delay between updates to Pachube.com + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // connection state + boolean notConnected = true; + + // After starting the modem with GSM.begin() + // attach the shield to the GPRS network with the APN, login and password + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } +} + +void loop() +{ + // read the analog sensor: + int sensorReading = analogRead(A0); + + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only: + if (client.available()) + { + char c = client.read(); + Serial.print(c); + } + + // if there's no net connection, but there was one last time + // through the loop, then stop the client: + if (!client.connected() && lastConnected) + { + client.stop(); + } + + // if you're not connected, and ten seconds have passed since + // your last connection, then connect again and send data: + if(!client.connected() && ((millis() - lastConnectionTime) > postingInterval)) + { + sendData(sensorReading); + } + + // store the state of the connection for next time through + // the loop: + lastConnected = client.connected(); +} + +/* + This method makes a HTTP connection to the server. +*/ +void sendData(int thisData) +{ + // if there's a successful connection: + if (client.connect(server, 80)) + { + Serial.println("connecting..."); + + // send the HTTP PUT request: + client.print("PUT /v2/feeds/"); + client.print(FEEDID); + client.println(".csv HTTP/1.1"); + client.print("Host: api.pachube.com\n"); + client.print("X-ApiKey: "); + client.println(APIKEY); + client.print("User-Agent: "); + client.println(USERAGENT); + client.print("Content-Length: "); + + // calculate the length of the sensor reading in bytes: + // 8 bytes for "sensor1," + number of digits of the data: + int thisLength = 8 + getLength(thisData); + client.println(thisLength); + + // last pieces of the HTTP PUT request: + client.print("Content-Type: text/csv\n"); + client.println("Connection: close"); + client.println(); + + // here's the actual content of the PUT request: + client.print("sensor1,"); + client.println(thisData); + } + else + { + // if you couldn't make a connection: + Serial.println("connection failed"); + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + } + // note the time that the connection was made or attempted + lastConnectionTime = millis(); +} + +/* + This method calculates the number of digits in the + sensor reading. Since each digit of the ASCII decimal + representation is a byte, the number of digits equals + the number of bytes. +*/ +int getLength(int someValue) +{ + // there's at least one byte: + int digits = 1; + + // continually divide the value by ten, + // adding one to the digit count for each + // time you divide, until you're at 0: + int dividend = someValue /10; + while (dividend > 0) + { + dividend = dividend /10; + digits++; + } + + // return the number of digits: + return digits; +} + diff --git a/libraries/GSM3/examples/GSMPachubeClientString/GSMPachubeClientString.ino b/libraries/GSM3/examples/GSMPachubeClientString/GSMPachubeClientString.ino new file mode 100644 index 000000000..f28370e42 --- /dev/null +++ b/libraries/GSM3/examples/GSMPachubeClientString/GSMPachubeClientString.ino @@ -0,0 +1,167 @@ +/* + Pachube client with Strings + + This sketch connects two analog sensors to Pachube (http://www.pachube.com) + through a Telefonica GSM/GPRS shield. + + This example has been updated to use version 2.0 of the Pachube.com API. + To make it work, create a feed with two datastreams, and give them the IDs + sensor1 and sensor2. Or change the code below to match your feed. + + This example uses the String library, which is part of the Arduino core from + version 0019. + + Circuit: + * Analog sensors attached to A0 and A1 + * GSM shield attached to an Arduino + * SIM card with a data plan + + created 8 March 2012 + by Tom Igoe + and adapted for GSM shield by David Del Peral + + This code is in the public domain. + + */ + +// Include the GSM library +#include + +// Pachube login information +#define APIKEY "YOUR API KEY GOES HERE" // replace your pachube api key here +#define FEEDID 00000 // replace your feed ID +#define USERAGENT "My Project" // user agent is the project name + +// PIN Number +#define PINNUMBER "" + +// APN data +#define GPRS_APN "GPRS_APN" // replace your GPRS APN +#define GPRS_LOGIN "login" // replace with your GPRS login +#define GPRS_PASSWORD "password" // replace with your GPRS password + +// initialize the library instance +GSMClient client; +GPRS gprs; +GSM gsmAccess; + +// if you don't want to use DNS (and reduce your sketch size) +// use the numeric IP instead of the name for the server: +// IPAddress server(216,52,233,121); // numeric IP for api.pachube.com +char server[] = "api.pachube.com"; // name address for Pachube API + +unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds +boolean lastConnected = false; // state of the connection last time through the main loop +const unsigned long postingInterval = 10*1000; // delay between updates to Pachube.com + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // connection state + boolean notConnected = true; + + // After starting the modem with GSM.begin() + // attach the shield to the GPRS network with the APN, login and password + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("Connected to GPRS network"); +} + +void loop() +{ + // read the sensor on A0 + int sensorReading = analogRead(A0); + + // convert the data to a String + String dataString = "sensor1,"; + dataString += sensorReading; + + // you can append multiple readings to this String to + // send the pachube feed multiple values + int otherSensorReading = analogRead(A1); + dataString += "\nsensor2,"; + dataString += otherSensorReading; + + // if there's incoming data from the net connection. + // send it out the serial port. This is for debugging + // purposes only + if (client.available()) + { + char c = client.read(); + Serial.print(c); + } + + // if there's no net connection, but there was one last time + // through the loop, then stop the client + if (!client.connected() && lastConnected) + { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + } + + // if you're not connected, and ten seconds have passed since + // your last connection, then connect again and send data + if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) + { + sendData(dataString); + } + // store the state of the connection for next time through + // the loop + lastConnected = client.connected(); +} + +// this method makes a HTTP connection to the server +void sendData(String thisData) +{ + // if there's a successful connection: + if (client.connect(server, 80)) + { + Serial.println("connecting..."); + + // send the HTTP PUT request: + client.print("PUT /v2/feeds/"); + client.print(FEEDID); + client.println(".csv HTTP/1.1"); + client.print("Host: api.pachube.com\n"); + client.print("X-ApiKey: "); + client.println(APIKEY); + client.print("User-Agent: "); + client.println(USERAGENT); + client.print("Content-Length: "); + client.println(thisData.length()); + + // last pieces of the HTTP PUT request + client.print("Content-Type: text/csv\n"); + client.println("Connection: close\n"); + client.println(); + + // here's the actual content of the PUT request + client.println(thisData); + } + else + { + // if you couldn't make a connection + Serial.println("connection failed"); + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + } + // note the time that the connection was made or attempted: + lastConnectionTime = millis(); +} diff --git a/libraries/GSM3/examples/GsmTwitterClient/GsmTwitterClient.ino b/libraries/GSM3/examples/GsmTwitterClient/GsmTwitterClient.ino new file mode 100644 index 000000000..30321417e --- /dev/null +++ b/libraries/GSM3/examples/GsmTwitterClient/GsmTwitterClient.ino @@ -0,0 +1,162 @@ +/* + GSM Twitter Client with Strings + + This sketch connects to Twitter using an Arduino GSM shield. + It parses the XML returned, and looks for the string this is a tweet + + This example uses the String library, which is part of the Arduino core from + version 0019. + + Circuit: + * GSM shield attached to an Arduino + * SIM card with a data plan + + created 8 Mar 2012 + by Tom Igoe + + http://arduino.cc/en/Tutorial/GSMExamplesTwitterClient + + This code is in the public domain. + + */ + +// libraries +#include + +// PIN Number +#define PINNUMBER "" + +// APN data +#define GPRS_APN "APN" // replace your GPRS APN +#define GPRS_LOGIN "LOGIN" // replace with your GPRS login +#define GPRS_PASSWORD "PASSWORD" // replace with your GPRS password + +// initialize the library instance +GSMClient client; +GPRS gprs; +GSM gsmAccess; + +const unsigned long requestInterval = 30*1000; // delay between requests: 30 seconds + +// API Twitter URL +char server[] = "api.twitter.com"; + +boolean requested; // whether you've made a request since connecting +unsigned long lastAttemptTime = 0; // last time you connected to the server, in milliseconds + +String currentLine = ""; // string to hold the text from server +String tweet = ""; // string to hold the tweet +boolean readingTweet = false; // if you're currently reading the tweet + +void setup() +{ + // reserve space for the strings: + currentLine.reserve(256); + tweet.reserve(150); + + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // connection state + boolean notConnected = true; + + // After starting the modem with GSM.begin() + // attach the shield to the GPRS network with the APN, login and password + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("Connected to GPRS network"); + + Serial.println("connecting..."); + connectToServer(); +} + + + +void loop() +{ + char c; + if (client.connected()) + { + if (client.available()) + { + // read incoming bytes: + char inChar = client.read(); + + // add incoming byte to end of line: + currentLine += inChar; + + // if you get a newline, clear the line: + if (inChar == '\n') + { + currentLine = ""; + } + + // if the current line ends with , it will + // be followed by the tweet: + if (currentLine.endsWith("")) + { + // tweet is beginning. Clear the tweet string: + readingTweet = true; + tweet = ""; + } + + // if you're currently reading the bytes of a tweet, + // add them to the tweet String: + if (readingTweet) + { + if (inChar != '<') + { + tweet += inChar; + } + else + { + // if you got a "<" character, + // you've reached the end of the tweet: + readingTweet = false; + Serial.println(tweet); + + // close the connection to the server: + client.stop(); + } + } + } + } + else if (millis() - lastAttemptTime > requestInterval) + { + // if you're not connected, and two minutes have passed since + // your last connection, then attempt to connect again: + connectToServer(); + } +} + +/* + Connect to API Twitter server and do a request for timeline +*/ +void connectToServer() +{ + // attempt to connect, and wait a millisecond: + Serial.println("connecting to server..."); + if (client.connect(server, 80)) + { + Serial.println("making HTTP request..."); + // make HTTP GET request to twitter: + client.println("GET /1/statuses/user_timeline.xml?screen_name=arduino&count=1 HTTP/1.1"); + client.println("HOST: api.twitter.com"); + client.println(); + } + // note the time of this connect attempt: + lastAttemptTime = millis(); +} diff --git a/libraries/GSM3/examples/GsmWebClient/GsmWebClient.ino b/libraries/GSM3/examples/GsmWebClient/GsmWebClient.ino new file mode 100644 index 000000000..8a9636792 --- /dev/null +++ b/libraries/GSM3/examples/GsmWebClient/GsmWebClient.ino @@ -0,0 +1,106 @@ +/* + Web client + + This sketch connects to a website through a GSM shield. Specifically, + this example downloads the URL "http://arduino.cc/" and prints it + to the Serial monitor. + + Circuit: + * GSM shield attached to an Arduino + * SIM card with a data plan + + created 8 Mar 2012 + by Tom Igoe + + http://arduino.cc/en/Tutorial/GSMExamplesWebClient + + */ + +// libraries +#include + +// PIN Number +#define PINNUMBER "" + +// APN data +#define GPRS_APN "GPRS_APN" // replace your GPRS APN +#define GPRS_LOGIN "login" // replace with your GPRS login +#define GPRS_PASSWORD "password" // replace with your GPRS password + +// initialize the library instance +GSMClient client; +GPRS gprs; +GSM gsmAccess; + +// URL, path & port (for example: arduino.cc) +char server[] = "arduino.cc"; +char path[] = "/"; +int port = 80; // port 80 is the default for HTTP + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("Starting Arduino web client."); + // connection state + boolean notConnected = true; + + // After starting the modem with GSM.begin() + // attach the shield to the GPRS network with the APN, login and password + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("connecting..."); + + // if you get a connection, report back via serial: + if (client.connect(server, port)) + { + Serial.println("connected"); + // Make a HTTP request: + client.print("GET "); + client.print(path); + client.println(" HTTP/1.0"); + client.println(); + } + else + { + // if you didn't get a connection to the server: + Serial.println("connection failed"); + } +} + +void loop() +{ + // if there are incoming bytes available + // from the server, read them and print them: + if (client.available()) + { + char c = client.read(); + Serial.print(c); + } + + // if the server's disconnected, stop the client: + if (!client.available() && !client.connected()) + { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + + // do nothing forevermore: + for(;;) + ; + } +} diff --git a/libraries/GSM3/examples/GsmWebServer/GsmWebServer.ino b/libraries/GSM3/examples/GsmWebServer/GsmWebServer.ino new file mode 100644 index 000000000..e957b4cf8 --- /dev/null +++ b/libraries/GSM3/examples/GsmWebServer/GsmWebServer.ino @@ -0,0 +1,118 @@ +/* + GSM Web Server + + A simple web server that shows the value of the analog input pins. + using a GSM shield. + + Circuit: + * GSM shield attached + * Analog inputs attached to pins A0 through A5 (optional) + + created 8 Mar 2012 + by Tom Igoe + */ + +// libraries +#include + +// PIN Number +#define PINNUMBER "" + +// APN data +#define GPRS_APN "GPRS_APN" // replace your GPRS APN +#define GPRS_LOGIN "login" // replace with your GPRS login +#define GPRS_PASSWORD "password" // replace with your GPRS password + + +// initialize the library instance +GPRS gprs; +GSM gsmAccess; // include a 'true' parameter for debug enabled +GSMServer server(80); // port 80 (http default) + +// timeout +const unsigned long __TIMEOUT__ = 10*1000; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // connection state + boolean notConnected = true; + + // Start GSM shield + // If your SIM has PIN, pass it as a parameter of begin() in quotes + while(notConnected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("Connected to GPRS network"); + + // start server + server.begin(); + + //Get IP. + IPAddress LocalIP = gprs.getIPAddress(); + Serial.println("Server IP address="); + Serial.println(LocalIP); +} + +void loop() { + + + // listen for incoming clients + GSMClient client = server.available(); + + + + if (client) + { + while (client.connected()) + { + if (client.available()) + { + Serial.println("Receiving request!"); + bool sendResponse = false; + while(char c=client.read()) { + if (c == '\n') sendResponse = true; + } + + // if you've gotten to the end of the line (received a newline + // character) + if (sendResponse) + { + // send a standard http response header + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println(); + client.println(""); + // output the value of each analog input pin + for (int analogChannel = 0; analogChannel < 6; analogChannel++) { + client.print("analog input "); + client.print(analogChannel); + client.print(" is "); + client.print(analogRead(analogChannel)); + client.println("
"); + } + client.println(""); + //necessary delay + delay(1000); + client.stop(); + } + } + } + } +} + + diff --git a/libraries/GSM3/examples/MakeVoiceCall/MakeVoiceCall.ino b/libraries/GSM3/examples/MakeVoiceCall/MakeVoiceCall.ino new file mode 100644 index 000000000..64df44afc --- /dev/null +++ b/libraries/GSM3/examples/MakeVoiceCall/MakeVoiceCall.ino @@ -0,0 +1,116 @@ +/* + Make Voice Call + + This sketch, for the Arduino GSM shield, puts a voice call to + a remote phone number that you enter through the serial monitor. + To make it work, open the serial monitor, and when you see the + READY message, type a phone number. Make sure the serial monitor + is set to send a just newline when you press return. + + Circuit: + * GSM shield + * Voice circuit. + With no voice circuit the call will send nor receive any sound + + + created Mar 2012 + by Javier Zorzano + + This example is in the public domain. + */ + +// libraries +#include + +// PIN Number +#define PINNUMBER "" + +// initialize the library instance +GSM gsmAccess; // include a 'true' parameter for debug enabled +GSMVoiceCall vcs; + +String remoteNumber = ""; // the number you will call +char charbuffer[20]; + +void setup() +{ + + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("Make Voice Call"); + + // connection state + boolean notConnected = true; + + // Start GSM shield + // If your SIM has PIN, pass it as a parameter of begin() in quotes + while(notConnected) + { + if(gsmAccess.begin(PINNUMBER)==GSM_READY) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("GSM initialized."); + Serial.println("Enter phone number to call."); + +} + +void loop() +{ + + // add any incoming characters to the String: + while (Serial.available() > 0) + { + char inChar = Serial.read(); + // if it's a newline, that means you should make the call: + if (inChar == '\n') + { + // make sure the phone number is not too long: + if (remoteNumber.length() < 20) + { + // let the user know you're calling: + Serial.print("Calling to : "); + Serial.println(remoteNumber); + Serial.println(); + + // Call the remote number + remoteNumber.toCharArray(charbuffer, 20); + + + // Check if the receiving end has picked up the call + if(vcs.voiceCall(charbuffer)) + { + Serial.println("Call Established. Enter line to end"); + // Wait for some input from the line + while(Serial.read()!='\n' && (vcs.getvoiceCallStatus()==TALKING)); + // And hang up + vcs.hangCall(); + } + Serial.println("Call Finished"); + remoteNumber=""; + Serial.println("Enter phone number to call."); + } + else + { + Serial.println("That's too long for a phone number. I'm forgetting it"); + remoteNumber = ""; + } + } + else + { + // add the latest character to the message to send: + if(inChar!='\r') + remoteNumber += inChar; + } + } +} + diff --git a/libraries/GSM3/examples/ReceiveSMS/ReceiveSMS.ino b/libraries/GSM3/examples/ReceiveSMS/ReceiveSMS.ino new file mode 100644 index 000000000..af800f46f --- /dev/null +++ b/libraries/GSM3/examples/ReceiveSMS/ReceiveSMS.ino @@ -0,0 +1,98 @@ +/* + SMS receiver + + This sketch, for the Arduino GSM shield, waits for a SMS message + and displays it through the Serial port. + + Circuit: + * GSM shield attached to and Arduino + * SIM card that can receive SMS messages + + created 25 Feb 2012 + by Javier Zorzano / TD + + This example is in the public domain. + + http://arduino.cc/en/Tutorial/GSMExamplesReceiveSMS + +*/ + +// include the GSM library +#include + +// PIN Number for the SIM +#define PINNUMBER "" + +// initialize the library instances +GSM gsmAccess; +GSM_SMS sms; + +// Array to hold the number a SMS is retreived from +char senderNumber[20]; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("SMS Messages Receiver"); + + // connection state + boolean notConnected = true; + + // Start GSM connection + while(notConnected) + { + if(gsmAccess.begin(PINNUMBER)==GSM_READY) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("GSM initialized"); + Serial.println("Waiting for messages"); +} + +void loop() +{ + char c; + + // If there are any SMSs available() + if (sms.available()) + { + Serial.println("Message received from:"); + + // Get remote number + sms.remoteNumber(senderNumber, 20); + Serial.println(senderNumber); + + // An example of message disposal + // Any messages starting with # should be discarded + if(sms.peek()=='#') + { + Serial.println("Discarded SMS"); + sms.flush(); + } + + // Read message bytes and print them + while(c=sms.read()) + Serial.print(c); + + Serial.println("\nEND OF MESSAGE"); + + // Delete message from modem memory + sms.flush(); + Serial.println("MESSAGE DELETED"); + } + + delay(1000); + +} + + diff --git a/libraries/GSM3/examples/ReceiveVoiceCall/ReceiveVoiceCall.ino b/libraries/GSM3/examples/ReceiveVoiceCall/ReceiveVoiceCall.ino new file mode 100644 index 000000000..14dbc5ee1 --- /dev/null +++ b/libraries/GSM3/examples/ReceiveVoiceCall/ReceiveVoiceCall.ino @@ -0,0 +1,105 @@ +/* + Receive Voice Call + + This sketch, for the Arduino GSM shield, receives voice calls, + displays the calling number, waits a few seconds then hangs up. + + Circuit: + * GSM shield + * Voice circuit. Refer to to the GSM shield getting started guide + at http://arduino.cc/en/Guide/ArduinoGSMShield#toc11 + * SIM card that can accept voice calls + + With no voice circuit the call will connect, but will not send or receive sound + + created Mar 2012 + by Javier Zorzano + + This example is in the public domain. + + http://arduino.cc/en/Tutorial/GSMExamplesReceiveVoiceCall + + */ + +// Include the GSM library +#include + +// PIN Number +#define PINNUMBER "" + +// initialize the library instance +GSM gsmAccess; +GSMVoiceCall vcs; + +// Array to hold the number for the incoming call +char numtel[20]; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("Receive Voice Call"); + + // connection state + boolean notConnected = true; + + // Start GSM shield + // If your SIM has PIN, pass it as a parameter of begin() in quotes + while(notConnected) + { + if(gsmAccess.begin(PINNUMBER)==GSM_READY) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + // This makes sure the modem correctly reports incoming events + vcs.hangCall(); + + Serial.println("Waiting for a call"); +} + +void loop() +{ + // Check the status of the voice call + switch (vcs.getvoiceCallStatus()) + { + case IDLE_CALL: // Nothing is happening + + break; + + case RECEIVINGCALL: // Yes! Someone is calling us + + Serial.println("RECEIVING CALL"); + + // Retrieve the calling number + vcs.retrieveCallingNumber(numtel, 20); + + // Print the calling number + Serial.print("Number:"); + Serial.println(numtel); + + // Answer the call, establish the call + vcs.answerCall(); + break; + + case TALKING: // In this case the call would be established + + Serial.println("TALKING. Press enter to hang up."); + while(Serial.read()!='\n') + delay(100); + vcs.hangCall(); + Serial.println("Hanging up and waiting for the next call."); + break; + } + delay(1000); +} + + diff --git a/libraries/GSM3/examples/SendSMS/SendSMS.ino b/libraries/GSM3/examples/SendSMS/SendSMS.ino new file mode 100644 index 000000000..677442a93 --- /dev/null +++ b/libraries/GSM3/examples/SendSMS/SendSMS.ino @@ -0,0 +1,110 @@ +/* + SMS sender + + This sketch, for the Arduino GSM shield,sends an SMS message + you enter in the serial monitor. Connect your Arduino with the + GSM shield and SIM card, open the serial monitor, and wait for + the "READY" message to appear in the monitor. Next, type a + message to send and press "return". Make sure the serial + monitor is set to send a newline when you press return. + + Circuit: + * GSM shield + * SIM card that can send SMS + + created 25 Feb 2012 + by Tom Igoe + + This example is in the public domain. + + http://arduino.cc/en/Tutorial/GSMExamplesSendSMS + + */ + +// Include the GSM library +#include + +#define PINNUMBER "" + +// initialize the library instance +GSM gsmAccess; +GSM_SMS sms; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("SMS Messages Sender"); + + // connection state + boolean notConnected = true; + + // Start GSM shield + // If your SIM has PIN, pass it as a parameter of begin() in quotes + while(notConnected) + { + if(gsmAccess.begin(PINNUMBER)==GSM_READY) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("GSM initialized"); +} + +void loop() +{ + + Serial.print("Enter a mobile number: "); + char remoteNum[20]; // telephone number to send sms + readSerial(remoteNum); + Serial.println(remoteNum); + + // sms text + Serial.print("Now, enter SMS content: "); + char txtMsg[200]; + readSerial(txtMsg); + Serial.println("SENDING"); + Serial.println(); + Serial.println("Message:"); + Serial.println(txtMsg); + + // send the message + sms.beginSMS(remoteNum); + sms.print(txtMsg); + sms.endSMS(); + Serial.println("\nCOMPLETE!\n"); +} + +/* + Read input serial + */ +int readSerial(char result[]) +{ + int i = 0; + while(1) + { + while (Serial.available() > 0) + { + char inChar = Serial.read(); + if (inChar == '\n') + { + result[i] = '\0'; + Serial.flush(); + return 0; + } + if(inChar!='\r') + { + result[i] = inChar; + i++; + } + } + } +} diff --git a/libraries/GSM3/examples/Tools/BandManagement/BandManagement.ino b/libraries/GSM3/examples/Tools/BandManagement/BandManagement.ino new file mode 100644 index 000000000..84d8c71c1 --- /dev/null +++ b/libraries/GSM3/examples/Tools/BandManagement/BandManagement.ino @@ -0,0 +1,120 @@ +/* + Band Management + + This sketch, for the Arduino GSM shield, checks the band + currently configured in the modem and allows you to change + it. + + Please check http://www.worldtimezone.com/gsm.html + Usual configurations: + Europe, Africa, Middle East: E-GSM(900)+DCS(1800) + USA, Canada, South America: GSM(850)+PCS(1900) + Mexico: PCS(1900) + Brazil: GSM(850)+E-GSM(900)+DCS(1800)+PCS(1900) + + + Circuit: + * GSM shield + + created 12 June 2012 + by Javier Zorzano, Scott Fitzgerald + + This example is in the public domain. + */ + +// libraries +#include + +// initialize the library instance +GSMBand band; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // Beginning the band manager restarts the modem + Serial.println("Restarting modem..."); + band.begin(); + Serial.println("Modem restarted."); + +}; + + +void loop() +{ + // Get current band + String bandName = band.getBand(); // Get and print band name + Serial.print("Current band:"); + Serial.println(bandName); + Serial.println("Want to change the band you’re on?"); + String newBandName; + newBandName = askUser(); + // Tell the user what we are about to do… + Serial.print("\nConfiguring band "); + Serial.println(newBandName); + // Change the band + boolean operationSuccess; + operationSuccess = band.setBand(newBandName); + // Tell the user if the operation was OK + if(operationSuccess) + { + Serial.println("Success"); + } + else + { + Serial.println("Error while changing band"); + } + + if(operationSuccess) + { + while(true); + } +} + +// This function offers the user different options +// through the Serial interface +// The user selects one +String askUser() +{ + String newBand; + Serial.println("Select band:"); + // Print the different options + Serial.println("1 : E-GSM(900)"); + Serial.println("2 : DCS(1800)"); + Serial.println("3 : PCS(1900)"); + Serial.println("4 : E-GSM(900)+DCS(1800) ex: Europe"); + Serial.println("5 : GSM(850)+PCS(1900) Ex: USA, South Am."); + Serial.println("6 : GSM(850)+E-GSM(900)+DCS(1800)+PCS(1900)"); + + // Empty the incoming buffer + while(Serial.available()) + Serial.read(); + + // Wait for an answer, just look at the first character + while(!Serial.available()); + char c= Serial.read(); + if(c=='1') + newBand=GSM_MODE_EGSM; + else if(c=='2') + newBand=GSM_MODE_DCS; + else if(c=='3') + newBand=GSM_MODE_PCS; + else if(c=='4') + newBand=GSM_MODE_EGSM_DCS; + else if(c=='5') + newBand=GSM_MODE_GSM850_PCS; + else if(c=='6') + newBand=GSM_MODE_GSM850_EGSM_DCS_PCS; + else + newBand="GSM_MODE_UNDEFINED"; + return newBand; +} + + + + + diff --git a/libraries/GSM3/examples/Tools/GsmScanNetworks/GsmScanNetworks.ino b/libraries/GSM3/examples/Tools/GsmScanNetworks/GsmScanNetworks.ino new file mode 100644 index 000000000..0e442eb7b --- /dev/null +++ b/libraries/GSM3/examples/Tools/GsmScanNetworks/GsmScanNetworks.ino @@ -0,0 +1,95 @@ +/* + + GSM Scan Networks + + This example prints out the IMEI number of the modem, + then checks to see if it's connected to a carrier. If so, + it prints the phone number associated with the card. + Then it scans for nearby networks and prints out their signal strengths. + + Circuit: + * GSM shield + * SIM card + + Created 8 Mar 2012 + by Tom Igoe, implemented by Javier Carazo + Modified 4 Feb 2013 + by Scott Fitzgerald + + http://arduino.cc/en/Tutorial/GSMToolsGsmScanNetworks + + This example code is part of the public domain + */ + +// libraries +#include + +// PIN Number +#define PINNUMBER "" + +// initialize the library instance +GSM gsmAccess; // include a 'true' parameter to enable debugging +GSMScanner scannerNetworks; +GSMModem modemTest; + +// Save data variables +String IMEI = ""; + +// serial monitor result messages +String errortext = "ERROR"; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("GSM networks scanner"); + scannerNetworks.begin(); + + // connection state + boolean notConnected = true; + + // Start GSM shield + // If your SIM has PIN, pass it as a parameter of begin() in quotes + while(notConnected) + { + if(gsmAccess.begin(PINNUMBER)==GSM_READY) + notConnected = false; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + // get modem parameters + // IMEI, modem unique identifier + Serial.print("Modem IMEI: "); + IMEI = modemTest.getIMEI(); + IMEI.replace("\n",""); + if(IMEI != NULL) + Serial.println(IMEI); +} + +void loop() +{ + // scan for existing networks, displays a list of networks + Serial.println("Scanning available networks. May take some seconds."); + Serial.println(scannerNetworks.readNetworks()); + + // currently connected carrier + Serial.print("Current carrier: "); + Serial.println(scannerNetworks.getCurrentCarrier()); + + // returns strength and ber + // signal strength in 0-31 scale. 31 means power > 51dBm + // BER is the Bit Error Rate. 0-7 scale. 99=not detectable + Serial.print("Signal Strength: "); + Serial.print(scannerNetworks.getSignalStrength()); + Serial.println(" [0-31]"); + +} + diff --git a/libraries/GSM3/examples/Tools/PinManagement/PinManagement.ino b/libraries/GSM3/examples/Tools/PinManagement/PinManagement.ino new file mode 100644 index 000000000..654d1b839 --- /dev/null +++ b/libraries/GSM3/examples/Tools/PinManagement/PinManagement.ino @@ -0,0 +1,168 @@ +/* + + This example enables you to change or remove the PIN number of + a SIM card inserted into a GSM shield. + + Circuit: + * GSM shield + * SIM card + + Created 12 Jun 2012 + by David del Peral + + This example code is part of the public domain + + http://arduino.cc/en/Tutorial/GSMToolsPinManagement + + */ + +// libraries +#include + +// pin manager object +GSMPIN PINManager; + +// save input in serial by user +String user_input = ""; + +// authenticated with PIN code +boolean auth = false; + +// serial monitor result messages +String oktext = "OK"; +String errortext = "ERROR"; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("Change PIN example\n"); + PINManager.begin(); + + // check if the SIM have pin lock + while(!auth){ + int pin_query = PINManager.isPIN(); + if(pin_query == 1) + { + // if SIM is locked, enter PIN code + Serial.print("Enter PIN code: "); + user_input = readSerial(); + // check PIN code + if(PINManager.checkPIN(user_input) == 0) + { + auth = true; + PINManager.setPINUsed(true); + Serial.println(oktext); + } + else + { + // if PIN code was incorrected + Serial.println("Incorrect PIN. Remember that you have 3 opportunities."); + } + } + else if(pin_query == -1) + { + // PIN code is locked, user must enter PUK code + Serial.println("PIN locked. Enter PUK code: "); + String puk = readSerial(); + Serial.print("Now, enter a new PIN code: "); + user_input = readSerial(); + // check PUK code + if(PINManager.checkPUK(puk, user_input) == 0) + { + auth = true; + PINManager.setPINUsed(true); + Serial.println(oktext); + } + else + { + // if PUK o the new PIN are incorrect + Serial.println("Incorrect PUK or invalid new PIN. Try again!."); + } + } + else if(pin_query == -2) + { + // the worst case, PIN and PUK are locked + Serial.println("PIN & PUK locked. Use PIN2/PUK2 in a mobile phone."); + while(true); + } + else + { + // SIM does not requires authetication + Serial.println("No pin necessary."); + auth = true; + } + } + + // start GSM shield + Serial.print("Checking register in GSM network..."); + if(PINManager.checkReg() == 0) + Serial.println(oktext); + // if you are connect by roaming + else if(PINManager.checkReg() == 1) + Serial.println("ROAMING " + oktext); + else + { + // error connection + Serial.println(errortext); + while(true); + } +} + +void loop() +{ + // Function loop implements pin management user menu + // Only if you SIM use pin lock, you can change PIN code + // user_op variables save user option + + Serial.println("Choose an option:\n1 - On/Off PIN."); + if(PINManager.getPINUsed()) + Serial.println("2 - Change PIN."); + String user_op = readSerial(); + if(user_op == "1") + { + Serial.println("Enter your PIN code:"); + user_input = readSerial(); + // activate/deactivate PIN lock + PINManager.switchPIN(user_input); + } + else if(user_op == "2" & PINManager.getPINUsed()) + { + Serial.println("Enter your actual PIN code:"); + String oldPIN = readSerial(); + Serial.println("Now, enter your new PIN code:"); + String newPIN = readSerial(); + // change PIN + PINManager.changePIN(oldPIN, newPIN); + } + else + { + Serial.println("Incorrect option. Try again!."); + } + delay(1000); +} + +/* + Read input serial + */ +String readSerial() +{ + String text = ""; + while(1) + { + while (Serial.available() > 0) + { + char inChar = Serial.read(); + if (inChar == '\n') + { + return text; + } + if(inChar!='\r') + text += inChar; + } + } +} diff --git a/libraries/GSM3/examples/Tools/TestGPRS/TestGPRS.ino b/libraries/GSM3/examples/Tools/TestGPRS/TestGPRS.ino new file mode 100644 index 000000000..ab4a2bed1 --- /dev/null +++ b/libraries/GSM3/examples/Tools/TestGPRS/TestGPRS.ino @@ -0,0 +1,204 @@ +/* + + This sketch test the GSM shield's ability to connect to a + GPERS network. It asks for APN information through the + serial monitor and tries to connect to arduino.cc. + + Circuit: + * GSM shield attached + * SIM card with data plan + + Created 18 Jun 2012 + by David del Peral + + This example code is part of the public domain + + http://arduino.cc/en/Tutorial/GSMToolsTestGPRS + + */ + +// libraries +#include + +// PIN Number +#define PINNUMBER "" + +// initialize the library instance +GSM gsmAccess; // GSM access: include a 'true' parameter for debug enabled +GPRS gprsAccess; // GPRS access +GSMClient client; // Client service for TCP connection + +// messages for serial monitor response +String oktext = "OK"; +String errortext = "ERROR"; + +// URL and path (for example: arduino.cc) +char url[] = "arduino.cc"; +char urlproxy[] = "http://arduino.cc"; +char path[] = "/"; + +// variable for save response obtained +String response = ""; + +// use a proxy +boolean use_proxy = false; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } +} + +void loop() +{ + use_proxy = false; + + // start GSM shield + // if your SIM has PIN, pass it as a parameter of begin() in quotes + Serial.print("Connecting GSM network..."); + if(gsmAccess.begin(PINNUMBER)!=GSM_READY) + { + Serial.println(errortext); + while(true); + } + Serial.println(oktext); + + // read APN introduced by user + char apn[50]; + Serial.print("Enter your APN: "); + readSerial(apn); + Serial.println(apn); + + // Read APN login introduced by user + char login[50]; + Serial.print("Now, enter your login: "); + readSerial(login); + Serial.println(login); + + // read APN password introduced by user + char password[20]; + Serial.print("Finally, enter your password: "); + readSerial(password); + + // attach GPRS + Serial.println("Attaching to GPRS with your APN..."); + if(gprsAccess.attachGPRS(apn, login, password)!=GPRS_READY) + { + Serial.println(errortext); + } + else{ + + Serial.println(oktext); + + // read proxy introduced by user + char proxy[100]; + Serial.print("If your carrier uses a proxy, enter it, if not press enter: "); + readSerial(proxy); + Serial.println(proxy); + + // if user introduced a proxy, asks him for proxy port + int pport; + if(proxy[0] != '\0'){ + // read proxy port introduced by user + char proxyport[10]; + Serial.print("Enter the proxy port: "); + readSerial(proxyport); + // cast proxy port introduced to integer + pport = (int) proxyport; + use_proxy = true; + Serial.println(proxyport); + } + + // connection with arduino.cc and realize HTTP request + Serial.print("Connecting and sending GET request to arduino.cc..."); + int res_connect; + + // if use a proxy, connect with it + if(use_proxy) + res_connect = client.connect(proxy, pport); + else + res_connect = client.connect(url, 80); + + if (res_connect) + { + // make a HTTP 1.0 GET request (client sends the request) + client.print("GET "); + + // if use a proxy, the path is arduino.cc URL + if(use_proxy) + client.print(urlproxy); + else + client.print(path); + + client.println(" HTTP/1.0"); + client.println(); + Serial.println(oktext); + } + else + { + // if you didn't get a connection to the server + Serial.println(errortext); + } + Serial.print("Receiving response..."); + + boolean test = true; + while(test) + { + // if there are incoming bytes available + // from the server, read and check them + if (client.available()) + { + char c = client.read(); + response += c; + + // cast response obtained from string to char array + char responsechar[response.length()+1]; + response.toCharArray(responsechar, response.length()+1); + + // if response includes a "200 OK" substring + if(strstr(responsechar, "200 OK") != NULL){ + Serial.println(oktext); + Serial.println("TEST COMPLETE!"); + test = false; + } + } + + // if the server's disconnected, stop the client: + if (!client.connected()) + { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + test = false; + } + } + } +} + +/* + Read input serial + */ +int readSerial(char result[]) +{ + int i = 0; + while(1) + { + while (Serial.available() > 0) + { + char inChar = Serial.read(); + if (inChar == '\n') + { + result[i] = '\0'; + return 0; + } + if(inChar!='\r') + { + result[i] = inChar; + i++; + } + } + } +} diff --git a/libraries/GSM3/examples/Tools/TestModem/TestModem.ino b/libraries/GSM3/examples/Tools/TestModem/TestModem.ino new file mode 100644 index 000000000..de61fffaa --- /dev/null +++ b/libraries/GSM3/examples/Tools/TestModem/TestModem.ino @@ -0,0 +1,77 @@ +/* + + This example tests to see if the modem of the + GSM shield is working correctly. You do not need + a SIM card for this example. + + Circuit: + * GSM shield attached + + Created 12 Jun 2012 + by David del Peral + modified 21 Nov 2012 + by Tom Igoe + + http://arduino.cc/en/Tutorial/GSMToolsTestModem + + This sample code is part of the public domain + + */ + +// libraries +#include + +// modem verification object +GSMModem modem; + +// IMEI variable +String IMEI = ""; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // start modem test (reset and check response) + Serial.print("Starting modem test..."); + if(modem.begin()) + Serial.println("modem.begin() succeeded"); + else + Serial.println("ERROR, no modem answer."); +} + +void loop() +{ + // get modem IMEI + Serial.print("Checking IMEI..."); + IMEI = modem.getIMEI(); + + // check IMEI response + if(IMEI != NULL) + { + // show IMEI in serial monitor + Serial.println("Modem's IMEI: " + IMEI); + // reset modem to check booting: + Serial.print("Resetting modem..."); + modem.begin(); + // get and check IMEI one more time + if(modem.getIMEI() != NULL) + { + Serial.println("Modem is functoning properly"); + } + else + { + Serial.println("Error: getIMEI() failed after modem.begin()"); + } + } + else + { + Serial.println("Error: Could not get IMEI"); + } + // do nothing: + while(true); +} + diff --git a/libraries/GSM3/examples/Tools/TestWebServer/TestWebServer.ino b/libraries/GSM3/examples/Tools/TestWebServer/TestWebServer.ino new file mode 100644 index 000000000..5cc3f8af4 --- /dev/null +++ b/libraries/GSM3/examples/Tools/TestWebServer/TestWebServer.ino @@ -0,0 +1,85 @@ +/* + Basic Web Server + + A simple web server that replies with nothing, but prints the client's request + and the server IP address. + + Circuit: + * GSM shield attached + + created + by David Cuartielles + modified 21 Nov 2012 + by Tom Igoe + + http://arduino.cc/en/Tutorial/GSMToolsTestWebServer + + This example code is part of the public domain + */ + #include + +// PIN Number +#define PINNUMBER "" + +// APN data +#define GPRS_APN "GPRS_APN" // replace your GPRS APN +#define GPRS_LOGIN "login" // replace with your GPRS login +#define GPRS_PASSWORD "password" // replace with your GPRS password + + +// initialize the library instance +GPRS gprs; +GSM gsmAccess; // include a 'true' parameter for debug enabled +GSMServer server(80); // port 80 (http default) + +// timeout +const unsigned long __TIMEOUT__ = 10*1000; + +void setup() +{ + // initialize serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + Serial.println("starting,.."); + // connection state + boolean connected = true; + + // Start GSM shield + // If your SIM has PIN, pass it as a parameter of begin() in quotes + while(!connected) + { + if((gsmAccess.begin(PINNUMBER)==GSM_READY) & + (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)) + connected = true; + else + { + Serial.println("Not connected"); + delay(1000); + } + } + + Serial.println("Connected to GPRS network"); + + // start server + server.begin(); + + //Get IP. + IPAddress LocalIP = gprs.getIPAddress(); + Serial.println("Server IP address="); + Serial.println(LocalIP); +} + +void loop(){ + GSMClient client = server.available(); + + if (client) { + if (client.available()) { + Serial.write(client.read()); + } +} + +} + diff --git a/libraries/GSM3/keywords.txt b/libraries/GSM3/keywords.txt new file mode 100644 index 000000000..0662e75bd --- /dev/null +++ b/libraries/GSM3/keywords.txt @@ -0,0 +1,72 @@ +####################################### +# Syntax Coloring Map For GSM +####################################### +# Class +####################################### + +GSM KEYWORD3 +GSMVoiceCall KEYWORD3 +GSM_SMS KEYWORD3 +GPRS KEYWORD3 +GSMClient KEYWORD3 +GSMServer KEYWORD3 +GSMModem KEYWORD3 +GSMScanner KEYWORD3 +GSMPIN KEYWORD3 +GSMBand KEYWORD3 + +####################################### +# Methods and Functions +####################################### + +begin KEYWORD2 +shutdown KEYWORD2 +gatVoiceCallStatus KEYWORD2 +ready KEYWORD2 +voiceCall KEYWORD2 +answerCall KEYWORD2 +hangCall KEYWORD2 +retrieveCallingNumber KEYWORD2 +beginSMS KEYWORD2 +endSMS KEYWORD2 +remoteNumber KEYWORD2 +attachGPRS KEYWORD2 +begnWrite KEYWORD2 +endWrite KEYWORD2 +getIMEI KEYWORD2 +getCurrentCarrier KEYWORD2 +getSignalStrength KEYWORD2 +readNetworks KEYWORD2 +isPIN KEYWORD2 +checkPIN KEYWORD2 +checkPUK KEYWORD2 +changePIN KEYWORD2 +switchPIN KEYWORD2 +checkReg KEYWORD2 +getPINUsed KEYWORD2 +setPINUsed KEYWORD2 +getBand KEYWORD2 +setBand KEYWORD2 +getvoiceCallStatus KEYWORD2 + +####################################### +# Constants +####################################### + +ERROR LITERAL1 +IDLE LITERAL1 +CONNECTING LITERAL1 +GSM_READY LITERAL1 +GPRS_READY LITERAL1 +TRANSPARENT_CONNECTED LITERAL1 +IDLE_CALL LITERAL1 +CALLING LITERAL1 +RECEIVINGCALL LITERAL1 +TALKING LITERAL1 +GSM_MODE_UNDEFINED LITERAL1 +GSM_MODE_EGSM LITERAL1 +GSM_MODE_DCS LITERAL1 +GSM_MODE_PCS LITERAL1 +GSM_MODE_EGSM_DCS LITERAL1 +GSM_MODE_GSM850_PCS LITERAL1 +GSM_MODE_GSM850_EGSM_DCS_PCS LITERAL1 \ No newline at end of file