[175] | 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 <GSM3MobileClientService.h>
|
---|
| 35 | #include <GSM3MobileClientProvider.h>
|
---|
| 36 | #include <Arduino.h>
|
---|
| 37 |
|
---|
| 38 | // While there is only a shield (ShieldV1) we will include it by default
|
---|
| 39 | #include <GSM3ShieldV1ClientProvider.h>
|
---|
| 40 | GSM3ShieldV1ClientProvider theShieldV1ClientProvider;
|
---|
| 41 |
|
---|
| 42 |
|
---|
| 43 | #define GSM3MOBILECLIENTSERVICE_CLIENT 0x01 // 1: This side is Client. 0: This side is Server
|
---|
| 44 | #define GSM3MOBILECLIENTSERVICE_WRITING 0x02 // 1: TRUE 0: FALSE
|
---|
| 45 | #define GSM3MOBILECLIENTSERVICE_SYNCH 0x04 // 1: TRUE, compatible with other clients 0: FALSE
|
---|
| 46 |
|
---|
| 47 | #define __TOUTBEGINWRITE__ 10000
|
---|
| 48 |
|
---|
| 49 |
|
---|
| 50 | GSM3MobileClientService::GSM3MobileClientService(bool synch)
|
---|
| 51 | {
|
---|
| 52 | flags = GSM3MOBILECLIENTSERVICE_CLIENT;
|
---|
| 53 | if(synch)
|
---|
| 54 | flags |= GSM3MOBILECLIENTSERVICE_SYNCH;
|
---|
| 55 | mySocket=255;
|
---|
| 56 | }
|
---|
| 57 |
|
---|
| 58 | GSM3MobileClientService::GSM3MobileClientService(int socket, bool synch)
|
---|
| 59 | {
|
---|
| 60 | // We are creating a socket on an existing, occupied one.
|
---|
| 61 | flags=0;
|
---|
| 62 | if(synch)
|
---|
| 63 | flags |= GSM3MOBILECLIENTSERVICE_SYNCH;
|
---|
| 64 | mySocket=socket;
|
---|
| 65 | theGSM3MobileClientProvider->getSocket(socket);
|
---|
| 66 |
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | // Returns 0 if last command is still executing
|
---|
| 70 | // 1 if success
|
---|
| 71 | // >1 if error
|
---|
| 72 | int GSM3MobileClientService::ready()
|
---|
| 73 | {
|
---|
| 74 | return theGSM3MobileClientProvider->ready();
|
---|
| 75 | }
|
---|
| 76 |
|
---|
| 77 | int GSM3MobileClientService::connect(IPAddress add, uint16_t port)
|
---|
| 78 | {
|
---|
| 79 | if(theGSM3MobileClientProvider==0)
|
---|
| 80 | return 2;
|
---|
| 81 |
|
---|
| 82 | // TODO: ask for the socket id
|
---|
| 83 | mySocket=theGSM3MobileClientProvider->getSocket();
|
---|
| 84 |
|
---|
| 85 | if(mySocket<0)
|
---|
| 86 | return 2;
|
---|
| 87 |
|
---|
| 88 | int res=theGSM3MobileClientProvider->connectTCPClient(add, port, mySocket);
|
---|
| 89 | if(flags & GSM3MOBILECLIENTSERVICE_SYNCH)
|
---|
| 90 | res=waitForAnswer();
|
---|
| 91 |
|
---|
| 92 | return res;
|
---|
| 93 | };
|
---|
| 94 |
|
---|
| 95 | int GSM3MobileClientService::connect(const char *host, uint16_t port)
|
---|
| 96 | {
|
---|
| 97 |
|
---|
| 98 | if(theGSM3MobileClientProvider==0)
|
---|
| 99 | return 2;
|
---|
| 100 | // TODO: ask for the socket id
|
---|
| 101 | mySocket=theGSM3MobileClientProvider->getSocket();
|
---|
| 102 |
|
---|
| 103 | if(mySocket<0)
|
---|
| 104 | return 2;
|
---|
| 105 |
|
---|
| 106 | int res=theGSM3MobileClientProvider->connectTCPClient(host, port, mySocket);
|
---|
| 107 | if(flags & GSM3MOBILECLIENTSERVICE_SYNCH)
|
---|
| 108 | res=waitForAnswer();
|
---|
| 109 |
|
---|
| 110 | return res;
|
---|
| 111 | }
|
---|
| 112 |
|
---|
| 113 | int GSM3MobileClientService::waitForAnswer()
|
---|
| 114 | {
|
---|
| 115 | unsigned long m;
|
---|
| 116 | m=millis();
|
---|
| 117 | int res;
|
---|
| 118 |
|
---|
| 119 | while(((millis()-m)< __TOUTBEGINWRITE__ )&&(ready()==0))
|
---|
| 120 | delay(100);
|
---|
| 121 |
|
---|
| 122 | res=ready();
|
---|
| 123 |
|
---|
| 124 | // If we get something different from a 1, we are having a problem
|
---|
| 125 | if(res!=1)
|
---|
| 126 | res=0;
|
---|
| 127 |
|
---|
| 128 | return res;
|
---|
| 129 | }
|
---|
| 130 |
|
---|
| 131 | void GSM3MobileClientService::beginWrite(bool sync)
|
---|
| 132 | {
|
---|
| 133 | flags |= GSM3MOBILECLIENTSERVICE_WRITING;
|
---|
| 134 | theGSM3MobileClientProvider->beginWriteSocket(flags & GSM3MOBILECLIENTSERVICE_CLIENT, mySocket);
|
---|
| 135 | if(sync)
|
---|
| 136 | waitForAnswer();
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 | size_t GSM3MobileClientService::write(uint8_t c)
|
---|
| 140 | {
|
---|
| 141 | if(!(flags & GSM3MOBILECLIENTSERVICE_WRITING))
|
---|
| 142 | beginWrite(true);
|
---|
| 143 | theGSM3MobileClientProvider->writeSocket(c);
|
---|
| 144 | return 1;
|
---|
| 145 | }
|
---|
| 146 |
|
---|
| 147 | size_t GSM3MobileClientService::write(const uint8_t* buf)
|
---|
| 148 | {
|
---|
| 149 | if(!(flags & GSM3MOBILECLIENTSERVICE_WRITING))
|
---|
| 150 | beginWrite(true);
|
---|
| 151 | theGSM3MobileClientProvider->writeSocket((const char*)(buf));
|
---|
| 152 | return strlen((const char*)buf);
|
---|
| 153 | }
|
---|
| 154 |
|
---|
| 155 | size_t GSM3MobileClientService::write(const uint8_t* buf, size_t sz)
|
---|
| 156 | {
|
---|
| 157 | if(!(flags & GSM3MOBILECLIENTSERVICE_WRITING))
|
---|
| 158 | beginWrite(true);
|
---|
| 159 | for(int i=0;i<sz;i++)
|
---|
| 160 | theGSM3MobileClientProvider->writeSocket(buf[i]);
|
---|
| 161 | return sz;
|
---|
| 162 | }
|
---|
| 163 |
|
---|
| 164 | void GSM3MobileClientService::endWrite(bool sync)
|
---|
| 165 | {
|
---|
| 166 | flags ^= GSM3MOBILECLIENTSERVICE_WRITING;
|
---|
| 167 | theGSM3MobileClientProvider->endWriteSocket();
|
---|
| 168 | if(sync)
|
---|
| 169 | waitForAnswer();
|
---|
| 170 | }
|
---|
| 171 |
|
---|
| 172 | uint8_t GSM3MobileClientService::connected()
|
---|
| 173 | {
|
---|
| 174 | if(mySocket==255)
|
---|
| 175 | return 0;
|
---|
| 176 | return theGSM3MobileClientProvider->getStatusSocketClient(mySocket);
|
---|
| 177 | }
|
---|
| 178 |
|
---|
| 179 | GSM3MobileClientService::operator bool()
|
---|
| 180 | {
|
---|
| 181 | return connected()==1;
|
---|
| 182 | };
|
---|
| 183 |
|
---|
| 184 | int GSM3MobileClientService::available()
|
---|
| 185 | {
|
---|
| 186 | int res;
|
---|
| 187 |
|
---|
| 188 | // Even if not connected, we are looking for available data
|
---|
| 189 |
|
---|
| 190 | if(flags & GSM3MOBILECLIENTSERVICE_WRITING)
|
---|
| 191 | endWrite(true);
|
---|
| 192 |
|
---|
| 193 | res=theGSM3MobileClientProvider->availableSocket(flags & GSM3MOBILECLIENTSERVICE_CLIENT,mySocket);
|
---|
| 194 | if(flags & GSM3MOBILECLIENTSERVICE_SYNCH)
|
---|
| 195 | res=waitForAnswer();
|
---|
| 196 |
|
---|
| 197 | return res;
|
---|
| 198 | }
|
---|
| 199 |
|
---|
| 200 | int GSM3MobileClientService::read(uint8_t *buf, size_t size)
|
---|
| 201 | {
|
---|
| 202 | int i;
|
---|
| 203 | uint8_t c;
|
---|
| 204 |
|
---|
| 205 | for(i=0;i<size;i++)
|
---|
| 206 | {
|
---|
| 207 | c=read();
|
---|
| 208 | if(c==0)
|
---|
| 209 | break;
|
---|
| 210 | buf[i]=c;
|
---|
| 211 | }
|
---|
| 212 |
|
---|
| 213 | return i;
|
---|
| 214 | /* This is the old implementation, testing a simpler one
|
---|
| 215 | int res;
|
---|
| 216 | // If we were writing, just stop doing it.
|
---|
| 217 | if(flags & GSM3MOBILECLIENTSERVICE_WRITING)
|
---|
| 218 | endWrite(true);
|
---|
| 219 | res=theGSM3MobileClientProvider->readSocket(flags & GSM3MOBILECLIENTSERVICE_CLIENT, (char *)(buf), size, mySocket);
|
---|
| 220 |
|
---|
| 221 | return res;
|
---|
| 222 | */
|
---|
| 223 | }
|
---|
| 224 |
|
---|
| 225 | int GSM3MobileClientService::read()
|
---|
| 226 | {
|
---|
| 227 | if(flags & GSM3MOBILECLIENTSERVICE_WRITING)
|
---|
| 228 | endWrite(true);
|
---|
| 229 | int c=theGSM3MobileClientProvider->readSocket();
|
---|
| 230 | return c;
|
---|
| 231 | }
|
---|
| 232 |
|
---|
| 233 | int GSM3MobileClientService::peek()
|
---|
| 234 | {
|
---|
| 235 | if(flags & GSM3MOBILECLIENTSERVICE_WRITING)
|
---|
| 236 | endWrite(true);
|
---|
| 237 | return theGSM3MobileClientProvider->peekSocket(/*mySocket, false*/);
|
---|
| 238 | }
|
---|
| 239 |
|
---|
| 240 | void GSM3MobileClientService::flush()
|
---|
| 241 | {
|
---|
| 242 | if(flags & GSM3MOBILECLIENTSERVICE_WRITING)
|
---|
| 243 | endWrite(true);
|
---|
| 244 | theGSM3MobileClientProvider->flushSocket(/*mySocket*/);
|
---|
| 245 | if(flags & GSM3MOBILECLIENTSERVICE_SYNCH)
|
---|
| 246 | waitForAnswer();
|
---|
| 247 |
|
---|
| 248 | }
|
---|
| 249 |
|
---|
| 250 | void GSM3MobileClientService::stop()
|
---|
| 251 | {
|
---|
| 252 | if(flags & GSM3MOBILECLIENTSERVICE_WRITING)
|
---|
| 253 | endWrite(true);
|
---|
| 254 | theGSM3MobileClientProvider->disconnectTCP(flags & GSM3MOBILECLIENTSERVICE_CLIENT, mySocket);
|
---|
| 255 | theGSM3MobileClientProvider->releaseSocket(mySocket);
|
---|
| 256 | mySocket = 0;
|
---|
| 257 | if(flags & GSM3MOBILECLIENTSERVICE_SYNCH)
|
---|
| 258 | waitForAnswer();
|
---|
| 259 | }
|
---|
| 260 |
|
---|