diff options
Diffstat (limited to 'libraries')
103 files changed, 13906 insertions, 1190 deletions
diff --git a/libraries/GSM/GSM.h b/libraries/GSM/GSM.h new file mode 100644 index 0000000..ec2bf6a --- /dev/null +++ b/libraries/GSM/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 <GSM3CircularBuffer.h> +#include <GSM3MobileCellManagement.h> +#include <GSM3MobileClientService.h> +#include <GSM3MobileNetworkRegistry.h> +#include <GSM3MobileServerService.h> +#include <GSM3ShieldV1AccessProvider.h> +#include <GSM3ShieldV1BandManagement.h> +#include <GSM3ShieldV1ClientProvider.h> +#include <GSM3ShieldV1DataNetworkProvider.h> +#include <GSM3ShieldV1ModemVerification.h> +#include <GSM3ShieldV1PinManagement.h> +#include <GSM3ShieldV1ScanNetworks.h> +#include <GSM3SMSService.h> +#include <GSM3VoiceCallService.h> + +#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/GSM/GSM3CircularBuffer.cpp b/libraries/GSM/GSM3CircularBuffer.cpp new file mode 100644 index 0000000..e64c571 --- /dev/null +++ b/libraries/GSM/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 <HardwareSerial.h>
+
+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<bufsize, b!=((h2) & __BUFFERMASK__); i++, b=(b+1)& __BUFFERMASK__)
+ buffer[i]=theBuffer[b];
+ buffer[i]=0;
+
+//DEBUG
+//Serial.println("");
+//Serial.println("Finishing extractSubstring");
+
+ return true;
+}
+
+int GSM3CircularBuffer::readInt()
+{
+ int res=0;
+ byte c;
+ bool anyfound=false;
+ bool negative=false;
+ for(byte b=head + 1; b!=tail; b=(b+1)& __BUFFERMASK__)
+ {
+ c=theBuffer[b];
+ if((c==' ' )&&(!anyfound))
+ {
+ } else if((c=='-' )&&(!anyfound))
+ {
+ negative=true;
+ anyfound=true; // Don't admit blanks after -
+ } else if((c>='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<bufsize, b!=tail; i++, b=(b+1)& __BUFFERMASK__)
+ {
+ buffer[i]=theBuffer[b];
+ }
+ buffer[i]=0;
+ SizeWritten = i;*/
+ b=head;
+ for(i=0;i<bufsize; i++)
+ {
+ if (b!=tail)
+ {
+ buffer[i]=theBuffer[b];
+ buffer[i+1]=0;
+ b=(b+1)& __BUFFERMASK__;
+ SizeWritten = i + 1;
+ }
+ }
+
+
+ return true;
+}
+
+
+
diff --git a/libraries/GSM/GSM3CircularBuffer.h b/libraries/GSM/GSM3CircularBuffer.h new file mode 100644 index 0000000..b160d09 --- /dev/null +++ b/libraries/GSM/GSM3CircularBuffer.h @@ -0,0 +1,205 @@ +/*
+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_CIRCULARBUFFER__
+#define __GSM3_CIRCULARBUFFER__
+
+
+#include <inttypes.h>
+#include <stddef.h>
+
+#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/GSM/GSM3MobileAccessProvider.cpp b/libraries/GSM/GSM3MobileAccessProvider.cpp new file mode 100644 index 0000000..02d1080 --- /dev/null +++ b/libraries/GSM/GSM3MobileAccessProvider.cpp @@ -0,0 +1,3 @@ +#include <GSM3MobileAccessProvider.h> + +GSM3MobileAccessProvider* theGSM3MobileAccessProvider;
\ No newline at end of file diff --git a/libraries/GSM/GSM3MobileAccessProvider.h b/libraries/GSM/GSM3MobileAccessProvider.h new file mode 100644 index 0000000..21ecd1b --- /dev/null +++ b/libraries/GSM/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/GSM/GSM3MobileCellManagement.cpp b/libraries/GSM/GSM3MobileCellManagement.cpp new file mode 100644 index 0000000..1db20b9 --- /dev/null +++ b/libraries/GSM/GSM3MobileCellManagement.cpp @@ -0,0 +1 @@ +#include <GSM3MobileCellManagement.h>
\ No newline at end of file diff --git a/libraries/GSM/GSM3MobileCellManagement.h b/libraries/GSM/GSM3MobileCellManagement.h new file mode 100644 index 0000000..035dfee --- /dev/null +++ b/libraries/GSM/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 <Arduino.h> + +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/GSM/GSM3MobileClientProvider.cpp b/libraries/GSM/GSM3MobileClientProvider.cpp new file mode 100644 index 0000000..3636a75 --- /dev/null +++ b/libraries/GSM/GSM3MobileClientProvider.cpp @@ -0,0 +1,3 @@ +#include <GSM3MobileClientProvider.h> + +GSM3MobileClientProvider* theGSM3MobileClientProvider;
\ No newline at end of file diff --git a/libraries/GSM/GSM3MobileClientProvider.h b/libraries/GSM/GSM3MobileClientProvider.h new file mode 100644 index 0000000..a771ff4 --- /dev/null +++ b/libraries/GSM/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 <Arduino.h> +#include <IPAddress.h> + +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/GSM/GSM3MobileClientService.cpp b/libraries/GSM/GSM3MobileClientService.cpp new file mode 100644 index 0000000..a913f54 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileClientService.h>
+#include <GSM3MobileClientProvider.h>
+#include <Arduino.h>
+
+// While there is only a shield (ShieldV1) we will include it by default
+#include <GSM3ShieldV1ClientProvider.h>
+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;i<sz;i++)
+ theGSM3MobileClientProvider->writeSocket(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;i<size;i++)
+ {
+ c=read();
+ if(c==0)
+ break;
+ buf[i]=c;
+ }
+
+ return i;
+/* This is the old implementation, testing a simpler one
+ int res;
+ // If we were writing, just stop doing it.
+ if(flags & GSM3MOBILECLIENTSERVICE_WRITING)
+ endWrite(true);
+ res=theGSM3MobileClientProvider->readSocket(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/GSM/GSM3MobileClientService.h b/libraries/GSM/GSM3MobileClientService.h new file mode 100644 index 0000000..5a36a97 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+#include <Client.h>
+
+
+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/GSM/GSM3MobileDataNetworkProvider.cpp b/libraries/GSM/GSM3MobileDataNetworkProvider.cpp new file mode 100644 index 0000000..538f6d4 --- /dev/null +++ b/libraries/GSM/GSM3MobileDataNetworkProvider.cpp @@ -0,0 +1,3 @@ +#include <GSM3MobileDataNetworkProvider.h> + +// GSM3MobileDataNetworkProvider* theGSM3MobileDataNetworkProvider;
\ No newline at end of file diff --git a/libraries/GSM/GSM3MobileDataNetworkProvider.h b/libraries/GSM/GSM3MobileDataNetworkProvider.h new file mode 100644 index 0000000..bffd381 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileAccessProvider.h> + +// 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/GSM/GSM3MobileMockupProvider.cpp b/libraries/GSM/GSM3MobileMockupProvider.cpp new file mode 100644 index 0000000..b39ee26 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+#include <GSM3MobileMockupProvider.h>
+#include <inttypes.h>
+#include <HardwareSerial.h>
+
+
+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<size;i++)
+ Serial.print(buf[i]);
+}
+/* I'm taking this off. We'll reply from the NetworkProvider
+uint8_t GSM3MobileMockupProvider::getStatus(uint8_t socket)
+{
+ if((socket>=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;(i<size)&&(i<l);i++)
+ buf[i]=msgExample[i];
+ buf[i]=0;
+ return i;
+}
+
+int GSM3MobileMockupProvider::availableSocket(int idsocket)
+{
+ return 1;
+};
+
+int GSM3MobileMockupProvider::readSocket(int idsocket, bool advance)
+{
+ char c;
+ if(msgExample[msgIndex]==0)
+ {
+ msgIndex=0;
+ return 0;
+ }
+ else
+ {
+ c=msgExample[msgIndex];
+ if(advance)
+ msgIndex++;
+ };
+ return c;
+};
+
+void GSM3MobileMockupProvider::flushSocket(int idsocket)
+{
+ while(readSocket(idsocket));
+};
+
+int GSM3MobileMockupProvider::disconnectTCP(int idsocket)
+{
+ Serial.println("GSM3MobileMockupProvider::disconnectTCP()");
+ return 1;
+};
+
+int GSM3MobileMockupProvider::connectTCPServer(int port, char* localIP, int* localIPlength)
+{
+ Serial.println("GSM3MobileMockupProvider::connectTCPServer()");
+ if((localIP!=0)&&(*localIPlength>12))
+ strcpy("192.168.1.1", localIP);
+ return 1;
+};
+
+bool GSM3MobileMockupProvider::getSocketModemStatus(uint8_t s)
+{
+ // Feeling lazy
+ return true;
+}
+
diff --git a/libraries/GSM/GSM3MobileMockupProvider.h b/libraries/GSM/GSM3MobileMockupProvider.h new file mode 100644 index 0000000..59eee41 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+#include <GSM3MobileVoiceProvider.h>
+
+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/GSM/GSM3MobileNetworkProvider.cpp b/libraries/GSM/GSM3MobileNetworkProvider.cpp new file mode 100644 index 0000000..a8a91c2 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+#include <HardwareSerial.h>
+
+GSM3MobileNetworkProvider* theProvider;
+
+GSM3MobileNetworkProvider::GSM3MobileNetworkProvider()
+{
+ socketsAsServer=0x0000;
+};
+
+
+int GSM3MobileNetworkProvider::getNewOccupiedSocketAsServer()
+{
+ int i;
+ for(i=minSocketAsServer(); i<=maxSocketAsServer(); i++)
+ {
+ if ((!(socketsAsServer&(0x0001<<i))) && getSocketAsServerModemStatus(i))
+ {
+ socketsAsServer|=((0x0001)<<i);
+ //Serial.print("New occupied=");Serial.println(i);
+ return i;
+ }
+ }
+ //Serial.println("No new occupied");
+ return -1;
+}
+
+
+bool GSM3MobileNetworkProvider::getStatusSocketAsServer(uint8_t socket)
+{
+ if(socketsAsServer&(0x0001<<socket))
+ return 1;
+ else
+ return 0;
+};
+
+
+
+
diff --git a/libraries/GSM/GSM3MobileNetworkProvider.h b/libraries/GSM/GSM3MobileNetworkProvider.h new file mode 100644 index 0000000..7def6ee --- /dev/null +++ b/libraries/GSM/GSM3MobileNetworkProvider.h @@ -0,0 +1,136 @@ +/*
+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 _GSM3MOBILENETWORKPROVIDER_
+#define _GSM3MOBILENETWORKPROVIDER_
+
+#include <GSM3MobileAccessProvider.h>
+#include <inttypes.h>
+#include <stddef.h>
+#include <IPAddress.h>
+
+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/GSM/GSM3MobileNetworkRegistry.cpp b/libraries/GSM/GSM3MobileNetworkRegistry.cpp new file mode 100644 index 0000000..5e22f3a --- /dev/null +++ b/libraries/GSM/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.h>
+
+GSM3MobileNetworkRegistry::GSM3MobileNetworkRegistry()
+{
+ theProvider=0;
+};
+
+void GSM3MobileNetworkRegistry::registerMobileNetworkProvider(GSM3MobileNetworkProvider* provider)
+{
+ theProvider=provider;
+}
+
+GSM3MobileNetworkProvider* GSM3MobileNetworkRegistry::getMobileNetworkProvider()
+{
+ return theProvider;
+}
+
+GSM3MobileNetworkRegistry theMobileNetworkRegistry;
diff --git a/libraries/GSM/GSM3MobileNetworkRegistry.h b/libraries/GSM/GSM3MobileNetworkRegistry.h new file mode 100644 index 0000000..de43977 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+
+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/GSM/GSM3MobileSMSProvider.cpp b/libraries/GSM/GSM3MobileSMSProvider.cpp new file mode 100644 index 0000000..b536330 --- /dev/null +++ b/libraries/GSM/GSM3MobileSMSProvider.cpp @@ -0,0 +1,3 @@ +#include <GSM3MobileSMSProvider.h> + +GSM3MobileSMSProvider* theGSM3SMSProvider; diff --git a/libraries/GSM/GSM3MobileSMSProvider.h b/libraries/GSM/GSM3MobileSMSProvider.h new file mode 100644 index 0000000..aa72711 --- /dev/null +++ b/libraries/GSM/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/GSM/GSM3MobileServerProvider.cpp b/libraries/GSM/GSM3MobileServerProvider.cpp new file mode 100644 index 0000000..4739ac7 --- /dev/null +++ b/libraries/GSM/GSM3MobileServerProvider.cpp @@ -0,0 +1,5 @@ + #include <GSM3MobileServerProvider.h> + + GSM3MobileServerProvider* theGSM3MobileServerProvider; + +
\ No newline at end of file diff --git a/libraries/GSM/GSM3MobileServerProvider.h b/libraries/GSM/GSM3MobileServerProvider.h new file mode 100644 index 0000000..e4eb9c5 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileAccessProvider.h> +#include <inttypes.h> +#include <stddef.h> + + +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/GSM/GSM3MobileServerService.cpp b/libraries/GSM/GSM3MobileServerService.cpp new file mode 100644 index 0000000..bf76cfc --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileServerService.h>
+#include <GSM3MobileServerProvider.h>
+#include <GSM3MobileClientProvider.h>
+
+
+#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.h>
+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/GSM/GSM3MobileServerService.h b/libraries/GSM/GSM3MobileServerService.h new file mode 100644 index 0000000..12165ee --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+#include <GSM3MobileClientService.h>
+#include <Server.h>
+
+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/GSM/GSM3MobileVoiceProvider.cpp b/libraries/GSM/GSM3MobileVoiceProvider.cpp new file mode 100644 index 0000000..7af4e8f --- /dev/null +++ b/libraries/GSM/GSM3MobileVoiceProvider.cpp @@ -0,0 +1,4 @@ +#include <GSM3MobileVoiceProvider.h> + + +GSM3MobileVoiceProvider* theGSM3MobileVoiceProvider; diff --git a/libraries/GSM/GSM3MobileVoiceProvider.h b/libraries/GSM/GSM3MobileVoiceProvider.h new file mode 100644 index 0000000..2091a1b --- /dev/null +++ b/libraries/GSM/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/GSM/GSM3SMSService.cpp b/libraries/GSM/GSM3SMSService.cpp new file mode 100644 index 0000000..378dc2c --- /dev/null +++ b/libraries/GSM/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 <GSM3SMSService.h>
+#include <GSM3MobileNetworkProvider.h>
+#include <Arduino.h>
+
+// While there is only a shield (ShieldV1) we will include it by default
+#include <GSM3ShieldV1SMSProvider.h>
+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/GSM/GSM3SMSService.h b/libraries/GSM/GSM3SMSService.h new file mode 100644 index 0000000..878be11 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileSMSProvider.h>
+#include <Stream.h>
+
+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/GSM/GSM3ShieldV1.cpp b/libraries/GSM/GSM3ShieldV1.cpp new file mode 100644 index 0000000..d594874 --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1.h>
+#include <HardwareSerial.h>
+#include <Arduino.h>
+
+#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/GSM/GSM3ShieldV1.h b/libraries/GSM/GSM3ShieldV1.h new file mode 100644 index 0000000..db52f7b --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+#include <GSM3ShieldV1ModemCore.h>
+#include <GSM3ShieldV1BaseProvider.h>
+#include <Arduino.h>
+
+
+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/GSM/GSM3ShieldV1AccessProvider.cpp b/libraries/GSM/GSM3ShieldV1AccessProvider.cpp new file mode 100644 index 0000000..67ae755 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1AccessProvider.cpp @@ -0,0 +1,296 @@ +#include <GSM3ShieldV1AccessProvider.h> +#include <Arduino.h> + +#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/GSM/GSM3ShieldV1AccessProvider.h b/libraries/GSM/GSM3ShieldV1AccessProvider.h new file mode 100644 index 0000000..1ddcc8c --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileAccessProvider.h> +#include <GSM3ShieldV1ModemCore.h> +#include <GSM3ShieldV1BaseProvider.h> + +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/GSM/GSM3ShieldV1BandManagement.cpp b/libraries/GSM/GSM3ShieldV1BandManagement.cpp new file mode 100644 index 0000000..94dec9a --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1BandManagement.cpp @@ -0,0 +1,67 @@ +#include <GSM3ShieldV1BandManagement.h> + +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/GSM/GSM3ShieldV1BandManagement.h b/libraries/GSM/GSM3ShieldV1BandManagement.h new file mode 100644 index 0000000..919d4ad --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1DirectModemProvider.h> + +#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/GSM/GSM3ShieldV1BaseProvider.cpp b/libraries/GSM/GSM3ShieldV1BaseProvider.cpp new file mode 100644 index 0000000..d63967b --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1BaseProvider.cpp @@ -0,0 +1,27 @@ +#include <GSM3ShieldV1BaseProvider.h> +#include <GSM3ShieldV1ModemCore.h> +#include <Arduino.h> + +// 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/GSM/GSM3ShieldV1BaseProvider.h b/libraries/GSM/GSM3ShieldV1BaseProvider.h new file mode 100644 index 0000000..802d46c --- /dev/null +++ b/libraries/GSM/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 <GSM3SoftSerial.h> + +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/GSM/GSM3ShieldV1CellManagement.cpp b/libraries/GSM/GSM3ShieldV1CellManagement.cpp new file mode 100644 index 0000000..2af91ab --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1CellManagement.cpp @@ -0,0 +1,168 @@ +#include <GSM3ShieldV1CellManagement.h> + +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/GSM/GSM3ShieldV1CellManagement.h b/libraries/GSM/GSM3ShieldV1CellManagement.h new file mode 100644 index 0000000..78307da --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1ModemCore.h> +#include <GSM3MobileCellManagement.h> +#include <GSM3ShieldV1CellManagement.h> + +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/GSM/GSM3ShieldV1ClientProvider.cpp b/libraries/GSM/GSM3ShieldV1ClientProvider.cpp new file mode 100644 index 0000000..92d3e85 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1ClientProvider.cpp @@ -0,0 +1,294 @@ +#include <GSM3ShieldV1ClientProvider.h> +#include <GSM3ShieldV1ModemCore.h> + +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/GSM/GSM3ShieldV1ClientProvider.h b/libraries/GSM/GSM3ShieldV1ClientProvider.h new file mode 100644 index 0000000..fa2f8b5 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileClientProvider.h> +#include <GSM3ShieldV1BaseProvider.h> + +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/GSM/GSM3ShieldV1DataNetworkProvider.cpp b/libraries/GSM/GSM3ShieldV1DataNetworkProvider.cpp new file mode 100644 index 0000000..aaffdba --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1DataNetworkProvider.cpp @@ -0,0 +1,363 @@ +#include <GSM3ShieldV1DataNetworkProvider.h> +#include <Arduino.h> + +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/GSM/GSM3ShieldV1DataNetworkProvider.h b/libraries/GSM/GSM3ShieldV1DataNetworkProvider.h new file mode 100644 index 0000000..012a0ca --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileDataNetworkProvider.h> +#include <GSM3ShieldV1BaseProvider.h> +#include <GSM3ShieldV1ModemCore.h> +#include <IPAddress.h> + +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/GSM/GSM3ShieldV1DirectModemProvider.cpp b/libraries/GSM/GSM3ShieldV1DirectModemProvider.cpp new file mode 100644 index 0000000..47aa52b --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1DirectModemProvider.h> +#include <GSM3ShieldV1ModemCore.h> +#include <HardwareSerial.h> +#include <Arduino.h> + +#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/GSM/GSM3ShieldV1DirectModemProvider.h b/libraries/GSM/GSM3ShieldV1DirectModemProvider.h new file mode 100644 index 0000000..2d20412 --- /dev/null +++ b/libraries/GSM/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 <GSM3SoftSerial.h> +#include <GSM3MobileNetworkProvider.h> +#include <GSM3ShieldV1BaseProvider.h> +#include <Stream.h> +#include <Arduino.h> + +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/GSM/GSM3ShieldV1ModemCore.cpp b/libraries/GSM/GSM3ShieldV1ModemCore.cpp new file mode 100644 index 0000000..c90ff4d --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1ModemCore.cpp @@ -0,0 +1,198 @@ +#include <GSM3ShieldV1ModemCore.h> +#include <Arduino.h> + +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;i<UMPROVIDERS;i++) + UMProvider[i]=0; +} + +void GSM3ShieldV1ModemCore::registerUMProvider(GSM3ShieldV1BaseProvider* provider) +{ + for(int i=0;i<UMPROVIDERS;i++) + { + if(UMProvider[i]==0) + { + UMProvider[i]=provider; + break; + } + + } + +} + +void GSM3ShieldV1ModemCore::unRegisterUMProvider(GSM3ShieldV1BaseProvider* provider) +{ + for(int i=0;i<UMPROVIDERS;i++) + { + if(UMProvider[i]==provider) + { + UMProvider[i]=0; + break; + } + } +} + + +//Response parse. +bool GSM3ShieldV1ModemCore::genericParse_rsp(bool& rsp, char* string, char* string2) +{ + if((string==0) && (string2==0)) + string=__ok__; + + rsp=theBuffer().locate(string); + + if((!rsp)&&(string2!=0)) + rsp=theBuffer().locate(string2); + + return true; +} + +void GSM3ShieldV1ModemCore::closeCommand(int code) +{ + // If we were configuring the modem, + // and there's been an error + // we don't know exactly where we are + if((code!=1)&&(theGSM3ShieldV1ModemCore.getOngoingCommand()==MODEMCONFIG)) + theGSM3ShieldV1ModemCore.setStatus(ERROR); + + setCommandError(code); + ongoingCommand=NONE; + activeProvider=0; + commandCounter=1; +} + +//Generic command (stored in flash). +void GSM3ShieldV1ModemCore::genericCommand_rq(PROGMEM prog_char str[], bool addCR) +{ + theBuffer().flush(); + writePGM(str, addCR); +} + +//Generic command (const string). +void GSM3ShieldV1ModemCore::genericCommand_rqc(const char* str, bool addCR) +{ + theBuffer().flush(); + print(str); + if(addCR) + print("\r"); +} + +// If we are not debugging, lets manage data in interrupt time +// but if we are not, just take note. +void GSM3ShieldV1ModemCore::manageMsg(byte from, byte to) +{ + if(_debug) + { + _dataInBufferFrom=from; + _dataInBufferTo=to; + } + else + { + manageMsgNow(from, to); + } +} + +void GSM3ShieldV1ModemCore::manageReceivedData() +{ + if(_debug) + { +/* Serial.print(theBuffer().getHead()); + Serial.print(" "); + Serial.println(theBuffer().getTail());*/ + if(_dataInBufferFrom != _dataInBufferTo) + { + theBuffer().debugBuffer(); + manageMsgNow(_dataInBufferFrom, _dataInBufferTo); + _dataInBufferFrom=0; + _dataInBufferTo=0; + } + } + else + { + // Just debugging the non debugging +// Serial.println(); +// Serial.print("Com:"); +// Serial.print(ongoingCommand); +// Serial.print(" Step:"); +// Serial.print(commandCounter); + } +} + +//Select between URC or response. +void GSM3ShieldV1ModemCore::manageMsgNow(byte from, byte to) +{ + bool recognized=false; + + for(int i=0;(i<UMPROVIDERS)&&(!recognized);i++) + { + if(UMProvider[i]) + recognized=UMProvider[i]->recognizeUnsolicitedEvent(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<milliseconds;k++) + theGSM3ShieldV1ModemCore.gss.tunedDelay(1000); +} diff --git a/libraries/GSM/GSM3ShieldV1ModemCore.h b/libraries/GSM/GSM3ShieldV1ModemCore.h new file mode 100644 index 0000000..f9efce7 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1ModemCore.h @@ -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 +*/ + +#ifndef __GSM3_SHIELDV1MODEMCORE__ +#define __GSM3_SHIELDV1MODEMCORE__ + +#include <GSM3SoftSerial.h> +#include <GSM3ShieldV1BaseProvider.h> +#include <GSM3MobileAccessProvider.h> +#include <Print.h> + +#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/GSM/GSM3ShieldV1ModemVerification.cpp b/libraries/GSM/GSM3ShieldV1ModemVerification.cpp new file mode 100644 index 0000000..e5d190f --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1ModemVerification.h> + +// 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/GSM/GSM3ShieldV1ModemVerification.h b/libraries/GSM/GSM3ShieldV1ModemVerification.h new file mode 100644 index 0000000..e03980e --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1AccessProvider.h> +#include <GSM3ShieldV1DirectModemProvider.h> + +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/GSM/GSM3ShieldV1MultiClientProvider.cpp b/libraries/GSM/GSM3ShieldV1MultiClientProvider.cpp new file mode 100644 index 0000000..797424f --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1MultiClientProvider.cpp @@ -0,0 +1,583 @@ +#include <GSM3ShieldV1MultiClientProvider.h> +#include <GSM3ShieldV1ModemCore.h> + +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<<i))) + { + sockets|=((0x0001)<<i); + return i; + } + } + } + else + { + if (!(sockets&(0x0001<<socket))) + { + sockets|=((0x0001)<<socket); + return socket; + } + } + return -1; +} + +void GSM3ShieldV1MultiClientProvider::releaseSocket(int socket) +{ + if (sockets&((0x0001)<<socket)) + sockets^=((0x0001)<<socket); +} + +bool GSM3ShieldV1MultiClientProvider::getStatusSocketClient(uint8_t socket) +{ + if(socket>8) + return 0; + if(sockets&(0x0001<<socket)) + return 1; + else + return 0; +}; + + + diff --git a/libraries/GSM/GSM3ShieldV1MultiClientProvider.h b/libraries/GSM/GSM3ShieldV1MultiClientProvider.h new file mode 100644 index 0000000..565a4fc --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1MultiClientProvider.h @@ -0,0 +1,202 @@ +/* +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 <GSM3MobileClientProvider.h> +#include <GSM3ShieldV1BaseProvider.h> + +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/GSM/GSM3ShieldV1MultiServerProvider.cpp b/libraries/GSM/GSM3ShieldV1MultiServerProvider.cpp new file mode 100644 index 0000000..6a915f2 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1MultiServerProvider.cpp @@ -0,0 +1,357 @@ +#include <GSM3ShieldV1MultiServerProvider.h> +#include <GSM3ShieldV1ModemCore.h> +#include <Arduino.h> + +#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<<s)) + return true; + else return false; +} + + +//URC recognize. +bool GSM3ShieldV1MultiServerProvider::recognizeUnsolicitedEvent(byte oldTail) +{ + + int nlength; + char auxLocate [15]; + + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("0, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(0); + socketsAccepted &= ~(0x0001); + //Serial.println("JCR_DB REMOTE CLOSED"); + } + + //REMOTE SOCKET CLOSED. + + prepareAuxLocate(PSTR("1, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(1); + socketsAccepted &= ~(0x0002); + } + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("2, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(2); + socketsAccepted &= ~(0x0004); + } + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("3, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(3); + socketsAccepted &= ~(0x0008); + } + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("4, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(4); + socketsAccepted &= ~(0x0010); + } + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("5, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(5); + socketsAccepted &= ~(0x0020); + } + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("6, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(6); + socketsAccepted &= ~(0x0040); + } + + //REMOTE SOCKET CLOSED. + prepareAuxLocate(PSTR("7, CLOSED\r\n"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + releaseSocket(7); + socketsAccepted &= ~(0x0080); + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("0, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0001); + return true; + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("1, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0002); + return true; + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("2, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0004); + return true; + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("3, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0008); + return true; + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("4, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0010); + return true; + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("5, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0020); + return true; + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("6, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0040); + return true; + } + + //REMOTE SOCKET ACCEPTED. + prepareAuxLocate(PSTR("7, REMOTE IP"), auxLocate); + if(theGSM3ShieldV1ModemCore.gss.cb.locate(auxLocate)) + { + //To detect remote socket closed for example inside socket data. + theGSM3ShieldV1ModemCore.gss.cb.flush(); + socketsAccepted |= (0x0080); + return true; + } + + + return false; +} + +bool GSM3ShieldV1MultiServerProvider::getStatusSocketAsServer(uint8_t socket) +{ + if(socketsAsServer&(0x0001<<socket)) + return 1; + else + return 0; +}; + +void GSM3ShieldV1MultiServerProvider::releaseSocket(int socket) +{ + if (socketsAsServer&((0x0001)<<socket)) + socketsAsServer^=((0x0001)<<socket); +} + +int GSM3ShieldV1MultiServerProvider::getNewOccupiedSocketAsServer() +{ + int i; + ready(); + for(i=minSocketAsServer(); i<=maxSocketAsServer(); i++) + { + if ((!(socketsAsServer&(0x0001<<i))) && getSocketAsServerModemStatus(i)) + { + socketsAsServer|=((0x0001)<<i); + return i; + } + } + // No new occupied + return -1; +} diff --git a/libraries/GSM/GSM3ShieldV1MultiServerProvider.h b/libraries/GSM/GSM3ShieldV1MultiServerProvider.h new file mode 100644 index 0000000..5369334 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1MultiServerProvider.h @@ -0,0 +1,136 @@ +/* +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 <GSM3MobileServerProvider.h> +#include <GSM3ShieldV1BaseProvider.h> + +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/GSM/GSM3ShieldV1PinManagement.cpp b/libraries/GSM/GSM3ShieldV1PinManagement.cpp new file mode 100644 index 0000000..0c0c749 --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1PinManagement.h> + +// 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/GSM/GSM3ShieldV1PinManagement.h b/libraries/GSM/GSM3ShieldV1PinManagement.h new file mode 100644 index 0000000..ce43cdd --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1AccessProvider.h> +#include <GSM3ShieldV1DirectModemProvider.h> + +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/GSM/GSM3ShieldV1SMSProvider.cpp b/libraries/GSM/GSM3ShieldV1SMSProvider.cpp new file mode 100644 index 0000000..9ed075e --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1SMSProvider.cpp @@ -0,0 +1,293 @@ +#include <GSM3ShieldV1SMSProvider.h> +#include <Arduino.h> + +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/GSM/GSM3ShieldV1SMSProvider.h b/libraries/GSM/GSM3ShieldV1SMSProvider.h new file mode 100644 index 0000000..408da33 --- /dev/null +++ b/libraries/GSM/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 <GSM3ShieldV1ModemCore.h> +#include <GSM3MobileSMSProvider.h> +#include <GSM3ShieldV1SMSProvider.h> + + +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/GSM/GSM3ShieldV1ScanNetworks.cpp b/libraries/GSM/GSM3ShieldV1ScanNetworks.cpp new file mode 100644 index 0000000..23da8a6 --- /dev/null +++ b/libraries/GSM/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.h> + +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<modemResponse.length();i++) + { + if(modemResponse[i]=='"') + { + if(!inQuotes) + { + inQuotes=true; + quoteCounter++; + if(quoteCounter==1) + result+="> "; + } + else + { + inQuotes=false; + if(quoteCounter==3) + quoteCounter=0; + if(quoteCounter==1) + result+="\n"; + + } + } + else + { + if(inQuotes&&(quoteCounter==1)) + { + result+=modemResponse[i]; + } + } + } + return result; +} + diff --git a/libraries/GSM/GSM3ShieldV1ScanNetworks.h b/libraries/GSM/GSM3ShieldV1ScanNetworks.h new file mode 100644 index 0000000..f43b164 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1ScanNetworks.h @@ -0,0 +1,75 @@ +/* +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 __GSM3SHIELDV1SCANNETWORKS__ +#define __GSM3SHIELDV1SCANNETWORKS__ + +// This class executes band management functions for the ShieldV1 +#include <GSM3ShieldV1AccessProvider.h> +#include <GSM3ShieldV1DirectModemProvider.h> + +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/GSM/GSM3ShieldV1ServerProvider.cpp b/libraries/GSM/GSM3ShieldV1ServerProvider.cpp new file mode 100644 index 0000000..77f5436 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1ServerProvider.cpp @@ -0,0 +1,205 @@ +#include <GSM3ShieldV1ServerProvider.h> +#include <GSM3ShieldV1ModemCore.h> +#include <Arduino.h> + +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/GSM/GSM3ShieldV1ServerProvider.h b/libraries/GSM/GSM3ShieldV1ServerProvider.h new file mode 100644 index 0000000..93fcd89 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileServerProvider.h> +#include <GSM3ShieldV1BaseProvider.h> + +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/GSM/GSM3ShieldV1VoiceProvider.cpp b/libraries/GSM/GSM3ShieldV1VoiceProvider.cpp new file mode 100644 index 0000000..98a50b9 --- /dev/null +++ b/libraries/GSM/GSM3ShieldV1VoiceProvider.cpp @@ -0,0 +1,215 @@ +#include <GSM3ShieldV1VoiceProvider.h> +#include <Arduino.h> + +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/GSM/GSM3ShieldV1VoiceProvider.h b/libraries/GSM/GSM3ShieldV1VoiceProvider.h new file mode 100644 index 0000000..b961385 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileVoiceProvider.h> +#include <GSM3ShieldV1ModemCore.h> +#include <GSM3ShieldV1BaseProvider.h> + +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/GSM/GSM3SoftSerial.cpp b/libraries/GSM/GSM3SoftSerial.cpp new file mode 100644 index 0000000..176e8cb --- /dev/null +++ b/libraries/GSM/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 <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include "pins_arduino.h"
+#include <HardwareSerial.h>
+#include <Arduino.h>
+
+#if defined(__AVR_ATmega328P__)
+#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; i<sizeof(table)/sizeof(table[0]); ++i)
+ {
+ long baud = pgm_read_dword(&table[i].baud);
+ if (baud == speed)
+ {
+ _rx_delay_centering = pgm_read_word(&table[i].rx_delay_centering);
+ _rx_delay_intrabit = pgm_read_word(&table[i].rx_delay_intrabit);
+ _rx_delay_stopbit = pgm_read_word(&table[i].rx_delay_stopbit);
+ _tx_delay = pgm_read_word(&table[i].tx_delay);
+ break;
+ }
+ }
+
+ if (_rx_delay_stopbit)
+ {
+ if (digitalPinToPCICR(__RXPIN__))
+ {
+ *digitalPinToPCICR(__RXPIN__) |= _BV(digitalPinToPCICRbit(__RXPIN__));
+ *digitalPinToPCMSK(__RXPIN__) |= _BV(digitalPinToPCMSKbit(__RXPIN__));
+ }
+ tunedDelay(_tx_delay); // if we were low this establishes the end
+ }
+
+ _activeObject=this;
+
+}
+
+void GSM3SoftSerial::close()
+ {
+ _activeObject=0;
+ }
+
+size_t GSM3SoftSerial::write(uint8_t c)
+{
+ if (_tx_delay == 0)
+ return 0;
+
+ // Characters to be escaped under XON/XOFF control with Quectel
+ if(c==0x11)
+ {
+ this->finalWrite(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/GSM/GSM3SoftSerial.h b/libraries/GSM/GSM3SoftSerial.h new file mode 100644 index 0000000..c35ef68 --- /dev/null +++ b/libraries/GSM/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 <avr/pgmspace.h>
+
+/*
+#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/GSM/GSM3VoiceCallService.cpp b/libraries/GSM/GSM3VoiceCallService.cpp new file mode 100644 index 0000000..fefb0f0 --- /dev/null +++ b/libraries/GSM/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 <GSM3VoiceCallService.h>
+#include <Arduino.h>
+
+#include <GSM3ShieldV1VoiceProvider.h>
+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/GSM/GSM3VoiceCallService.h b/libraries/GSM/GSM3VoiceCallService.h new file mode 100644 index 0000000..089d579 --- /dev/null +++ b/libraries/GSM/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 <GSM3MobileNetworkProvider.h>
+#include <GSM3MobileVoiceProvider.h>
+
+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/GSM/License.txt b/libraries/GSM/License.txt new file mode 100644 index 0000000..fb6d90b --- /dev/null +++ b/libraries/GSM/License.txt @@ -0,0 +1,166 @@ +GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + 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/GSM/examples/GSMPachubeClient/GSMPachubeClient.ino b/libraries/GSM/examples/GSMPachubeClient/GSMPachubeClient.ino new file mode 100644 index 0000000..445aab5 --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/GSMPachubeClientString/GSMPachubeClientString.ino b/libraries/GSM/examples/GSMPachubeClientString/GSMPachubeClientString.ino new file mode 100644 index 0000000..f28370e --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/GsmTwitterClient/GsmTwitterClient.ino b/libraries/GSM/examples/GsmTwitterClient/GsmTwitterClient.ino new file mode 100644 index 0000000..3032141 --- /dev/null +++ b/libraries/GSM/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 <text>this is a tweet</text> + + 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 <GSM.h> + +// 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 <text>, it will + // be followed by the tweet: + if (currentLine.endsWith("<text>")) + { + // 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/GSM/examples/GsmWebClient/GsmWebClient.ino b/libraries/GSM/examples/GsmWebClient/GsmWebClient.ino new file mode 100644 index 0000000..8a96367 --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/GsmWebServer/GsmWebServer.ino b/libraries/GSM/examples/GsmWebServer/GsmWebServer.ino new file mode 100644 index 0000000..e957b4c --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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("<html>"); + // 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("<br />"); + } + client.println("</html>"); + //necessary delay + delay(1000); + client.stop(); + } + } + } + } +} + + diff --git a/libraries/GSM/examples/MakeVoiceCall/MakeVoiceCall.ino b/libraries/GSM/examples/MakeVoiceCall/MakeVoiceCall.ino new file mode 100644 index 0000000..64df44a --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/ReceiveSMS/ReceiveSMS.ino b/libraries/GSM/examples/ReceiveSMS/ReceiveSMS.ino new file mode 100644 index 0000000..af800f4 --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/ReceiveVoiceCall/ReceiveVoiceCall.ino b/libraries/GSM/examples/ReceiveVoiceCall/ReceiveVoiceCall.ino new file mode 100644 index 0000000..14dbc5e --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/SendSMS/SendSMS.ino b/libraries/GSM/examples/SendSMS/SendSMS.ino new file mode 100644 index 0000000..677442a --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +#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/GSM/examples/Tools/BandManagement/BandManagement.ino b/libraries/GSM/examples/Tools/BandManagement/BandManagement.ino new file mode 100644 index 0000000..84d8c71 --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/Tools/GsmScanNetworks/GsmScanNetworks.ino b/libraries/GSM/examples/Tools/GsmScanNetworks/GsmScanNetworks.ino new file mode 100644 index 0000000..0e442eb --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/Tools/PinManagement/PinManagement.ino b/libraries/GSM/examples/Tools/PinManagement/PinManagement.ino new file mode 100644 index 0000000..654d1b8 --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/Tools/TestGPRS/TestGPRS.ino b/libraries/GSM/examples/Tools/TestGPRS/TestGPRS.ino new file mode 100644 index 0000000..ab4a2be --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/Tools/TestModem/TestModem.ino b/libraries/GSM/examples/Tools/TestModem/TestModem.ino new file mode 100644 index 0000000..de61fff --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/examples/Tools/TestWebServer/TestWebServer.ino b/libraries/GSM/examples/Tools/TestWebServer/TestWebServer.ino new file mode 100644 index 0000000..5cc3f8a --- /dev/null +++ b/libraries/GSM/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 <GSM.h> + +// 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/GSM/keywords.txt b/libraries/GSM/keywords.txt new file mode 100644 index 0000000..0662e75 --- /dev/null +++ b/libraries/GSM/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 diff --git a/libraries/Servo/Servo.cpp b/libraries/Servo/Servo.cpp index a716433..a17ed34 100644 --- a/libraries/Servo/Servo.cpp +++ b/libraries/Servo/Servo.cpp @@ -100,28 +100,28 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t #ifndef WIRING // Wiring pre-defines signal handlers so don't define any if compiling for the Wiring platform
// Interrupt handlers for Arduino
#if defined(_useTimer1)
-SIGNAL (TIMER1_COMPA_vect)
+ISR(TIMER1_COMPA_vect)
{
handle_interrupts(_timer1, &TCNT1, &OCR1A);
}
#endif
#if defined(_useTimer3)
-SIGNAL (TIMER3_COMPA_vect)
+ISR(TIMER3_COMPA_vect)
{
handle_interrupts(_timer3, &TCNT3, &OCR3A);
}
#endif
#if defined(_useTimer4)
-SIGNAL (TIMER4_COMPA_vect)
+ISR(TIMER4_COMPA_vect)
{
handle_interrupts(_timer4, &TCNT4, &OCR4A);
}
#endif
#if defined(_useTimer5)
-SIGNAL (TIMER5_COMPA_vect)
+ISR(TIMER5_COMPA_vect)
{
handle_interrupts(_timer5, &TCNT5, &OCR5A);
}
diff --git a/libraries/WiFi/WiFi.cpp b/libraries/WiFi/WiFi.cpp index c0cb001..f209280 100644 --- a/libraries/WiFi/WiFi.cpp +++ b/libraries/WiFi/WiFi.cpp @@ -8,7 +8,7 @@ extern "C" { } // XXX: don't make assumptions about the value of MAX_SOCK_NUM. -int16_t WiFiClass::_state[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; +int16_t WiFiClass::_state[MAX_SOCK_NUM] = { NA_STATE, NA_STATE, NA_STATE, NA_STATE }; uint16_t WiFiClass::_server_port[MAX_SOCK_NUM] = { 0, 0, 0, 0 }; WiFiClass::WiFiClass() @@ -71,8 +71,7 @@ int WiFiClass::begin(char* ssid, uint8_t key_idx, const char *key) { delay(WL_DELAY_START_CONNECTION); status = WiFiDrv::getConnectionStatus(); - } - while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0)); + }while ((( status == WL_IDLE_STATUS)||(status == WL_SCAN_COMPLETED))&&(--attempts>0)); }else{ status = WL_CONNECT_FAILED; } @@ -99,6 +98,39 @@ int WiFiClass::begin(char* ssid, const char *passphrase) return status; } +void WiFiClass::config(IPAddress local_ip) +{ + WiFiDrv::config(1, (uint32_t)local_ip, 0, 0); +} + +void WiFiClass::config(IPAddress local_ip, IPAddress dns_server) +{ + WiFiDrv::config(1, (uint32_t)local_ip, 0, 0); + WiFiDrv::setDNS(1, (uint32_t)dns_server, 0); +} + +void WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway) +{ + WiFiDrv::config(2, (uint32_t)local_ip, (uint32_t)gateway, 0); + WiFiDrv::setDNS(1, (uint32_t)dns_server, 0); +} + +void WiFiClass::config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) +{ + WiFiDrv::config(3, (uint32_t)local_ip, (uint32_t)gateway, (uint32_t)subnet); + WiFiDrv::setDNS(1, (uint32_t)dns_server, 0); +} + +void WiFiClass::setDNS(IPAddress dns_server1) +{ + WiFiDrv::setDNS(1, (uint32_t)dns_server1, 0); +} + +void WiFiClass::setDNS(IPAddress dns_server1, IPAddress dns_server2) +{ + WiFiDrv::setDNS(2, (uint32_t)dns_server1, (uint32_t)dns_server2); +} + int WiFiClass::disconnect() { return WiFiDrv::disconnect(); diff --git a/libraries/WiFi/WiFi.h b/libraries/WiFi/WiFi.h index 9a86701..ef36a84 100644 --- a/libraries/WiFi/WiFi.h +++ b/libraries/WiFi/WiFi.h @@ -59,6 +59,50 @@ public: */ int begin(char* ssid, const char *passphrase); + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + */ + void config(IPAddress local_ip); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + */ + void config(IPAddress local_ip, IPAddress dns_server); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + * param gateway : Static gateway configuration + */ + void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway); + + /* Change Ip configuration settings disabling the dhcp client + * + * param local_ip: Static ip configuration + * param dns_server: IP configuration for DNS server 1 + * param gateway: Static gateway configuration + * param subnet: Static Subnet mask + */ + void config(IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet); + + /* Change DNS Ip configuration + * + * param dns_server1: ip configuration for DNS server 1 + */ + void setDNS(IPAddress dns_server1); + + /* Change DNS Ip configuration + * + * param dns_server1: ip configuration for DNS server 1 + * param dns_server2: ip configuration for DNS server 2 + * + */ + void setDNS(IPAddress dns_server1, IPAddress dns_server2); + /* * Disconnect from the network * diff --git a/libraries/WiFi/WiFiClient.cpp b/libraries/WiFi/WiFiClient.cpp index 83c0d10..0b4b6dc 100644 --- a/libraries/WiFi/WiFiClient.cpp +++ b/libraries/WiFi/WiFiClient.cpp @@ -129,13 +129,13 @@ void WiFiClient::stop() { return; ServerDrv::stopClient(_sock); + WiFiClass::_state[_sock] = NA_STATE; - unsigned long start = millis(); - + int count = 0; + // wait maximum 5 secs for the connection to close + while (status() != CLOSED && ++count < 50) + delay(100); - // wait a second for the connection to close - while (status() != CLOSED && millis() - start < 1000) - delay(1); _sock = 255; } @@ -149,7 +149,7 @@ uint8_t WiFiClient::connected() { return !(s == LISTEN || s == CLOSED || s == FIN_WAIT_1 || s == FIN_WAIT_2 || s == TIME_WAIT || s == SYN_SENT || s== SYN_RCVD || - (s == CLOSE_WAIT && !available())); + (s == CLOSE_WAIT)); } } @@ -169,7 +169,7 @@ WiFiClient::operator bool() { uint8_t WiFiClient::getFirstSocket() { for (int i = 0; i < MAX_SOCK_NUM; i++) { - if (WiFiClass::_state[i] == 0) + if (WiFiClass::_state[i] == NA_STATE) { return i; } diff --git a/libraries/WiFi/WiFiServer.cpp b/libraries/WiFi/WiFiServer.cpp index 77dbac0..2f03bc1 100644 --- a/libraries/WiFi/WiFiServer.cpp +++ b/libraries/WiFi/WiFiServer.cpp @@ -21,6 +21,7 @@ void WiFiServer::begin() { ServerDrv::startServer(_port, _sock); WiFiClass::_server_port[_sock] = _port; + WiFiClass::_state[_sock] = _sock; } } diff --git a/libraries/WiFi/WiFiUdp.cpp b/libraries/WiFi/WiFiUdp.cpp new file mode 100644 index 0000000..7020df8 --- /dev/null +++ b/libraries/WiFi/WiFiUdp.cpp @@ -0,0 +1,163 @@ + +extern "C" { + #include "utility/debug.h" + #include "utility/wifi_spi.h" +} +#include <string.h> +#include "server_drv.h" +#include "wifi_drv.h" + +#include "WiFi.h" +#include "WiFiUdp.h" +#include "WiFiClient.h" +#include "WiFiServer.h" + + +/* Constructor */ +WiFiUDP::WiFiUDP() : _sock(NO_SOCKET_AVAIL) {} + +/* Start WiFiUDP socket, listening at local port PORT */ +uint8_t WiFiUDP::begin(uint16_t port) { + + uint8_t sock = WiFiClass::getSocket(); + if (sock != NO_SOCKET_AVAIL) + { + ServerDrv::startServer(port, sock, UDP_MODE); + WiFiClass::_server_port[sock] = port; + _sock = sock; + _port = port; + return 1; + } + return 0; + +} + +/* return number of bytes available in the current packet, + will return zero if parsePacket hasn't been called yet */ +int WiFiUDP::available() { + if (_sock != NO_SOCKET_AVAIL) + { + return ServerDrv::availData(_sock); + } + return 0; +} + +/* Release any resources being used by this WiFiUDP instance */ +void WiFiUDP::stop() +{ + if (_sock == NO_SOCKET_AVAIL) + return; + + ServerDrv::stopClient(_sock); + + _sock = NO_SOCKET_AVAIL; +} + +int WiFiUDP::beginPacket(const char *host, uint16_t port) +{ + // Look up the host first + int ret = 0; + IPAddress remote_addr; + if (WiFi.hostByName(host, remote_addr)) + { + return beginPacket(remote_addr, port); + } + return ret; +} + +int WiFiUDP::beginPacket(IPAddress ip, uint16_t port) +{ + if (_sock == NO_SOCKET_AVAIL) + _sock = WiFiClass::getSocket(); + if (_sock != NO_SOCKET_AVAIL) + { + ServerDrv::startClient(uint32_t(ip), port, _sock, UDP_MODE); + WiFiClass::_state[_sock] = _sock; + return 1; + } + return 0; +} + +int WiFiUDP::endPacket() +{ + return ServerDrv::sendUdpData(_sock); +} + +size_t WiFiUDP::write(uint8_t byte) +{ + return write(&byte, 1); +} + +size_t WiFiUDP::write(const uint8_t *buffer, size_t size) +{ + ServerDrv::insertDataBuf(_sock, buffer, size); + return size; +} + +int WiFiUDP::parsePacket() +{ + return available(); +} + +int WiFiUDP::read() +{ + uint8_t b; + if (available()) + { + ServerDrv::getData(_sock, &b); + return b; + }else{ + return -1; + } +} + +int WiFiUDP::read(unsigned char* buffer, size_t len) +{ + if (available()) + { + size_t size = 0; + if (!ServerDrv::getDataBuf(_sock, buffer, &size)) + return -1; + // TODO check if the buffer is too smal respect to buffer size + return size; + }else{ + return -1; + } +} + +int WiFiUDP::peek() +{ + uint8_t b; + if (!available()) + return -1; + + ServerDrv::getData(_sock, &b, 1); + return b; +} + +void WiFiUDP::flush() +{ + while (available()) + read(); +} + +IPAddress WiFiUDP::remoteIP() +{ + uint8_t _remoteIp[4] = {0}; + uint8_t _remotePort[2] = {0}; + + WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort); + IPAddress ip(_remoteIp); + return ip; +} + +uint16_t WiFiUDP::remotePort() +{ + uint8_t _remoteIp[4] = {0}; + uint8_t _remotePort[2] = {0}; + + WiFiDrv::getRemoteData(_sock, _remoteIp, _remotePort); + uint16_t port = (_remotePort[0]<<8)+_remotePort[1]; + return port; +} + diff --git a/libraries/WiFi/WiFiUdp.h b/libraries/WiFi/WiFiUdp.h new file mode 100644 index 0000000..1b31693 --- /dev/null +++ b/libraries/WiFi/WiFiUdp.h @@ -0,0 +1,61 @@ +#ifndef wifiudp_h +#define wifiudp_h + +#include <Udp.h> + +#define UDP_TX_PACKET_MAX_SIZE 24 + +class WiFiUDP : public UDP { +private: + uint8_t _sock; // socket ID for Wiz5100 + uint16_t _port; // local port to listen on + +public: + WiFiUDP(); // Constructor + virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual void stop(); // Finish with the UDP socket + + // Sending UDP packets + + // Start building up a packet to send to the remote host specific in ip and port + // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port + virtual int beginPacket(IPAddress ip, uint16_t port); + // Start building up a packet to send to the remote host specific in host and port + // Returns 1 if successful, 0 if there was a problem resolving the hostname or port + virtual int beginPacket(const char *host, uint16_t port); + // Finish off this packet and send it + // Returns 1 if the packet was sent successfully, 0 if there was an error + virtual int endPacket(); + // Write a single byte into the packet + virtual size_t write(uint8_t); + // Write size bytes from buffer into the packet + virtual size_t write(const uint8_t *buffer, size_t size); + + using Print::write; + + // Start processing the next available incoming packet + // Returns the size of the packet in bytes, or 0 if no packets are available + virtual int parsePacket(); + // Number of bytes remaining in the current packet + virtual int available(); + // Read a single byte from the current packet + virtual int read(); + // Read up to len bytes from the current packet and place them into buffer + // Returns the number of bytes read, or 0 if none are available + virtual int read(unsigned char* buffer, size_t len); + // Read up to len characters from the current packet and place them into buffer + // Returns the number of characters read, or 0 if none are available + virtual int read(char* buffer, size_t len) { return read((unsigned char*)buffer, len); }; + // Return the next byte from the current packet without moving on to the next byte + virtual int peek(); + virtual void flush(); // Finish reading the current packet + + // Return the IP address of the host who sent the current incoming packet + virtual IPAddress remoteIP(); + // Return the port of the host who sent the current incoming packet + virtual uint16_t remotePort(); + + friend class WiFiDrv; +}; + +#endif diff --git a/libraries/WiFi/examples/WiFiUdpNtpClient/WiFiUdpNtpClient.ino b/libraries/WiFi/examples/WiFiUdpNtpClient/WiFiUdpNtpClient.ino new file mode 100644 index 0000000..dd8b003 --- /dev/null +++ b/libraries/WiFi/examples/WiFiUdpNtpClient/WiFiUdpNtpClient.ino @@ -0,0 +1,182 @@ +/* + + Udp NTP Client + + Get the time from a Network Time Protocol (NTP) time server + Demonstrates use of UDP sendPacket and ReceivePacket + For more on NTP time servers and the messages needed to communicate with them, + see http://en.wikipedia.org/wiki/Network_Time_Protocol + + created 4 Sep 2010 + by Michael Margolis + modified 9 Apr 2012 + by Tom Igoe + + This code is in the public domain. + + */ + +#include <SPI.h> +#include <WiFi.h> +#include <WiFiUdp.h> + +int status = WL_IDLE_STATUS; +char ssid[] = "mynetwork"; // your network SSID (name) +char pass[] = "mypassword"; // your network password +int keyIndex = 0; // your network key Index number (needed only for WEP) + +unsigned int localPort = 2390; // local port to listen for UDP packets + +IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server + +const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message + +byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets + +// A UDP instance to let us send and receive packets over UDP +WiFiUDP Udp; + +void setup() +{ + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // check for the presence of the shield: + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue: + while(true); + } + + + // attempt to connect to Wifi network: + while ( status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); + + // wait 10 seconds for connection: + delay(10000); + } + + Serial.println("Connected to wifi"); + printWifiStatus(); + + Serial.println("\nStarting connection to server..."); + Udp.begin(localPort); +} + +void loop() +{ + sendNTPpacket(timeServer); // send an NTP packet to a time server + // wait to see if a reply is available + delay(1000); + Serial.println( Udp.parsePacket() ); + if ( Udp.parsePacket() ) { + Serial.println("packet received"); + // We've received a packet, read the data from it + Udp.read(packetBuffer,NTP_PACKET_SIZE); // read the packet into the buffer + + //the timestamp starts at byte 40 of the received packet and is four bytes, + // or two words, long. First, esxtract the two words: + + unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); + unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); + // combine the four bytes (two words) into a long integer + // this is NTP time (seconds since Jan 1 1900): + unsigned long secsSince1900 = highWord << 16 | lowWord; + Serial.print("Seconds since Jan 1 1900 = " ); + Serial.println(secsSince1900); + + // now convert NTP time into everyday time: + Serial.print("Unix time = "); + // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: + const unsigned long seventyYears = 2208988800UL; + // subtract seventy years: + unsigned long epoch = secsSince1900 - seventyYears; + // print Unix time: + Serial.println(epoch); + + + // print the hour, minute and second: + Serial.print("The UTC time is "); // UTC is the time at Greenwich Meridian (GMT) + Serial.print((epoch % 86400L) / 3600); // print the hour (86400 equals secs per day) + Serial.print(':'); + if ( ((epoch % 3600) / 60) < 10 ) { + // In the first 10 minutes of each hour, we'll want a leading '0' + Serial.print('0'); + } + Serial.print((epoch % 3600) / 60); // print the minute (3600 equals secs per minute) + Serial.print(':'); + if ( (epoch % 60) < 10 ) { + // In the first 10 seconds of each minute, we'll want a leading '0' + Serial.print('0'); + } + Serial.println(epoch %60); // print the second + } + // wait ten seconds before asking for the time again + delay(10000); +} + +// send an NTP request to the time server at the given address +unsigned long sendNTPpacket(IPAddress& address) +{ + //Serial.println("1"); + // set all bytes in the buffer to 0 + memset(packetBuffer, 0, NTP_PACKET_SIZE); + // Initialize values needed to form NTP request + // (see URL above for details on the packets) + //Serial.println("2"); + packetBuffer[0] = 0b11100011; // LI, Version, Mode + packetBuffer[1] = 0; // Stratum, or type of clock + packetBuffer[2] = 6; // Polling Interval + packetBuffer[3] = 0xEC; // Peer Clock Precision + // 8 bytes of zero for Root Delay & Root Dispersion + packetBuffer[12] = 49; + packetBuffer[13] = 0x4E; + packetBuffer[14] = 49; + packetBuffer[15] = 52; + + //Serial.println("3"); + + // all NTP fields have been given values, now + // you can send a packet requesting a timestamp: + Udp.beginPacket(address, 123); //NTP requests are to port 123 + //Serial.println("4"); + Udp.write(packetBuffer,NTP_PACKET_SIZE); + //Serial.println("5"); + Udp.endPacket(); + //Serial.println("6"); +} + + +void printWifiStatus() { + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print your WiFi shield's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.print(rssi); + Serial.println(" dBm"); +} + + + + + + + + + + diff --git a/libraries/WiFi/examples/WifiUdpSendReceiveString/WifiUdpSendReceiveString.ino b/libraries/WiFi/examples/WifiUdpSendReceiveString/WifiUdpSendReceiveString.ino new file mode 100644 index 0000000..eb11295 --- /dev/null +++ b/libraries/WiFi/examples/WifiUdpSendReceiveString/WifiUdpSendReceiveString.ino @@ -0,0 +1,112 @@ + +/* + WiFi UDP Send and Receive String + + This sketch wait an UDP packet on localPort using a WiFi shield. + When a packet is received an Acknowledge packet is sent to the client on port remotePort + + Circuit: + * WiFi shield attached + + created 30 December 2012 + by dlf (Metodo2 srl) + + */ + + +#include <SPI.h> +#include <WiFi.h> +#include <WiFiUdp.h> + +int status = WL_IDLE_STATUS; +char ssid[] = "yourNetwork"; // your network SSID (name) +char pass[] = "secretPassword"; // your network password (use for WPA, or use as key for WEP) +int keyIndex = 0; // your network key Index number (needed only for WEP) + +unsigned int localPort = 2390; // local port to listen on + +char packetBuffer[255]; //buffer to hold incoming packet +char ReplyBuffer[] = "acknowledged"; // a string to send back + +WiFiUDP Udp; + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for Leonardo only + } + + // check for the presence of the shield: + if (WiFi.status() == WL_NO_SHIELD) { + Serial.println("WiFi shield not present"); + // don't continue: + while(true); + } + + // attempt to connect to Wifi network: + while ( status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid); + + // wait 10 seconds for connection: + delay(10000); + } + Serial.println("Connected to wifi"); + printWifiStatus(); + + Serial.println("\nStarting connection to server..."); + // if you get a connection, report back via serial: + Udp.begin(localPort); +} + +void loop() { + + // if there's data available, read a packet + int packetSize = Udp.parsePacket(); + if(packetSize) + { + Serial.print("Received packet of size "); + Serial.println(packetSize); + Serial.print("From "); + IPAddress remoteIp = Udp.remoteIP(); + Serial.print(remoteIp); + Serial.print(", port "); + Serial.println(Udp.remotePort()); + + // read the packet into packetBufffer + int len = Udp.read(packetBuffer,255); + if (len >0) packetBuffer[len]=0; + Serial.println("Contents:"); + Serial.println(packetBuffer); + + // send a reply, to the IP address and port that sent us the packet we received + Udp.beginPacket(Udp.remoteIP(), Udp.remotePort()); + Udp.write(ReplyBuffer); + Udp.endPacket(); + } +} + + +void printWifiStatus() { + // print the SSID of the network you're attached to: + Serial.print("SSID: "); + Serial.println(WiFi.SSID()); + + // print your WiFi shield's IP address: + IPAddress ip = WiFi.localIP(); + Serial.print("IP Address: "); + Serial.println(ip); + + // print the received signal strength: + long rssi = WiFi.RSSI(); + Serial.print("signal strength (RSSI):"); + Serial.print(rssi); + Serial.println(" dBm"); +} + + + + diff --git a/libraries/WiFi/examples/WifiWebServer/WifiWebServer.ino b/libraries/WiFi/examples/WifiWebServer/WifiWebServer.ino index a514e15..7d7a247 100644 --- a/libraries/WiFi/examples/WifiWebServer/WifiWebServer.ino +++ b/libraries/WiFi/examples/WifiWebServer/WifiWebServer.ino @@ -1,5 +1,5 @@ /* - Web Server + WiFi Web Server A simple web server that shows the value of the analog input pins. using a WiFi shield. @@ -15,7 +15,9 @@ by dlf (Metodo2 srl) modified 31 May 2012 by Tom Igoe + */ + #include <SPI.h> #include <WiFi.h> diff --git a/libraries/WiFi/keywords.txt b/libraries/WiFi/keywords.txt index 47704cd..4106a7d 100644 --- a/libraries/WiFi/keywords.txt +++ b/libraries/WiFi/keywords.txt @@ -18,6 +18,8 @@ status KEYWORD2 connect KEYWORD2 write KEYWORD2 available KEYWORD2 +config KEYWORD2 +setDNS KEYWORD2 read KEYWORD2 flush KEYWORD2 stop KEYWORD2 @@ -36,6 +38,12 @@ getResult KEYWORD2 getSocket KEYWORD2 WiFiClient KEYWORD2 WiFiServer KEYWORD2 +WiFiUDP KEYWORD2 +beginPacket KEYWORD2 +endPacket KEYWORD2 +parsePacket KEYWORD2 +remoteIP KEYWORD2 +remotePort KEYWORD2 ####################################### # Constants (LITERAL1) diff --git a/libraries/WiFi/utility/server_drv.cpp b/libraries/WiFi/utility/server_drv.cpp index ce03604..4a6d293 100644 --- a/libraries/WiFi/utility/server_drv.cpp +++ b/libraries/WiFi/utility/server_drv.cpp @@ -1,131 +1,205 @@ -//#define _DEBUG_
-
-#include "server_drv.h"
-
-#include "Arduino.h"
-#include "spi_drv.h"
-
-extern "C" {
-#include "wl_types.h"
-#include "debug.h"
-}
-
-
-// Start server TCP on port specified
-void ServerDrv::startServer(uint16_t port, uint8_t sock)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(START_SERVER_TCP_CMD, PARAM_NUMS_2);
- SpiDrv::sendParam(port);
- SpiDrv::sendParam(&sock, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(START_SERVER_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
-}
-
-// Start server TCP on port specified
-void ServerDrv::startClient(uint32_t ipAddress, uint16_t port, uint8_t sock)
+//#define _DEBUG_ + +#include "server_drv.h" + +#include "Arduino.h" +#include "spi_drv.h" + +extern "C" { +#include "wl_types.h" +#include "debug.h" +} + + +// Start server TCP on port specified +void ServerDrv::startServer(uint16_t port, uint8_t sock, uint8_t protMode)
+{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(START_SERVER_TCP_CMD, PARAM_NUMS_3);
+ SpiDrv::sendParam(port); + SpiDrv::sendParam(&sock, 1);
+ SpiDrv::sendParam(&protMode, 1, LAST_PARAM);
+ + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(START_SERVER_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); +} + +// Start server TCP on port specified +void ServerDrv::startClient(uint32_t ipAddress, uint16_t port, uint8_t sock, uint8_t protMode)
+{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_4);
+ SpiDrv::sendParam((uint8_t*)&ipAddress, sizeof(ipAddress)); + SpiDrv::sendParam(port); + SpiDrv::sendParam(&sock, 1);
+ SpiDrv::sendParam(&protMode, 1, LAST_PARAM);
+ + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); +} + +// Start server TCP on port specified +void ServerDrv::stopClient(uint8_t sock) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1); + SpiDrv::sendParam(&sock, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); +} + + +uint8_t ServerDrv::getServerState(uint8_t sock) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1); + SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); + return _data; +} + +uint8_t ServerDrv::getClientState(uint8_t sock) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1); + SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); + return _data; +} + +uint16_t ServerDrv::availData(uint8_t sock) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1); + SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _dataLen = 0; + uint16_t len = 0; + + SpiDrv::waitResponseCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1, (uint8_t*)&len, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return len; +} + +bool ServerDrv::getData(uint8_t sock, uint8_t *data, uint8_t peek) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(GET_DATA_TCP_CMD, PARAM_NUMS_2); + SpiDrv::sendParam(&sock, sizeof(sock)); + SpiDrv::sendParam(peek, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseData8(GET_DATA_TCP_CMD, &_data, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); + if (_dataLen!=0) + { + *data = _data; + return true; + } + return false; +} + +bool ServerDrv::getDataBuf(uint8_t sock, uint8_t *_data, uint16_t *_dataLen) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(GET_DATABUF_TCP_CMD, PARAM_NUMS_1); + SpiDrv::sendBuffer(&sock, sizeof(sock), LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + if (!SpiDrv::waitResponseData16(GET_DATABUF_TCP_CMD, _data, _dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); + if (*_dataLen!=0) + { + return true; + } + return false; +} + +bool ServerDrv::insertDataBuf(uint8_t sock, const uint8_t *data, uint16_t _len)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
- SpiDrv::sendCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_3);
- SpiDrv::sendParam((uint8_t*)&ipAddress, sizeof(ipAddress));
- SpiDrv::sendParam(port);
- SpiDrv::sendParam(&sock, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(START_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
-}
-
-// Start server TCP on port specified
-void ServerDrv::stopClient(uint8_t sock)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1);
- SpiDrv::sendParam(&sock, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(STOP_CLIENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
-}
-
-
-uint8_t ServerDrv::getServerState(uint8_t sock)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1);
- SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(GET_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
- return _data;
-}
-
-uint8_t ServerDrv::getClientState(uint8_t sock)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1);
- SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(GET_CLIENT_STATE_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
- return _data;
-}
-
-uint8_t ServerDrv::availData(uint8_t sock)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1);
- SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
+ SpiDrv::sendCmd(INSERT_DATABUF_CMD, PARAM_NUMS_2);
+ SpiDrv::sendBuffer(&sock, sizeof(sock));
+ SpiDrv::sendBuffer((uint8_t *)data, _len, LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
@@ -133,12 +207,11 @@ uint8_t ServerDrv::availData(uint8_t sock) // Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(AVAIL_DATA_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
+ if (!SpiDrv::waitResponseData8(INSERT_DATABUF_CMD, &_data, &_dataLen))
{
WARN("error waitResponse");
}
SpiDrv::spiSlaveDeselect();
-
if (_dataLen!=0)
{
return (_data == 1);
@@ -146,64 +219,12 @@ uint8_t ServerDrv::availData(uint8_t sock) return false;
}
-bool ServerDrv::getData(uint8_t sock, uint8_t *data, uint8_t peek)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(GET_DATA_TCP_CMD, PARAM_NUMS_2);
- SpiDrv::sendParam(&sock, sizeof(sock));
- SpiDrv::sendParam(peek, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseData8(GET_DATA_TCP_CMD, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
- if (_dataLen!=0)
- {
- *data = _data;
- return true;
- }
- return false;
-}
-
-bool ServerDrv::getDataBuf(uint8_t sock, uint8_t *_data, uint16_t *_dataLen)
+bool ServerDrv::sendUdpData(uint8_t sock)
{
WAIT_FOR_SLAVE_SELECT();
// Send Command
- SpiDrv::sendCmd(GET_DATABUF_TCP_CMD, PARAM_NUMS_1);
- SpiDrv::sendBuffer(&sock, sizeof(sock), LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- if (!SpiDrv::waitResponseData16(GET_DATABUF_TCP_CMD, _data, _dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
- if (*_dataLen!=0)
- {
- return true;
- }
- return false;
-}
-
-
-bool ServerDrv::sendData(uint8_t sock, const uint8_t *data, uint16_t len)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(SEND_DATA_TCP_CMD, PARAM_NUMS_2);
- SpiDrv::sendBuffer(&sock, sizeof(sock));
- SpiDrv::sendBuffer((uint8_t *)data, len, LAST_PARAM);
+ SpiDrv::sendCmd(SEND_DATA_UDP_CMD, PARAM_NUMS_1);
+ SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
@@ -211,7 +232,7 @@ bool ServerDrv::sendData(uint8_t sock, const uint8_t *data, uint16_t len) // Wait for reply
uint8_t _data = 0;
uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseData8(SEND_DATA_TCP_CMD, &_data, &_dataLen))
+ if (!SpiDrv::waitResponseData8(SEND_DATA_UDP_CMD, &_data, &_dataLen))
{
WARN("error waitResponse");
}
@@ -223,38 +244,65 @@ bool ServerDrv::sendData(uint8_t sock, const uint8_t *data, uint16_t len) return false;
}
-
-uint8_t ServerDrv::checkDataSent(uint8_t sock)
-{
- const uint16_t TIMEOUT_DATA_SENT = 25;
- uint16_t timeout = 0;
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
-
- do {
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(DATA_SENT_TCP_CMD, PARAM_NUMS_1);
- SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- if (!SpiDrv::waitResponseCmd(DATA_SENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse isDataSent");
- }
- SpiDrv::spiSlaveDeselect();
-
- if (_data) timeout = 0;
- else{
- ++timeout;
- delay(100);
- }
-
- }while((_data==0)&&(timeout<TIMEOUT_DATA_SENT));
- return (timeout==TIMEOUT_DATA_SENT)?0:1;
-}
-
-ServerDrv serverDrv;
+ +bool ServerDrv::sendData(uint8_t sock, const uint8_t *data, uint16_t len) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(SEND_DATA_TCP_CMD, PARAM_NUMS_2); + SpiDrv::sendBuffer(&sock, sizeof(sock)); + SpiDrv::sendBuffer((uint8_t *)data, len, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseData8(SEND_DATA_TCP_CMD, &_data, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); + if (_dataLen!=0) + { + return (_data == 1); + } + return false; +} + + +uint8_t ServerDrv::checkDataSent(uint8_t sock) +{ + const uint16_t TIMEOUT_DATA_SENT = 25; + uint16_t timeout = 0; + uint8_t _data = 0; + uint8_t _dataLen = 0; + + do { + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(DATA_SENT_TCP_CMD, PARAM_NUMS_1); + SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + if (!SpiDrv::waitResponseCmd(DATA_SENT_TCP_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse isDataSent"); + } + SpiDrv::spiSlaveDeselect(); + + if (_data) timeout = 0; + else{ + ++timeout; + delay(100); + } + + }while((_data==0)&&(timeout<TIMEOUT_DATA_SENT)); + return (timeout==TIMEOUT_DATA_SENT)?0:1; +} + +ServerDrv serverDrv; diff --git a/libraries/WiFi/utility/server_drv.h b/libraries/WiFi/utility/server_drv.h index 69ba593..50ba7e3 100644 --- a/libraries/WiFi/utility/server_drv.h +++ b/libraries/WiFi/utility/server_drv.h @@ -1,34 +1,41 @@ -#ifndef Server_Drv_h
-#define Server_Drv_h
-
-#include <inttypes.h>
-#include "wifi_spi.h"
-
-class ServerDrv
-{
-public:
- // Start server TCP on port specified
- static void startServer(uint16_t port, uint8_t sock);
-
- static void startClient(uint32_t ipAddress, uint16_t port, uint8_t sock);
-
- static void stopClient(uint8_t sock);
-
- static uint8_t getServerState(uint8_t sock);
-
- static uint8_t getClientState(uint8_t sock);
-
- static bool getData(uint8_t sock, uint8_t *data, uint8_t peek = 0);
-
- static bool getDataBuf(uint8_t sock, uint8_t *data, uint16_t *len);
-
- static bool sendData(uint8_t sock, const uint8_t *data, uint16_t len);
-
- static uint8_t availData(uint8_t sock);
-
- static uint8_t checkDataSent(uint8_t sock);
-};
-
-extern ServerDrv serverDrv;
-
-#endif
+#ifndef Server_Drv_h +#define Server_Drv_h + +#include <inttypes.h> +#include "wifi_spi.h" + +typedef enum eProtMode {TCP_MODE, UDP_MODE}tProtMode;
+
+class ServerDrv +{ +public: +
+ // Start server TCP on port specified + static void startServer(uint16_t port, uint8_t sock, uint8_t protMode=TCP_MODE);
+ + static void startClient(uint32_t ipAddress, uint16_t port, uint8_t sock, uint8_t protMode=TCP_MODE);
+ + static void stopClient(uint8_t sock); + + static uint8_t getServerState(uint8_t sock); + + static uint8_t getClientState(uint8_t sock); + + static bool getData(uint8_t sock, uint8_t *data, uint8_t peek = 0); + + static bool getDataBuf(uint8_t sock, uint8_t *data, uint16_t *len); + + static bool insertDataBuf(uint8_t sock, const uint8_t *_data, uint16_t _dataLen);
+
+ static bool sendData(uint8_t sock, const uint8_t *data, uint16_t len); + + static bool sendUdpData(uint8_t sock);
+
+ static uint16_t availData(uint8_t sock); + + static uint8_t checkDataSent(uint8_t sock); +}; + +extern ServerDrv serverDrv; + +#endif diff --git a/libraries/WiFi/utility/spi_drv.h b/libraries/WiFi/utility/spi_drv.h index 5c2e706..b7e4cb7 100644 --- a/libraries/WiFi/utility/spi_drv.h +++ b/libraries/WiFi/utility/spi_drv.h @@ -1,83 +1,83 @@ -#ifndef SPI_Drv_h
-#define SPI_Drv_h
-
-#include <inttypes.h>
-#include "wifi_spi.h"
-
-#define SPI_START_CMD_DELAY 12
-
-#define NO_LAST_PARAM 0
-#define LAST_PARAM 1
-
-#define DUMMY_DATA 0xFF
-
-#define WAIT_FOR_SLAVE_SELECT() \
- SpiDrv::waitForSlaveReady(); \
- SpiDrv::spiSlaveSelect();
-
-
-
-class SpiDrv
-{
-private:
- //static bool waitSlaveReady();
- static void waitForSlaveSign();
- static void getParam(uint8_t* param);
-public:
-
- static void begin();
-
- static void end();
-
- static void spiDriverInit();
-
- static void spiSlaveSelect();
-
- static void spiSlaveDeselect();
-
- static char spiTransfer(volatile char data);
-
- static void waitForSlaveReady();
-
- //static int waitSpiChar(char waitChar, char* readChar);
-
- static int waitSpiChar(unsigned char waitChar);
-
- static int readAndCheckChar(char checkChar, char* readChar);
-
- static char readChar();
-
- static int waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params);
-
- static int waitResponseCmd(uint8_t cmd, uint8_t numParam, uint8_t* param, uint8_t* param_len);
-
- static int waitResponseData8(uint8_t cmd, uint8_t* param, uint8_t* param_len);
-
- static int waitResponseData16(uint8_t cmd, uint8_t* param, uint16_t* param_len);
- /*
- static int waitResponse(uint8_t cmd, tParam* params, uint8_t* numParamRead, uint8_t maxNumParams);
-
- static int waitResponse(uint8_t cmd, uint8_t numParam, uint8_t* param, uint16_t* param_len);
-*/
- static int waitResponse(uint8_t cmd, uint8_t* numParamRead, uint8_t** params, uint8_t maxNumParams);
-
- static void sendParam(uint8_t* param, uint8_t param_len, uint8_t lastParam = NO_LAST_PARAM);
-
- static void sendParamLen8(uint8_t param_len);
-
- static void sendParamLen16(uint16_t param_len);
-
- static uint8_t readParamLen8(uint8_t* param_len = NULL);
-
- static uint16_t readParamLen16(uint16_t* param_len = NULL);
-
- static void sendBuffer(uint8_t* param, uint16_t param_len, uint8_t lastParam = NO_LAST_PARAM);
-
- static void sendParam(uint16_t param, uint8_t lastParam = NO_LAST_PARAM);
-
- static void sendCmd(uint8_t cmd, uint8_t numParam);
-};
-
-extern SpiDrv spiDrv;
-
-#endif
+#ifndef SPI_Drv_h +#define SPI_Drv_h + +#include <inttypes.h> +#include "wifi_spi.h" + +#define SPI_START_CMD_DELAY 10
+ +#define NO_LAST_PARAM 0 +#define LAST_PARAM 1 + +#define DUMMY_DATA 0xFF + +#define WAIT_FOR_SLAVE_SELECT() \ + SpiDrv::waitForSlaveReady(); \ + SpiDrv::spiSlaveSelect(); + + + +class SpiDrv +{ +private: + //static bool waitSlaveReady(); + static void waitForSlaveSign(); + static void getParam(uint8_t* param); +public: + + static void begin(); + + static void end(); + + static void spiDriverInit(); + + static void spiSlaveSelect(); + + static void spiSlaveDeselect(); + + static char spiTransfer(volatile char data); + + static void waitForSlaveReady(); + + //static int waitSpiChar(char waitChar, char* readChar); + + static int waitSpiChar(unsigned char waitChar); + + static int readAndCheckChar(char checkChar, char* readChar); + + static char readChar(); + + static int waitResponseParams(uint8_t cmd, uint8_t numParam, tParam* params); + + static int waitResponseCmd(uint8_t cmd, uint8_t numParam, uint8_t* param, uint8_t* param_len); + + static int waitResponseData8(uint8_t cmd, uint8_t* param, uint8_t* param_len); + + static int waitResponseData16(uint8_t cmd, uint8_t* param, uint16_t* param_len); + /* + static int waitResponse(uint8_t cmd, tParam* params, uint8_t* numParamRead, uint8_t maxNumParams); + + static int waitResponse(uint8_t cmd, uint8_t numParam, uint8_t* param, uint16_t* param_len); +*/ + static int waitResponse(uint8_t cmd, uint8_t* numParamRead, uint8_t** params, uint8_t maxNumParams); + + static void sendParam(uint8_t* param, uint8_t param_len, uint8_t lastParam = NO_LAST_PARAM); + + static void sendParamLen8(uint8_t param_len); + + static void sendParamLen16(uint16_t param_len); + + static uint8_t readParamLen8(uint8_t* param_len = NULL); + + static uint16_t readParamLen16(uint16_t* param_len = NULL); + + static void sendBuffer(uint8_t* param, uint16_t param_len, uint8_t lastParam = NO_LAST_PARAM); + + static void sendParam(uint16_t param, uint8_t lastParam = NO_LAST_PARAM); + + static void sendCmd(uint8_t cmd, uint8_t numParam); +}; + +extern SpiDrv spiDrv; + +#endif diff --git a/libraries/WiFi/utility/wifi_drv.cpp b/libraries/WiFi/utility/wifi_drv.cpp index 1ca1696..ccd5f25 100644 --- a/libraries/WiFi/utility/wifi_drv.cpp +++ b/libraries/WiFi/utility/wifi_drv.cpp @@ -1,491 +1,560 @@ -#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "Arduino.h"
-#include "spi_drv.h"
-#include "wifi_drv.h"
-
-#define _DEBUG_
-
-extern "C" {
-#include "wifi_spi.h"
-#include "wl_types.h"
-#include "debug.h"
-}
-
-// Array of data to cache the information related to the networks discovered
-char WiFiDrv::_networkSsid[][WL_SSID_MAX_LENGTH] = {{"1"},{"2"},{"3"},{"4"},{"5"}};
-int32_t WiFiDrv::_networkRssi[WL_NETWORKS_LIST_MAXNUM] = { 0 };
-uint8_t WiFiDrv::_networkEncr[WL_NETWORKS_LIST_MAXNUM] = { 0 };
-
-// Cached values of retrieved data
-char WiFiDrv::_ssid[] = {0};
-uint8_t WiFiDrv::_bssid[] = {0};
-uint8_t WiFiDrv::_mac[] = {0};
-uint8_t WiFiDrv::_localIp[] = {0};
-uint8_t WiFiDrv::_subnetMask[] = {0};
-uint8_t WiFiDrv::_gatewayIp[] = {0};
-// Firmware version
-char WiFiDrv::fwVersion[] = {0};
-
-
-// Private Methods
-
-void WiFiDrv::getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip)
+#include <stdio.h> +#include <string.h> +#include <stdint.h> + +#include "Arduino.h" +#include "spi_drv.h" +#include "wifi_drv.h" + +#define _DEBUG_ + +extern "C" { +#include "wifi_spi.h" +#include "wl_types.h" +#include "debug.h" +} + +// Array of data to cache the information related to the networks discovered +char WiFiDrv::_networkSsid[][WL_SSID_MAX_LENGTH] = {{"1"},{"2"},{"3"},{"4"},{"5"}}; +int32_t WiFiDrv::_networkRssi[WL_NETWORKS_LIST_MAXNUM] = { 0 }; +uint8_t WiFiDrv::_networkEncr[WL_NETWORKS_LIST_MAXNUM] = { 0 }; + +// Cached values of retrieved data +char WiFiDrv::_ssid[] = {0}; +uint8_t WiFiDrv::_bssid[] = {0}; +uint8_t WiFiDrv::_mac[] = {0}; +uint8_t WiFiDrv::_localIp[] = {0}; +uint8_t WiFiDrv::_subnetMask[] = {0}; +uint8_t WiFiDrv::_gatewayIp[] = {0}; +// Firmware version +char WiFiDrv::fwVersion[] = {0}; + + +// Private Methods + +void WiFiDrv::getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip) +{ + tParam params[PARAM_NUMS_3] = { {0, (char*)ip}, {0, (char*)mask}, {0, (char*)gwip}}; + + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_IPADDR_CMD, PARAM_NUMS_1); + + uint8_t _dummy = DUMMY_DATA; + SpiDrv::sendParam(&_dummy, sizeof(_dummy), LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + SpiDrv::waitResponseParams(GET_IPADDR_CMD, PARAM_NUMS_3, params); + + SpiDrv::spiSlaveDeselect(); +} + +void WiFiDrv::getRemoteData(uint8_t sock, uint8_t *ip, uint8_t *port)
{
- tParam params[PARAM_NUMS_3] = { {0, (char*)ip}, {0, (char*)mask}, {0, (char*)gwip}};
+ tParam params[PARAM_NUMS_2] = { {0, (char*)ip}, {0, (char*)port} };
WAIT_FOR_SLAVE_SELECT();
// Send Command
- SpiDrv::sendCmd(GET_IPADDR_CMD, PARAM_NUMS_1);
-
- uint8_t _dummy = DUMMY_DATA;
- SpiDrv::sendParam(&_dummy, sizeof(_dummy), LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- SpiDrv::waitResponseParams(GET_IPADDR_CMD, PARAM_NUMS_3, params);
-
- SpiDrv::spiSlaveDeselect();
-}
-
-// Public Methods
-
-
-void WiFiDrv::wifiDriverInit()
-{
- SpiDrv::begin();
-}
-
-int8_t WiFiDrv::wifiSetNetwork(char* ssid, uint8_t ssid_len)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(SET_NET_CMD, PARAM_NUMS_1);
- SpiDrv::sendParam((uint8_t*)ssid, ssid_len, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(SET_NET_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- _data = WL_FAILURE;
- }
- SpiDrv::spiSlaveDeselect();
-
- return(_data == WIFI_SPI_ACK) ? WL_SUCCESS : WL_FAILURE;
-}
-
-int8_t WiFiDrv::wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_2);
- SpiDrv::sendParam((uint8_t*)ssid, ssid_len, NO_LAST_PARAM);
- SpiDrv::sendParam((uint8_t*)passphrase, len, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- _data = WL_FAILURE;
- }
- SpiDrv::spiSlaveDeselect();
- return _data;
-}
-
-
-int8_t WiFiDrv::wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len)
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(SET_KEY_CMD, PARAM_NUMS_3);
- SpiDrv::sendParam((uint8_t*)ssid, ssid_len, NO_LAST_PARAM);
- SpiDrv::sendParam(&key_idx, KEY_IDX_LEN, NO_LAST_PARAM);
- SpiDrv::sendParam((uint8_t*)key, len, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(SET_KEY_CMD, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- _data = WL_FAILURE;
- }
- SpiDrv::spiSlaveDeselect();
- return _data;
-}
-
-int8_t WiFiDrv::disconnect()
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(DISCONNECT_CMD, PARAM_NUMS_1);
-
- uint8_t _dummy = DUMMY_DATA;
- SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- int8_t result = SpiDrv::waitResponseCmd(DISCONNECT_CMD, PARAM_NUMS_1, &_data, &_dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return result;
-}
-
-uint8_t WiFiDrv::getConnectionStatus()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_0);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = -1;
- uint8_t _dataLen = 0;
- SpiDrv::waitResponseCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_1, &_data, &_dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return _data;
-}
-
-uint8_t* WiFiDrv::getMacAddress()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_MACADDR_CMD, PARAM_NUMS_1);
-
- uint8_t _dummy = DUMMY_DATA;
- SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _dataLen = 0;
- SpiDrv::waitResponseCmd(GET_MACADDR_CMD, PARAM_NUMS_1, _mac, &_dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return _mac;
-}
-
-void WiFiDrv::getIpAddress(IPAddress& ip)
-{
- getNetworkData(_localIp, _subnetMask, _gatewayIp);
- ip = _localIp;
-}
-
- void WiFiDrv::getSubnetMask(IPAddress& mask)
- {
- getNetworkData(_localIp, _subnetMask, _gatewayIp);
- mask = _subnetMask;
- }
-
- void WiFiDrv::getGatewayIP(IPAddress& ip)
- {
- getNetworkData(_localIp, _subnetMask, _gatewayIp);
- ip = _gatewayIp;
- }
-
-char* WiFiDrv::getCurrentSSID()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_CURR_SSID_CMD, PARAM_NUMS_1);
-
- uint8_t _dummy = DUMMY_DATA;
- SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _dataLen = 0;
- SpiDrv::waitResponseCmd(GET_CURR_SSID_CMD, PARAM_NUMS_1, (uint8_t*)_ssid, &_dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return _ssid;
-}
-
-uint8_t* WiFiDrv::getCurrentBSSID()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_1);
-
- uint8_t _dummy = DUMMY_DATA;
- SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _dataLen = 0;
- SpiDrv::waitResponseCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_1, _bssid, &_dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return _bssid;
-}
-
-int32_t WiFiDrv::getCurrentRSSI()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_1);
-
- uint8_t _dummy = DUMMY_DATA;
- SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _dataLen = 0;
- int32_t rssi = 0;
- SpiDrv::waitResponseCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_1, (uint8_t*)&rssi, &_dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return rssi;
-}
-
-uint8_t WiFiDrv::getCurrentEncryptionType()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_CURR_ENCT_CMD, PARAM_NUMS_1);
-
- uint8_t _dummy = DUMMY_DATA;
- SpiDrv::sendParam(&_dummy, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t dataLen = 0;
- uint8_t encType = 0;
- SpiDrv::waitResponseCmd(GET_CURR_ENCT_CMD, PARAM_NUMS_1, (uint8_t*)&encType, &dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return encType;
-}
-
-int8_t WiFiDrv::startScanNetworks()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(START_SCAN_NETWORKS, PARAM_NUMS_0);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
-
- if (!SpiDrv::waitResponseCmd(START_SCAN_NETWORKS, PARAM_NUMS_1, &_data, &_dataLen))
- {
- WARN("error waitResponse");
- _data = WL_FAILURE;
- }
-
- SpiDrv::spiSlaveDeselect();
-
- return (_data == WL_FAILURE)? _data : WL_SUCCESS;
-}
-
-
-uint8_t WiFiDrv::getScanNetworks()
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(SCAN_NETWORKS, PARAM_NUMS_0);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t ssidListNum = 0;
- SpiDrv::waitResponse(SCAN_NETWORKS, &ssidListNum, (uint8_t**)_networkSsid, WL_NETWORKS_LIST_MAXNUM);
-
- SpiDrv::spiSlaveDeselect();
-
- return ssidListNum;
-}
-
-char* WiFiDrv::getSSIDNetoworks(uint8_t networkItem)
-{
- if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
- return NULL;
-
- return _networkSsid[networkItem];
-}
-
-uint8_t WiFiDrv::getEncTypeNetowrks(uint8_t networkItem)
-{
- if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
- return NULL;
-
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_IDX_ENCT_CMD, PARAM_NUMS_1);
-
- SpiDrv::sendParam(&networkItem, 1, LAST_PARAM);
+ SpiDrv::sendCmd(GET_REMOTE_DATA_CMD, PARAM_NUMS_1);
+ SpiDrv::sendParam(&sock, sizeof(sock), LAST_PARAM);
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
// Wait for reply
- uint8_t dataLen = 0;
- uint8_t encType = 0;
- SpiDrv::waitResponseCmd(GET_IDX_ENCT_CMD, PARAM_NUMS_1, (uint8_t*)&encType, &dataLen);
+ SpiDrv::waitResponseParams(GET_REMOTE_DATA_CMD, PARAM_NUMS_2, params);
SpiDrv::spiSlaveDeselect();
-
- return encType;
}
-int32_t WiFiDrv::getRSSINetoworks(uint8_t networkItem)
-{
- if (networkItem >= WL_NETWORKS_LIST_MAXNUM)
- return NULL;
- int32_t networkRssi = 0;
-
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(GET_IDX_RSSI_CMD, PARAM_NUMS_1);
-
- SpiDrv::sendParam(&networkItem, 1, LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t dataLen = 0;
- SpiDrv::waitResponseCmd(GET_IDX_RSSI_CMD, PARAM_NUMS_1, (uint8_t*)&networkRssi, &dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return networkRssi;
-}
-
-uint8_t WiFiDrv::reqHostByName(const char* aHostname)
-{
- WAIT_FOR_SLAVE_SELECT();
-
- // Send Command
- SpiDrv::sendCmd(REQ_HOST_BY_NAME_CMD, PARAM_NUMS_1);
- SpiDrv::sendParam((uint8_t*)aHostname, strlen(aHostname), LAST_PARAM);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _data = 0;
- uint8_t _dataLen = 0;
- uint8_t result = SpiDrv::waitResponseCmd(REQ_HOST_BY_NAME_CMD, PARAM_NUMS_1, &_data, &_dataLen);
-
- SpiDrv::spiSlaveDeselect();
-
- return result;
-}
-
-int WiFiDrv::getHostByName(IPAddress& aResult)
-{
- uint8_t _ipAddr[WL_IPV4_LENGTH];
- IPAddress dummy(0xFF,0xFF,0xFF,0xFF);
- int result = 0;
-
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(GET_HOST_BY_NAME_CMD, PARAM_NUMS_0);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(GET_HOST_BY_NAME_CMD, PARAM_NUMS_1, _ipAddr, &_dataLen))
- {
- WARN("error waitResponse");
- }else{
- aResult = _ipAddr;
- result = (aResult != dummy);
- }
- SpiDrv::spiSlaveDeselect();
- return result;
-}
-
-int WiFiDrv::getHostByName(const char* aHostname, IPAddress& aResult)
-{
- uint8_t retry = 10;
- if (reqHostByName(aHostname))
- {
- while(!getHostByName(aResult) && --retry > 0)
- {
- delay(1000);
- }
- }else{
- return 0;
- }
- return (retry>0);
-}
-
-char* WiFiDrv::getFwVersion()
-{
- WAIT_FOR_SLAVE_SELECT();
- // Send Command
- SpiDrv::sendCmd(GET_FW_VERSION_CMD, PARAM_NUMS_0);
-
- //Wait the reply elaboration
- SpiDrv::waitForSlaveReady();
-
- // Wait for reply
- uint8_t _dataLen = 0;
- if (!SpiDrv::waitResponseCmd(GET_FW_VERSION_CMD, PARAM_NUMS_1, (uint8_t*)fwVersion, &_dataLen))
- {
- WARN("error waitResponse");
- }
- SpiDrv::spiSlaveDeselect();
- return fwVersion;
-}
-WiFiDrv wiFiDrv;
+// Public Methods + + +void WiFiDrv::wifiDriverInit() +{ + SpiDrv::begin(); +} + +int8_t WiFiDrv::wifiSetNetwork(char* ssid, uint8_t ssid_len) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(SET_NET_CMD, PARAM_NUMS_1); + SpiDrv::sendParam((uint8_t*)ssid, ssid_len, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(SET_NET_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); + + return(_data == WIFI_SPI_ACK) ? WL_SUCCESS : WL_FAILURE; +} + +int8_t WiFiDrv::wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_2); + SpiDrv::sendParam((uint8_t*)ssid, ssid_len, NO_LAST_PARAM); + SpiDrv::sendParam((uint8_t*)passphrase, len, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(SET_PASSPHRASE_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); + return _data; +} + + +int8_t WiFiDrv::wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(SET_KEY_CMD, PARAM_NUMS_3); + SpiDrv::sendParam((uint8_t*)ssid, ssid_len, NO_LAST_PARAM); + SpiDrv::sendParam(&key_idx, KEY_IDX_LEN, NO_LAST_PARAM); + SpiDrv::sendParam((uint8_t*)key, len, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(SET_KEY_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); + return _data; +} + +void WiFiDrv::config(uint8_t validParams, uint32_t local_ip, uint32_t gateway, uint32_t subnet) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(SET_IP_CONFIG_CMD, PARAM_NUMS_4); + SpiDrv::sendParam((uint8_t*)&validParams, 1, NO_LAST_PARAM); + SpiDrv::sendParam((uint8_t*)&local_ip, 4, NO_LAST_PARAM); + SpiDrv::sendParam((uint8_t*)&gateway, 4, NO_LAST_PARAM); + SpiDrv::sendParam((uint8_t*)&subnet, 4, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(SET_IP_CONFIG_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); +} + +void WiFiDrv::setDNS(uint8_t validParams, uint32_t dns_server1, uint32_t dns_server2) +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(SET_DNS_CONFIG_CMD, PARAM_NUMS_3); + SpiDrv::sendParam((uint8_t*)&validParams, 1, NO_LAST_PARAM); + SpiDrv::sendParam((uint8_t*)&dns_server1, 4, NO_LAST_PARAM); + SpiDrv::sendParam((uint8_t*)&dns_server2, 4, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(SET_DNS_CONFIG_CMD, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + SpiDrv::spiSlaveDeselect(); +} + + + +int8_t WiFiDrv::disconnect() +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(DISCONNECT_CMD, PARAM_NUMS_1); + + uint8_t _dummy = DUMMY_DATA; + SpiDrv::sendParam(&_dummy, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + int8_t result = SpiDrv::waitResponseCmd(DISCONNECT_CMD, PARAM_NUMS_1, &_data, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return result; +} + +uint8_t WiFiDrv::getConnectionStatus() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_0); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = -1; + uint8_t _dataLen = 0; + SpiDrv::waitResponseCmd(GET_CONN_STATUS_CMD, PARAM_NUMS_1, &_data, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return _data; +} + +uint8_t* WiFiDrv::getMacAddress() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_MACADDR_CMD, PARAM_NUMS_1); + + uint8_t _dummy = DUMMY_DATA; + SpiDrv::sendParam(&_dummy, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _dataLen = 0; + SpiDrv::waitResponseCmd(GET_MACADDR_CMD, PARAM_NUMS_1, _mac, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return _mac; +} + +void WiFiDrv::getIpAddress(IPAddress& ip) +{ + getNetworkData(_localIp, _subnetMask, _gatewayIp); + ip = _localIp; +} + + void WiFiDrv::getSubnetMask(IPAddress& mask) + { + getNetworkData(_localIp, _subnetMask, _gatewayIp); + mask = _subnetMask; + } + + void WiFiDrv::getGatewayIP(IPAddress& ip) + { + getNetworkData(_localIp, _subnetMask, _gatewayIp); + ip = _gatewayIp; + } + +char* WiFiDrv::getCurrentSSID() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_CURR_SSID_CMD, PARAM_NUMS_1); + + uint8_t _dummy = DUMMY_DATA; + SpiDrv::sendParam(&_dummy, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _dataLen = 0; + SpiDrv::waitResponseCmd(GET_CURR_SSID_CMD, PARAM_NUMS_1, (uint8_t*)_ssid, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return _ssid; +} + +uint8_t* WiFiDrv::getCurrentBSSID() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_1); + + uint8_t _dummy = DUMMY_DATA; + SpiDrv::sendParam(&_dummy, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _dataLen = 0; + SpiDrv::waitResponseCmd(GET_CURR_BSSID_CMD, PARAM_NUMS_1, _bssid, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return _bssid; +} + +int32_t WiFiDrv::getCurrentRSSI() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_1); + + uint8_t _dummy = DUMMY_DATA; + SpiDrv::sendParam(&_dummy, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _dataLen = 0; + int32_t rssi = 0; + SpiDrv::waitResponseCmd(GET_CURR_RSSI_CMD, PARAM_NUMS_1, (uint8_t*)&rssi, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return rssi; +} + +uint8_t WiFiDrv::getCurrentEncryptionType() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_CURR_ENCT_CMD, PARAM_NUMS_1); + + uint8_t _dummy = DUMMY_DATA; + SpiDrv::sendParam(&_dummy, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t dataLen = 0; + uint8_t encType = 0; + SpiDrv::waitResponseCmd(GET_CURR_ENCT_CMD, PARAM_NUMS_1, (uint8_t*)&encType, &dataLen); + + SpiDrv::spiSlaveDeselect(); + + return encType; +} + +int8_t WiFiDrv::startScanNetworks() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(START_SCAN_NETWORKS, PARAM_NUMS_0); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + + if (!SpiDrv::waitResponseCmd(START_SCAN_NETWORKS, PARAM_NUMS_1, &_data, &_dataLen)) + { + WARN("error waitResponse"); + _data = WL_FAILURE; + } + + SpiDrv::spiSlaveDeselect(); + + return (_data == WL_FAILURE)? _data : WL_SUCCESS; +} + + +uint8_t WiFiDrv::getScanNetworks() +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(SCAN_NETWORKS, PARAM_NUMS_0); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t ssidListNum = 0; + SpiDrv::waitResponse(SCAN_NETWORKS, &ssidListNum, (uint8_t**)_networkSsid, WL_NETWORKS_LIST_MAXNUM); + + SpiDrv::spiSlaveDeselect(); + + return ssidListNum; +} + +char* WiFiDrv::getSSIDNetoworks(uint8_t networkItem) +{ + if (networkItem >= WL_NETWORKS_LIST_MAXNUM) + return NULL; + + return _networkSsid[networkItem]; +} + +uint8_t WiFiDrv::getEncTypeNetowrks(uint8_t networkItem) +{ + if (networkItem >= WL_NETWORKS_LIST_MAXNUM) + return NULL; + + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_IDX_ENCT_CMD, PARAM_NUMS_1); + + SpiDrv::sendParam(&networkItem, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t dataLen = 0; + uint8_t encType = 0; + SpiDrv::waitResponseCmd(GET_IDX_ENCT_CMD, PARAM_NUMS_1, (uint8_t*)&encType, &dataLen); + + SpiDrv::spiSlaveDeselect(); + + return encType; +} + +int32_t WiFiDrv::getRSSINetoworks(uint8_t networkItem) +{ + if (networkItem >= WL_NETWORKS_LIST_MAXNUM) + return NULL; + int32_t networkRssi = 0; + + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(GET_IDX_RSSI_CMD, PARAM_NUMS_1); + + SpiDrv::sendParam(&networkItem, 1, LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t dataLen = 0; + SpiDrv::waitResponseCmd(GET_IDX_RSSI_CMD, PARAM_NUMS_1, (uint8_t*)&networkRssi, &dataLen); + + SpiDrv::spiSlaveDeselect(); + + return networkRssi; +} + +uint8_t WiFiDrv::reqHostByName(const char* aHostname) +{ + WAIT_FOR_SLAVE_SELECT(); + + // Send Command + SpiDrv::sendCmd(REQ_HOST_BY_NAME_CMD, PARAM_NUMS_1); + SpiDrv::sendParam((uint8_t*)aHostname, strlen(aHostname), LAST_PARAM); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _data = 0; + uint8_t _dataLen = 0; + uint8_t result = SpiDrv::waitResponseCmd(REQ_HOST_BY_NAME_CMD, PARAM_NUMS_1, &_data, &_dataLen); + + SpiDrv::spiSlaveDeselect(); + + return result; +} + +int WiFiDrv::getHostByName(IPAddress& aResult) +{ + uint8_t _ipAddr[WL_IPV4_LENGTH]; + IPAddress dummy(0xFF,0xFF,0xFF,0xFF); + int result = 0; + + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(GET_HOST_BY_NAME_CMD, PARAM_NUMS_0); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(GET_HOST_BY_NAME_CMD, PARAM_NUMS_1, _ipAddr, &_dataLen)) + { + WARN("error waitResponse"); + }else{ + aResult = _ipAddr; + result = (aResult != dummy); + } + SpiDrv::spiSlaveDeselect(); + return result; +} + +int WiFiDrv::getHostByName(const char* aHostname, IPAddress& aResult) +{ + uint8_t retry = 10; + if (reqHostByName(aHostname)) + { + while(!getHostByName(aResult) && --retry > 0) + { + delay(1000); + } + }else{ + return 0; + } + return (retry>0); +} + +char* WiFiDrv::getFwVersion() +{ + WAIT_FOR_SLAVE_SELECT(); + // Send Command + SpiDrv::sendCmd(GET_FW_VERSION_CMD, PARAM_NUMS_0); + + //Wait the reply elaboration + SpiDrv::waitForSlaveReady(); + + // Wait for reply + uint8_t _dataLen = 0; + if (!SpiDrv::waitResponseCmd(GET_FW_VERSION_CMD, PARAM_NUMS_1, (uint8_t*)fwVersion, &_dataLen)) + { + WARN("error waitResponse"); + } + SpiDrv::spiSlaveDeselect(); + return fwVersion; +} + +WiFiDrv wiFiDrv; diff --git a/libraries/WiFi/utility/wifi_drv.h b/libraries/WiFi/utility/wifi_drv.h index c4f04db..d6ec029 100644 --- a/libraries/WiFi/utility/wifi_drv.h +++ b/libraries/WiFi/utility/wifi_drv.h @@ -1,219 +1,248 @@ -#ifndef WiFi_Drv_h
-#define WiFi_Drv_h
-
-#include <inttypes.h>
-#include "wifi_spi.h"
-#include "IPAddress.h"
-
-// Key index length
-#define KEY_IDX_LEN 1
-// 5 secs of delay to have the connection established
-#define WL_DELAY_START_CONNECTION 5000
-// firmware version string length
-#define WL_FW_VER_LENGTH 6
-
-class WiFiDrv
-{
-private:
- // settings of requested network
- static char _networkSsid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH];
- static int32_t _networkRssi[WL_NETWORKS_LIST_MAXNUM];
- static uint8_t _networkEncr[WL_NETWORKS_LIST_MAXNUM];
-
- // firmware version string in the format a.b.c
- static char fwVersion[WL_FW_VER_LENGTH];
-
- // settings of current selected network
- static char _ssid[WL_SSID_MAX_LENGTH];
- static uint8_t _bssid[WL_MAC_ADDR_LENGTH];
- static uint8_t _mac[WL_MAC_ADDR_LENGTH];
- static uint8_t _localIp[WL_IPV4_LENGTH];
- static uint8_t _subnetMask[WL_IPV4_LENGTH];
- static uint8_t _gatewayIp[WL_IPV4_LENGTH];
-
- /*
- * Get network Data information
- */
- static void getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip);
-
- static uint8_t reqHostByName(const char* aHostname);
-
- static int getHostByName(IPAddress& aResult);
-
-public:
-
- /*
- * Driver initialization
- */
- static void wifiDriverInit();
-
- /*
- * Set the desired network which the connection manager should try to
- * connect to.
- *
- * The ssid of the desired network should be specified.
- *
- * param ssid: The ssid of the desired network.
- * param ssid_len: Lenght of ssid string.
- * return: WL_SUCCESS or WL_FAILURE
- */
- static int8_t wifiSetNetwork(char* ssid, uint8_t ssid_len);
-
- /* Start Wifi connection with passphrase
- * the most secure supported mode will be automatically selected
- *
- * param ssid: Pointer to the SSID string.
- * param ssid_len: Lenght of ssid string.
- * param passphrase: Passphrase. Valid characters in a passphrase
- * must be between ASCII 32-126 (decimal).
- * param len: Lenght of passphrase string.
- * return: WL_SUCCESS or WL_FAILURE
- */
- static int8_t wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len);
-
- /* Start Wifi connection with WEP encryption.
- * Configure a key into the device. The key type (WEP-40, WEP-104)
- * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104).
- *
- * param ssid: Pointer to the SSID string.
- * param ssid_len: Lenght of ssid string.
- * param key_idx: The key index to set. Valid values are 0-3.
- * param key: Key input buffer.
- * param len: Lenght of key string.
- * return: WL_SUCCESS or WL_FAILURE
- */
- static int8_t wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len);
-
- /*
- * Disconnect from the network
- *
- * return: WL_SUCCESS or WL_FAILURE
- */
- static int8_t disconnect();
-
- /*
- * Disconnect from the network
- *
- * return: one value of wl_status_t enum
- */
- static uint8_t getConnectionStatus();
-
- /*
- * Get the interface MAC address.
- *
- * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
- */
- static uint8_t* getMacAddress();
-
- /*
- * Get the interface IP address.
- *
- * return: copy the ip address value in IPAddress object
- */
- static void getIpAddress(IPAddress& ip);
-
- /*
- * Get the interface subnet mask address.
- *
- * return: copy the subnet mask address value in IPAddress object
- */
- static void getSubnetMask(IPAddress& mask);
-
- /*
- * Get the gateway ip address.
- *
- * return: copy the gateway ip address value in IPAddress object
- */
- static void getGatewayIP(IPAddress& ip);
-
- /*
- * Return the current SSID associated with the network
- *
- * return: ssid string
- */
- static char* getCurrentSSID();
-
- /*
- * Return the current BSSID associated with the network.
- * It is the MAC address of the Access Point
- *
- * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH
- */
- static uint8_t* getCurrentBSSID();
-
- /*
- * Return the current RSSI /Received Signal Strength in dBm)
- * associated with the network
- *
- * return: signed value
- */
- static int32_t getCurrentRSSI();
-
- /*
- * Return the Encryption Type associated with the network
- *
- * return: one value of wl_enc_type enum
- */
- static uint8_t getCurrentEncryptionType();
-
- /*
- * Start scan WiFi networks available
- *
- * return: Number of discovered networks
- */
- static int8_t startScanNetworks();
-
- /*
- * Get the networks available
- *
- * return: Number of discovered networks
- */
- static uint8_t getScanNetworks();
-
- /*
- * Return the SSID discovered during the network scan.
- *
- * param networkItem: specify from which network item want to get the information
- *
- * return: ssid string of the specified item on the networks scanned list
- */
- static char* getSSIDNetoworks(uint8_t networkItem);
-
- /*
- * Return the RSSI of the networks discovered during the scanNetworks
- *
- * param networkItem: specify from which network item want to get the information
- *
- * return: signed value of RSSI of the specified item on the networks scanned list
- */
- static int32_t getRSSINetoworks(uint8_t networkItem);
-
- /*
- * Return the encryption type of the networks discovered during the scanNetworks
- *
- * param networkItem: specify from which network item want to get the information
- *
- * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list
- */
- static uint8_t getEncTypeNetowrks(uint8_t networkItem);
-
- /*
- * Resolve the given hostname to an IP address.
- * param aHostname: Name to be resolved
- * param aResult: IPAddress structure to store the returned IP address
- * result: 1 if aIPAddrString was successfully converted to an IP address,
- * else error code
- */
- static int getHostByName(const char* aHostname, IPAddress& aResult);
-
- /*
- * Get the firmware version
- * result: version as string with this format a.b.c
- */
- static char* getFwVersion();
-
-};
-
-extern WiFiDrv wiFiDrv;
-
-#endif
+#ifndef WiFi_Drv_h +#define WiFi_Drv_h + +#include <inttypes.h> +#include "wifi_spi.h" +#include "IPAddress.h" +#include "../WiFiUdp.h"
+ +// Key index length +#define KEY_IDX_LEN 1 +// 5 secs of delay to have the connection established +#define WL_DELAY_START_CONNECTION 5000 +// firmware version string length +#define WL_FW_VER_LENGTH 6 + +class WiFiDrv +{ +private: + // settings of requested network + static char _networkSsid[WL_NETWORKS_LIST_MAXNUM][WL_SSID_MAX_LENGTH]; + static int32_t _networkRssi[WL_NETWORKS_LIST_MAXNUM]; + static uint8_t _networkEncr[WL_NETWORKS_LIST_MAXNUM]; + + // firmware version string in the format a.b.c + static char fwVersion[WL_FW_VER_LENGTH]; + + // settings of current selected network + static char _ssid[WL_SSID_MAX_LENGTH]; + static uint8_t _bssid[WL_MAC_ADDR_LENGTH]; + static uint8_t _mac[WL_MAC_ADDR_LENGTH]; + static uint8_t _localIp[WL_IPV4_LENGTH]; + static uint8_t _subnetMask[WL_IPV4_LENGTH]; + static uint8_t _gatewayIp[WL_IPV4_LENGTH]; + + /* + * Get network Data information + */ + static void getNetworkData(uint8_t *ip, uint8_t *mask, uint8_t *gwip); + + static uint8_t reqHostByName(const char* aHostname); + + static int getHostByName(IPAddress& aResult); + + /*
+ * Get remote Data information on UDP socket
+ */
+ static void getRemoteData(uint8_t sock, uint8_t *ip, uint8_t *port);
+
+public: + + /* + * Driver initialization + */ + static void wifiDriverInit(); + + /* + * Set the desired network which the connection manager should try to + * connect to. + * + * The ssid of the desired network should be specified. + * + * param ssid: The ssid of the desired network. + * param ssid_len: Lenght of ssid string. + * return: WL_SUCCESS or WL_FAILURE + */ + static int8_t wifiSetNetwork(char* ssid, uint8_t ssid_len); + + /* Start Wifi connection with passphrase + * the most secure supported mode will be automatically selected + * + * param ssid: Pointer to the SSID string. + * param ssid_len: Lenght of ssid string. + * param passphrase: Passphrase. Valid characters in a passphrase + * must be between ASCII 32-126 (decimal). + * param len: Lenght of passphrase string. + * return: WL_SUCCESS or WL_FAILURE + */ + static int8_t wifiSetPassphrase(char* ssid, uint8_t ssid_len, const char *passphrase, const uint8_t len); + + /* Start Wifi connection with WEP encryption. + * Configure a key into the device. The key type (WEP-40, WEP-104) + * is determined by the size of the key (5 bytes for WEP-40, 13 bytes for WEP-104). + * + * param ssid: Pointer to the SSID string. + * param ssid_len: Lenght of ssid string. + * param key_idx: The key index to set. Valid values are 0-3. + * param key: Key input buffer. + * param len: Lenght of key string. + * return: WL_SUCCESS or WL_FAILURE + */ + static int8_t wifiSetKey(char* ssid, uint8_t ssid_len, uint8_t key_idx, const void *key, const uint8_t len); + + /* Set ip configuration disabling dhcp client + * + * param validParams: set the number of parameters that we want to change + * i.e. validParams = 1 means that we'll change only ip address + * validParams = 3 means that we'll change ip address, gateway and netmask + * param local_ip: Static ip configuration + * param gateway: Static gateway configuration + * param subnet: Static subnet mask configuration + */ + static void config(uint8_t validParams, uint32_t local_ip, uint32_t gateway, uint32_t subnet); + + /* Set DNS ip configuration + * + * param validParams: set the number of parameters that we want to change + * i.e. validParams = 1 means that we'll change only dns_server1 + * validParams = 2 means that we'll change dns_server1 and dns_server2 + * param dns_server1: Static DNS server1 configuration + * param dns_server2: Static DNS server2 configuration + */ + static void setDNS(uint8_t validParams, uint32_t dns_server1, uint32_t dns_server2); + + /* + * Disconnect from the network + * + * return: WL_SUCCESS or WL_FAILURE + */ + static int8_t disconnect(); + + /* + * Disconnect from the network + * + * return: one value of wl_status_t enum + */ + static uint8_t getConnectionStatus(); + + /* + * Get the interface MAC address. + * + * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + */ + static uint8_t* getMacAddress(); + + /* + * Get the interface IP address. + * + * return: copy the ip address value in IPAddress object + */ + static void getIpAddress(IPAddress& ip); + + /* + * Get the interface subnet mask address. + * + * return: copy the subnet mask address value in IPAddress object + */ + static void getSubnetMask(IPAddress& mask); + + /* + * Get the gateway ip address. + * + * return: copy the gateway ip address value in IPAddress object + */ + static void getGatewayIP(IPAddress& ip); + + /* + * Return the current SSID associated with the network + * + * return: ssid string + */ + static char* getCurrentSSID(); + + /* + * Return the current BSSID associated with the network. + * It is the MAC address of the Access Point + * + * return: pointer to uint8_t array with length WL_MAC_ADDR_LENGTH + */ + static uint8_t* getCurrentBSSID(); + + /* + * Return the current RSSI /Received Signal Strength in dBm) + * associated with the network + * + * return: signed value + */ + static int32_t getCurrentRSSI(); + + /* + * Return the Encryption Type associated with the network + * + * return: one value of wl_enc_type enum + */ + static uint8_t getCurrentEncryptionType(); + + /* + * Start scan WiFi networks available + * + * return: Number of discovered networks + */ + static int8_t startScanNetworks(); + + /* + * Get the networks available + * + * return: Number of discovered networks + */ + static uint8_t getScanNetworks(); + + /* + * Return the SSID discovered during the network scan. + * + * param networkItem: specify from which network item want to get the information + * + * return: ssid string of the specified item on the networks scanned list + */ + static char* getSSIDNetoworks(uint8_t networkItem); + + /* + * Return the RSSI of the networks discovered during the scanNetworks + * + * param networkItem: specify from which network item want to get the information + * + * return: signed value of RSSI of the specified item on the networks scanned list + */ + static int32_t getRSSINetoworks(uint8_t networkItem); + + /* + * Return the encryption type of the networks discovered during the scanNetworks + * + * param networkItem: specify from which network item want to get the information + * + * return: encryption type (enum wl_enc_type) of the specified item on the networks scanned list + */ + static uint8_t getEncTypeNetowrks(uint8_t networkItem); + + /* + * Resolve the given hostname to an IP address. + * param aHostname: Name to be resolved + * param aResult: IPAddress structure to store the returned IP address + * result: 1 if aIPAddrString was successfully converted to an IP address, + * else error code + */ + static int getHostByName(const char* aHostname, IPAddress& aResult); + + /* + * Get the firmware version + * result: version as string with this format a.b.c + */ + static char* getFwVersion(); + + friend class WiFiUDP;
+
+}; + +extern WiFiDrv wiFiDrv; + +#endif diff --git a/libraries/WiFi/utility/wifi_spi.h b/libraries/WiFi/utility/wifi_spi.h index bf479e2..8856e33 100644 --- a/libraries/WiFi/utility/wifi_spi.h +++ b/libraries/WiFi/utility/wifi_spi.h @@ -1,144 +1,153 @@ -#ifndef WiFi_Spi_h
-#define WiFi_Spi_h
-
-#include "wl_definitions.h"
-
-#define CMD_FLAG 0
-#define REPLY_FLAG 1<<7
-#define DATA_FLAG 0x40
-
-#define WIFI_SPI_ACK 1
-#define WIFI_SPI_ERR 0xFF
-
-#define TIMEOUT_CHAR 1000
-
-//#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */
-#define NO_SOCKET_AVAIL 255
-
-#define START_CMD 0xE0
-#define END_CMD 0xEE
-#define ERR_CMD 0xEF
-
-enum {
- SET_NET_CMD = 0x10,
- SET_PASSPHRASE_CMD = 0x11,
- SET_KEY_CMD = 0x12,
- TEST_CMD = 0x13,
-
- GET_CONN_STATUS_CMD = 0x20,
- GET_IPADDR_CMD = 0x21,
- GET_MACADDR_CMD = 0x22,
- GET_CURR_SSID_CMD = 0x23,
- GET_CURR_BSSID_CMD = 0x24,
- GET_CURR_RSSI_CMD = 0x25,
- GET_CURR_ENCT_CMD = 0x26,
- SCAN_NETWORKS = 0x27,
- START_SERVER_TCP_CMD= 0x28,
- GET_STATE_TCP_CMD = 0x29,
- DATA_SENT_TCP_CMD = 0x2A,
- AVAIL_DATA_TCP_CMD = 0x2B,
- GET_DATA_TCP_CMD = 0x2C,
- START_CLIENT_TCP_CMD= 0x2D,
- STOP_CLIENT_TCP_CMD = 0x2E,
- GET_CLIENT_STATE_TCP_CMD= 0x2F,
- DISCONNECT_CMD = 0x30,
- GET_IDX_SSID_CMD = 0x31,
- GET_IDX_RSSI_CMD = 0x32,
- GET_IDX_ENCT_CMD = 0x33,
- REQ_HOST_BY_NAME_CMD= 0x34,
- GET_HOST_BY_NAME_CMD= 0x35,
- START_SCAN_NETWORKS = 0x36,
- GET_FW_VERSION_CMD = 0x37,
-
- // All command with DATA_FLAG 0x40 send a 16bit Len
-
- SEND_DATA_TCP_CMD = 0x44,
- GET_DATABUF_TCP_CMD = 0x45,
-};
-
-
-enum wl_tcp_state {
- CLOSED = 0,
- LISTEN = 1,
- SYN_SENT = 2,
- SYN_RCVD = 3,
- ESTABLISHED = 4,
- FIN_WAIT_1 = 5,
- FIN_WAIT_2 = 6,
- CLOSE_WAIT = 7,
- CLOSING = 8,
- LAST_ACK = 9,
- TIME_WAIT = 10
-};
-
-
-enum numParams{
- PARAM_NUMS_0,
- PARAM_NUMS_1,
- PARAM_NUMS_2,
- PARAM_NUMS_3,
- PARAM_NUMS_4,
- PARAM_NUMS_5,
- MAX_PARAM_NUMS
-};
-
-#define MAX_PARAMS MAX_PARAM_NUMS-1
-#define PARAM_LEN_SIZE 1
-
-typedef struct __attribute__((__packed__))
-{
- uint8_t paramLen;
- char* param;
-}tParam;
-
-typedef struct __attribute__((__packed__))
-{
- uint16_t dataLen;
- char* data;
-}tDataParam;
-
-
-typedef struct __attribute__((__packed__))
-{
- unsigned char cmd;
- unsigned char tcmd;
- unsigned char nParam;
- tParam params[MAX_PARAMS];
-}tSpiMsg;
-
-typedef struct __attribute__((__packed__))
-{
- unsigned char cmd;
- unsigned char tcmd;
- unsigned char nParam;
- tDataParam params[MAX_PARAMS];
-}tSpiMsgData;
-
-
-typedef struct __attribute__((__packed__))
-{
- unsigned char cmd;
- unsigned char tcmd;
- //unsigned char totLen;
- unsigned char nParam;
-}tSpiHdr;
-
-typedef struct __attribute__((__packed__))
-{
- uint8_t paramLen;
- uint32_t param;
-}tLongParam;
-
-typedef struct __attribute__((__packed__))
-{
- uint8_t paramLen;
- uint16_t param;
-}tIntParam;
-
-typedef struct __attribute__((__packed__))
-{
- uint8_t paramLen;
- uint8_t param;
-}tByteParam;
-
-#endif
+#ifndef WiFi_Spi_h +#define WiFi_Spi_h + +#include "wl_definitions.h" + +#define CMD_FLAG 0 +#define REPLY_FLAG 1<<7 +#define DATA_FLAG 0x40 + +#define WIFI_SPI_ACK 1 +#define WIFI_SPI_ERR 0xFF + +#define TIMEOUT_CHAR 1000 + +//#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */ +#define NO_SOCKET_AVAIL 255 + +#define START_CMD 0xE0 +#define END_CMD 0xEE +#define ERR_CMD 0xEF +#define CMD_POS 1 // Position of Command OpCode on SPI stream +#define PARAM_LEN_POS 2 // Position of Param len on SPI stream + + +enum { + SET_NET_CMD = 0x10, + SET_PASSPHRASE_CMD = 0x11, + SET_KEY_CMD = 0x12, + TEST_CMD = 0x13, + SET_IP_CONFIG_CMD = 0x14, + SET_DNS_CONFIG_CMD = 0x15, + + GET_CONN_STATUS_CMD = 0x20, + GET_IPADDR_CMD = 0x21, + GET_MACADDR_CMD = 0x22, + GET_CURR_SSID_CMD = 0x23, + GET_CURR_BSSID_CMD = 0x24, + GET_CURR_RSSI_CMD = 0x25, + GET_CURR_ENCT_CMD = 0x26, + SCAN_NETWORKS = 0x27, + START_SERVER_TCP_CMD= 0x28, + GET_STATE_TCP_CMD = 0x29, + DATA_SENT_TCP_CMD = 0x2A, + AVAIL_DATA_TCP_CMD = 0x2B, + GET_DATA_TCP_CMD = 0x2C, + START_CLIENT_TCP_CMD= 0x2D, + STOP_CLIENT_TCP_CMD = 0x2E, + GET_CLIENT_STATE_TCP_CMD= 0x2F, + DISCONNECT_CMD = 0x30, + GET_IDX_SSID_CMD = 0x31, + GET_IDX_RSSI_CMD = 0x32, + GET_IDX_ENCT_CMD = 0x33, + REQ_HOST_BY_NAME_CMD= 0x34, + GET_HOST_BY_NAME_CMD= 0x35, + START_SCAN_NETWORKS = 0x36, + GET_FW_VERSION_CMD = 0x37, + GET_TEST_CMD = 0x38, + SEND_DATA_UDP_CMD = 0x39, + GET_REMOTE_DATA_CMD = 0x3A,
+ + // All command with DATA_FLAG 0x40 send a 16bit Len + + SEND_DATA_TCP_CMD = 0x44, + GET_DATABUF_TCP_CMD = 0x45, + INSERT_DATABUF_CMD = 0x46, +}; + + +enum wl_tcp_state { + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 +}; + + +enum numParams{ + PARAM_NUMS_0, + PARAM_NUMS_1, + PARAM_NUMS_2, + PARAM_NUMS_3, + PARAM_NUMS_4, + PARAM_NUMS_5, + MAX_PARAM_NUMS +}; + +#define MAX_PARAMS MAX_PARAM_NUMS-1 +#define PARAM_LEN_SIZE 1 + +typedef struct __attribute__((__packed__)) +{ + uint8_t paramLen; + char* param; +}tParam; + +typedef struct __attribute__((__packed__)) +{ + uint16_t dataLen; + char* data; +}tDataParam; + + +typedef struct __attribute__((__packed__)) +{ + unsigned char cmd; + unsigned char tcmd; + unsigned char nParam; + tParam params[MAX_PARAMS]; +}tSpiMsg; + +typedef struct __attribute__((__packed__)) +{ + unsigned char cmd; + unsigned char tcmd; + unsigned char nParam; + tDataParam params[MAX_PARAMS]; +}tSpiMsgData; + + +typedef struct __attribute__((__packed__)) +{ + unsigned char cmd; + unsigned char tcmd; + //unsigned char totLen; + unsigned char nParam; +}tSpiHdr; + +typedef struct __attribute__((__packed__)) +{ + uint8_t paramLen; + uint32_t param; +}tLongParam; + +typedef struct __attribute__((__packed__)) +{ + uint8_t paramLen; + uint16_t param; +}tIntParam; + +typedef struct __attribute__((__packed__)) +{ + uint8_t paramLen; + uint8_t param; +}tByteParam; + +#endif diff --git a/libraries/WiFi/utility/wl_definitions.h b/libraries/WiFi/utility/wl_definitions.h index 15de781..1ec8e71 100644 --- a/libraries/WiFi/utility/wl_definitions.h +++ b/libraries/WiFi/utility/wl_definitions.h @@ -22,6 +22,8 @@ #define WL_NETWORKS_LIST_MAXNUM 10 // Maxmium number of socket #define MAX_SOCK_NUM 4 +// Default state value for Wifi state field +#define NA_STATE -1 //Maximum number of attempts to establish wifi connection #define WL_MAX_ATTEMPT_CONNECTION 10 diff --git a/libraries/Wire/utility/twi.c b/libraries/Wire/utility/twi.c index 6b2db3c..201d7d1 100644 --- a/libraries/Wire/utility/twi.c +++ b/libraries/Wire/utility/twi.c @@ -360,7 +360,7 @@ void twi_releaseBus(void) twi_state = TWI_READY; } -SIGNAL(TWI_vect) +ISR(TWI_vect) { switch(TW_STATUS){ // All Master |