|
| 1 | +/* |
| 2 | +This file is part of the GSM3 communications library for Arduino |
| 3 | +-- Multi-transport communications platform |
| 4 | +-- Fully asynchronous |
| 5 | +-- Includes code for the Arduino-Telefonica GSM/GPRS Shield V1 |
| 6 | +-- Voice calls |
| 7 | +-- SMS |
| 8 | +-- TCP/IP connections |
| 9 | +-- HTTP basic clients |
| 10 | +
|
| 11 | +This library has been developed by Telefónica Digital - PDI - |
| 12 | +- Physical Internet Lab, as part as its collaboration with |
| 13 | +Arduino and the Open Hardware Community. |
| 14 | +
|
| 15 | +September-December 2012 |
| 16 | +
|
| 17 | +This library is free software; you can redistribute it and/or |
| 18 | +modify it under the terms of the GNU Lesser General Public |
| 19 | +License as published by the Free Software Foundation; either |
| 20 | +version 2.1 of the License, or (at your option) any later version. |
| 21 | +
|
| 22 | +This library is distributed in the hope that it will be useful, |
| 23 | +but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 24 | +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 25 | +Lesser General Public License for more details. |
| 26 | +
|
| 27 | +You should have received a copy of the GNU Lesser General Public |
| 28 | +License along with this library; if not, write to the Free Software |
| 29 | +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 30 | +
|
| 31 | +The latest version of this library can always be found at |
| 32 | +https://github.com/BlueVia/Official-Arduino |
| 33 | +*/ |
| 34 | +#include "GSM3CircularBuffer.h" |
| 35 | +#include <HardwareSerial.h> |
| 36 | + |
| 37 | +GSM3CircularBuffer::GSM3CircularBuffer(GSM3CircularBufferManager* mgr) |
| 38 | +{ |
| 39 | + head=0; |
| 40 | + tail=0; |
| 41 | + cbm=mgr; |
| 42 | +} |
| 43 | + |
| 44 | +int GSM3CircularBuffer::write(char c) |
| 45 | +{ |
| 46 | + byte aux=(tail+1)& __BUFFERMASK__; |
| 47 | + if(aux!=head) |
| 48 | + { |
| 49 | + theBuffer[tail]=c; |
| 50 | + // Lets put an extra zero at the end, so we can |
| 51 | + // read chains as we like. |
| 52 | + // This is not exactly perfect, we are always 1+ behind the head |
| 53 | + theBuffer[aux]=0; |
| 54 | + tail=aux; |
| 55 | + return 1; |
| 56 | + } |
| 57 | + return 0; |
| 58 | +} |
| 59 | + |
| 60 | +char GSM3CircularBuffer::read() |
| 61 | +{ |
| 62 | + char res; |
| 63 | + if(head!=tail) |
| 64 | + { |
| 65 | + res=theBuffer[head]; |
| 66 | + head=(head+1)& __BUFFERMASK__; |
| 67 | + //if(cbm) |
| 68 | + // cbm->spaceAvailable(); |
| 69 | + return res; |
| 70 | + } |
| 71 | + else |
| 72 | + { |
| 73 | + return 0; |
| 74 | + } |
| 75 | +} |
| 76 | + |
| 77 | +char GSM3CircularBuffer::peek(int increment) |
| 78 | +{ |
| 79 | + char res; |
| 80 | + byte num_aux; |
| 81 | + |
| 82 | + if (tail>head) num_aux = tail-head; |
| 83 | + else num_aux = 128 - head + tail; |
| 84 | + |
| 85 | + if(increment < num_aux) |
| 86 | + { |
| 87 | + res=theBuffer[head]; |
| 88 | + return res; |
| 89 | + } |
| 90 | + else |
| 91 | + { |
| 92 | + return 0; |
| 93 | + } |
| 94 | +} |
| 95 | + |
| 96 | +void GSM3CircularBufferManager::spaceAvailable(){return;}; |
| 97 | + |
| 98 | +void GSM3CircularBuffer::flush() |
| 99 | +{ |
| 100 | + head=tail; |
| 101 | +} |
| 102 | + |
| 103 | +char* GSM3CircularBuffer::nextString() |
| 104 | +{ |
| 105 | + while(head!=tail) |
| 106 | + { |
| 107 | + head=(head+1) & __BUFFERMASK__; |
| 108 | + if(theBuffer[head]==0) |
| 109 | + { |
| 110 | + head=(head+1) & __BUFFERMASK__; |
| 111 | + return (char*)theBuffer+head; |
| 112 | + } |
| 113 | + } |
| 114 | + return 0; |
| 115 | +} |
| 116 | + |
| 117 | + |
| 118 | +bool GSM3CircularBuffer::locate(const char* reference) |
| 119 | +{ |
| 120 | + |
| 121 | + return locate(reference, head, tail, 0, 0); |
| 122 | +} |
| 123 | + |
| 124 | +bool GSM3CircularBuffer::chopUntil(const char* reference, bool movetotheend, bool usehead) |
| 125 | +{ |
| 126 | + byte from, to; |
| 127 | + |
| 128 | + if(locate(reference, head, tail, &from, &to)) |
| 129 | + { |
| 130 | + if(usehead) |
| 131 | + { |
| 132 | + if(movetotheend) |
| 133 | + head=(to+1) & __BUFFERMASK__; |
| 134 | + else |
| 135 | + head=from; |
| 136 | + } |
| 137 | + else |
| 138 | + { |
| 139 | + if(movetotheend) |
| 140 | + tail=(to+1) & __BUFFERMASK__; |
| 141 | + else |
| 142 | + tail=from; |
| 143 | + } |
| 144 | + return true; |
| 145 | + } |
| 146 | + else |
| 147 | + { |
| 148 | + return false; |
| 149 | + } |
| 150 | +} |
| 151 | + |
| 152 | +bool GSM3CircularBuffer::locate(const char* reference, byte thishead, byte thistail, byte* from, byte* to) |
| 153 | +{ |
| 154 | + int refcursor=0; |
| 155 | + bool into=false; |
| 156 | + byte b2, binit; |
| 157 | + bool possible=1; |
| 158 | + |
| 159 | + if(reference[0]==0) |
| 160 | + return true; |
| 161 | + |
| 162 | + for(byte b1=thishead; b1!=thistail;b1=(b1+1)& __BUFFERMASK__) |
| 163 | + { |
| 164 | + possible = 1; |
| 165 | + b2 = b1; |
| 166 | + while (possible&&(b2!=thistail)) |
| 167 | + { |
| 168 | + if(theBuffer[b2]==reference[refcursor]) |
| 169 | + { |
| 170 | + if(!into) |
| 171 | + binit=b2; |
| 172 | + into=true; |
| 173 | + refcursor++; |
| 174 | + if(reference[refcursor]==0) |
| 175 | + { |
| 176 | + if(from) |
| 177 | + *from=binit; |
| 178 | + if(to) |
| 179 | + *to=b2; |
| 180 | + return true; |
| 181 | + } |
| 182 | + } |
| 183 | + else if (into==true) |
| 184 | + { |
| 185 | + possible = 0; |
| 186 | + into=false; |
| 187 | + refcursor=0; |
| 188 | + } |
| 189 | + b2=(b2+1)& __BUFFERMASK__; |
| 190 | + } |
| 191 | + } |
| 192 | + return false; |
| 193 | +} |
| 194 | + |
| 195 | +bool GSM3CircularBuffer::extractSubstring(const char* from, const char* to, char* buffer, int bufsize) |
| 196 | +{ |
| 197 | + byte t1; |
| 198 | + byte h2; |
| 199 | + byte b; |
| 200 | + int i; |
| 201 | + |
| 202 | +//DEBUG |
| 203 | +//Serial.println("Beginning extractSubstring"); |
| 204 | +//Serial.print("head,tail=");Serial.print(int(head));Serial.print(",");Serial.println(int(tail)); |
| 205 | + |
| 206 | + if(!locate(from, head, tail, 0, &t1)) |
| 207 | + return false; |
| 208 | + |
| 209 | +//DEBUG |
| 210 | +//Serial.println("Located chain from."); |
| 211 | + |
| 212 | + t1++; //To point the next. |
| 213 | + if(!locate(to, t1, tail, &h2, 0)) |
| 214 | + return false; |
| 215 | + |
| 216 | +//DEBUG |
| 217 | +//Serial.println("Located chain to."); |
| 218 | +/*Serial.print("t1=");Serial.println(int(t1)); |
| 219 | +Serial.print("h2=");Serial.println(int(h2));*/ |
| 220 | + |
| 221 | + |
| 222 | + for(i=0,b=t1;i<bufsize, b!=((h2) & __BUFFERMASK__); i++, b=(b+1)& __BUFFERMASK__) |
| 223 | + buffer[i]=theBuffer[b]; |
| 224 | + buffer[i]=0; |
| 225 | + |
| 226 | +//DEBUG |
| 227 | +//Serial.println(""); |
| 228 | +//Serial.println("Finishing extractSubstring"); |
| 229 | + |
| 230 | + return true; |
| 231 | +} |
| 232 | + |
| 233 | +int GSM3CircularBuffer::readInt() |
| 234 | +{ |
| 235 | + int res=0; |
| 236 | + byte c; |
| 237 | + bool anyfound=false; |
| 238 | + bool negative=false; |
| 239 | + for(byte b=head + 1; b!=tail; b=(b+1)& __BUFFERMASK__) |
| 240 | + { |
| 241 | + c=theBuffer[b]; |
| 242 | + if((c==' ' )&&(!anyfound)) |
| 243 | + { |
| 244 | + } else if((c=='-' )&&(!anyfound)) |
| 245 | + { |
| 246 | + negative=true; |
| 247 | + anyfound=true; // Don't admit blanks after - |
| 248 | + } else if((c>='0')&&(c<='9')) |
| 249 | + { |
| 250 | + anyfound=true; |
| 251 | + res=(res*10)+(int)c-48; |
| 252 | + } |
| 253 | + else |
| 254 | + { |
| 255 | + if(negative) |
| 256 | + res=(-1)*res; |
| 257 | + return res; |
| 258 | + } |
| 259 | + } |
| 260 | + if(negative) |
| 261 | + res=(-1)*res; |
| 262 | + return res; |
| 263 | +} |
| 264 | + |
| 265 | +void GSM3CircularBuffer::debugBuffer() |
| 266 | +{ |
| 267 | + byte h1=head; |
| 268 | + byte t1=tail; |
| 269 | + Serial.println(); |
| 270 | + Serial.print(h1); |
| 271 | + Serial.print(" "); |
| 272 | + Serial.print(t1); |
| 273 | + Serial.print('>'); |
| 274 | + for(byte b=h1; b!=t1; b=(b+1)& __BUFFERMASK__) |
| 275 | + printCharDebug(theBuffer[b]); |
| 276 | + Serial.println(); |
| 277 | +} |
| 278 | + |
| 279 | +void GSM3CircularBuffer::printCharDebug(uint8_t c) |
| 280 | +{ |
| 281 | + if((c>31)&&(c<127)) |
| 282 | + Serial.print((char)c); |
| 283 | + else |
| 284 | + { |
| 285 | + Serial.print('%'); |
| 286 | + Serial.print(c); |
| 287 | + Serial.print('%'); |
| 288 | + } |
| 289 | +} |
| 290 | + |
| 291 | +bool GSM3CircularBuffer::retrieveBuffer(char* buffer, int bufsize, int& SizeWritten) |
| 292 | +{ |
| 293 | + byte b; |
| 294 | + int i; |
| 295 | + |
| 296 | + /*for(i=0,b=head;i<bufsize, b!=tail; i++, b=(b+1)& __BUFFERMASK__) |
| 297 | + { |
| 298 | + buffer[i]=theBuffer[b]; |
| 299 | + } |
| 300 | + buffer[i]=0; |
| 301 | + SizeWritten = i;*/ |
| 302 | + b=head; |
| 303 | + for(i=0;i<bufsize; i++) |
| 304 | + { |
| 305 | + if (b!=tail) |
| 306 | + { |
| 307 | + buffer[i]=theBuffer[b]; |
| 308 | + buffer[i+1]=0; |
| 309 | + b=(b+1)& __BUFFERMASK__; |
| 310 | + SizeWritten = i + 1; |
| 311 | + } |
| 312 | + } |
| 313 | + |
| 314 | + |
| 315 | + return true; |
| 316 | +} |
| 317 | + |
| 318 | + |
| 319 | + |
0 commit comments