Arduino/libraries/GSM/GSM3CircularBuffer.h

205 lines
5.8 KiB
C++

/*
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