/* This file is part of the GSM3 communications library for Arduino -- Multi-transport communications platform -- Fully asynchronous -- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 -- Voice calls -- SMS -- TCP/IP connections -- HTTP basic clients This library has been developed by Telefónica Digital - PDI - - Physical Internet Lab, as part as its collaboration with Arduino and the Open Hardware Community. September-December 2012 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA The latest version of this library can always be found at https://github.com/BlueVia/Official-Arduino */ #include #include 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 //SerialUSB.println("Beginning extractSubstring"); //SerialUSB.print("head,tail=");SerialUSB.print(int(head));SerialUSB.print(",");SerialUSB.println(int(tail)); if(!locate(from, head, tail, 0, &t1)) return false; //DEBUG //SerialUSB.println("Located chain from."); t1++; //To point the next. if(!locate(to, t1, tail, &h2, 0)) return false; //DEBUG //SerialUSB.println("Located chain to."); /*SerialUSB.print("t1=");SerialUSB.println(int(t1)); SerialUSB.print("h2=");SerialUSB.println(int(h2));*/ for(i=0,b=t1;i='0')&&(c<='9')) { anyfound=true; res=(res*10)+(int)c-48; } else { if(negative) res=(-1)*res; return res; } } if(negative) res=(-1)*res; return res; } void GSM3CircularBuffer::debugBuffer() { byte h1=head; byte t1=tail; SerialUSB.println(); SerialUSB.print(h1); SerialUSB.print(" "); SerialUSB.print(t1); SerialUSB.print('>'); for(byte b=h1; b!=t1; b=(b+1)& __BUFFERMASK__) printCharDebug(theBuffer[b]); SerialUSB.println(); } void GSM3CircularBuffer::printCharDebug(uint8_t c) { if((c>31)&&(c<127)) SerialUSB.print((char)c); else { SerialUSB.print('%'); SerialUSB.print(c); SerialUSB.print('%'); } } bool GSM3CircularBuffer::retrieveBuffer(char* buffer, int bufsize, int& SizeWritten) { byte b; int i; /*for(i=0,b=head;i