a library to use GPRS like ethernet or wifi, which makes it possible to connect to the internet with your GPRS module

Dependencies:   BufferedSerial

Dependents:   ThinkSpeak_Test roam_v1 roam_v2 finalv3

Fork of GPRSInterface by wei zou

Committer:
yihui
Date:
Fri Apr 03 09:51:13 2015 +0000
Revision:
14:3c6454f033ac
Parent:
13:379ce1d51b88
bugfix

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yihui 14:3c6454f033ac 1 /*
yihui 14:3c6454f033ac 2 GPRS.cpp
yihui 14:3c6454f033ac 3 2014 Copyright (c) Seeed Technology Inc. All right reserved.
yihui 14:3c6454f033ac 4
yihui 14:3c6454f033ac 5 Author:lawliet zou(lawliet.zou@gmail.com)
yihui 14:3c6454f033ac 6 2014-2-24
yihui 14:3c6454f033ac 7
yihui 14:3c6454f033ac 8 This library is free software; you can redistribute it and/or
yihui 14:3c6454f033ac 9 modify it under the terms of the GNU Lesser General Public
yihui 14:3c6454f033ac 10 License as published by the Free Software Foundation; either
yihui 14:3c6454f033ac 11 version 2.1 of the License, or (at your option) any later version.
yihui 14:3c6454f033ac 12
yihui 14:3c6454f033ac 13 This library is distributed in the hope that it will be useful,
yihui 14:3c6454f033ac 14 but WITHOUT ANY WARRANTY; without even the implied warranty of
yihui 14:3c6454f033ac 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yihui 14:3c6454f033ac 16 Lesser General Public License for more details.
yihui 14:3c6454f033ac 17
yihui 14:3c6454f033ac 18 You should have received a copy of the GNU Lesser General Public
yihui 14:3c6454f033ac 19 License along with this library; if not, write to the Free Software
yihui 14:3c6454f033ac 20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
yihui 14:3c6454f033ac 21 */
yihui 14:3c6454f033ac 22
yihui 14:3c6454f033ac 23 #include "mbed.h"
Yihui Xiong 13:379ce1d51b88 24 #include "GPRS.h"
Yihui Xiong 13:379ce1d51b88 25
Yihui Xiong 13:379ce1d51b88 26 #define DEBUG
Yihui Xiong 13:379ce1d51b88 27
Yihui Xiong 13:379ce1d51b88 28 #ifdef DEBUG
Yihui Xiong 13:379ce1d51b88 29 #include "USBSerial.h"
Yihui Xiong 13:379ce1d51b88 30 extern USBSerial pc;
Yihui Xiong 13:379ce1d51b88 31 #define LOG(args...) pc.printf(args)
Yihui Xiong 13:379ce1d51b88 32 #else
Yihui Xiong 13:379ce1d51b88 33 #define LOG(args...)
Yihui Xiong 13:379ce1d51b88 34 #endif
yihui 14:3c6454f033ac 35
yihui 14:3c6454f033ac 36
yihui 14:3c6454f033ac 37 GPRS* GPRS::inst;
yihui 14:3c6454f033ac 38
yihui 14:3c6454f033ac 39 GPRS::GPRS(PinName tx, PinName rx, const char* apn, const char* userName, const char* passWord) : Modem(tx,rx)
yihui 14:3c6454f033ac 40 {
yihui 14:3c6454f033ac 41 inst = this;
yihui 14:3c6454f033ac 42 _apn = apn;
yihui 14:3c6454f033ac 43 _userName = userName;
yihui 14:3c6454f033ac 44 _passWord = passWord;
Yihui Xiong 13:379ce1d51b88 45 socketID = -1;
Yihui Xiong 13:379ce1d51b88 46
Yihui Xiong 13:379ce1d51b88 47 connected = false;
yihui 14:3c6454f033ac 48 recv_bytes = 0;
yihui 14:3c6454f033ac 49 }
yihui 14:3c6454f033ac 50
yihui 14:3c6454f033ac 51
yihui 14:3c6454f033ac 52
yihui 14:3c6454f033ac 53 bool GPRS::join()
yihui 14:3c6454f033ac 54 {
Yihui Xiong 13:379ce1d51b88 55 char ip_addr_buf[32];
yihui 14:3c6454f033ac 56
yihui 14:3c6454f033ac 57 //Select multiple connection
Yihui Xiong 13:379ce1d51b88 58 command("AT+CIPMUX=1\r\n");
yihui 14:3c6454f033ac 59
yihui 14:3c6454f033ac 60 // Set APN
Yihui Xiong 13:379ce1d51b88 61 command("AT+CSTT=\"%s\",\"%s\",\"%s\"\r\n",_apn,_userName,_passWord);
yihui 14:3c6454f033ac 62
yihui 14:3c6454f033ac 63 // Brings up wireless connection
yihui 14:3c6454f033ac 64 command("AT+CIICR\r\n");
yihui 14:3c6454f033ac 65
yihui 14:3c6454f033ac 66 // Get local IP address
Yihui Xiong 13:379ce1d51b88 67 printf("AT+CIFSR\r\n");
Yihui Xiong 13:379ce1d51b88 68
Yihui Xiong 13:379ce1d51b88 69 readline(ip_addr_buf, sizeof(ip_addr_buf)); // read echo
Yihui Xiong 13:379ce1d51b88 70
Yihui Xiong 13:379ce1d51b88 71 if (readline(ip_addr_buf, sizeof(ip_addr_buf)) <= 0) {
Yihui Xiong 13:379ce1d51b88 72 LOG("failed to join network\r\n");
Yihui Xiong 13:379ce1d51b88 73 return false;
Yihui Xiong 13:379ce1d51b88 74 }
Yihui Xiong 13:379ce1d51b88 75
Yihui Xiong 13:379ce1d51b88 76 int a, b, c, d;
Yihui Xiong 13:379ce1d51b88 77 if (sscanf(ip_addr_buf, "%d.%d.%d.%d", &a, &b, &c, &d) != 4) {
Yihui Xiong 13:379ce1d51b88 78 LOG("failed to get ip, r(%s)\r\n", ip_addr_buf);
Yihui Xiong 13:379ce1d51b88 79 return false;
Yihui Xiong 13:379ce1d51b88 80 }
Yihui Xiong 13:379ce1d51b88 81
yihui 14:3c6454f033ac 82 _ip = (a << 24) + (b << 16) + (c << 8) + d;
yihui 14:3c6454f033ac 83
yihui 14:3c6454f033ac 84 return true;
yihui 14:3c6454f033ac 85 }
yihui 14:3c6454f033ac 86
yihui 14:3c6454f033ac 87 bool GPRS::setProtocol(int socket, Protocol p)
Yihui Xiong 13:379ce1d51b88 88 {
yihui 14:3c6454f033ac 89 if (socket < 0 || socket > MAX_SOCK_NUM-1) {
yihui 14:3c6454f033ac 90 return false;
yihui 14:3c6454f033ac 91 }
yihui 14:3c6454f033ac 92 //ToDo: setProtocol
yihui 14:3c6454f033ac 93 return true;
yihui 14:3c6454f033ac 94 }
yihui 14:3c6454f033ac 95
yihui 14:3c6454f033ac 96 bool GPRS::connect(int socket, Protocol ptl, const char * host, int port, int timeout)
yihui 14:3c6454f033ac 97 {
yihui 14:3c6454f033ac 98 const char *protocol;
yihui 14:3c6454f033ac 99 if (socket < 0 || socket > MAX_SOCK_NUM-1) {
yihui 14:3c6454f033ac 100 return false;
yihui 14:3c6454f033ac 101 }
yihui 14:3c6454f033ac 102 if(ptl == TCP) {
yihui 14:3c6454f033ac 103 protocol = "TCP";
yihui 14:3c6454f033ac 104 } else if(ptl == UDP) {
yihui 14:3c6454f033ac 105 protocol = "UDP";
yihui 14:3c6454f033ac 106 } else {
yihui 14:3c6454f033ac 107 return false;
Yihui Xiong 13:379ce1d51b88 108 }
Yihui Xiong 13:379ce1d51b88 109
Yihui Xiong 13:379ce1d51b88 110 command("AT+CIPSTART=%d,\"%s\",\"%s\",%d\r\n", socket, protocol, host, port);
Yihui Xiong 13:379ce1d51b88 111
Yihui Xiong 13:379ce1d51b88 112 char response[64] = {0,};
Yihui Xiong 13:379ce1d51b88 113 if (readline(response, sizeof(response)) < 0) {
Yihui Xiong 13:379ce1d51b88 114 LOG("wait for connection - timeout\r\n");
Yihui Xiong 13:379ce1d51b88 115 return false;
Yihui Xiong 13:379ce1d51b88 116 }
Yihui Xiong 13:379ce1d51b88 117
Yihui Xiong 13:379ce1d51b88 118 if (strstr(response, "CONNECT OK") || strstr(response, "ALREADY CONNECT")) {
Yihui Xiong 13:379ce1d51b88 119 connected = true;
Yihui Xiong 13:379ce1d51b88 120 return true;
Yihui Xiong 13:379ce1d51b88 121 } else {
Yihui Xiong 13:379ce1d51b88 122 LOG("failed to connect (r:%s)\r\n", response);
Yihui Xiong 13:379ce1d51b88 123 return false;
yihui 14:3c6454f033ac 124 }
yihui 14:3c6454f033ac 125 }
yihui 14:3c6454f033ac 126
yihui 14:3c6454f033ac 127 bool GPRS::gethostbyname(const char* host, uint32_t* ip)
Yihui Xiong 13:379ce1d51b88 128 {
yihui 14:3c6454f033ac 129 int a, b, c, d;
Yihui Xiong 13:379ce1d51b88 130 if (sscanf(host, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) {
Yihui Xiong 13:379ce1d51b88 131 *ip = (a << 24) + (b << 16) + (c << 8) + d;
Yihui Xiong 13:379ce1d51b88 132
Yihui Xiong 13:379ce1d51b88 133 return true;
Yihui Xiong 13:379ce1d51b88 134 }
yihui 14:3c6454f033ac 135
yihui 14:3c6454f033ac 136 return false;
yihui 14:3c6454f033ac 137 }
yihui 14:3c6454f033ac 138
yihui 14:3c6454f033ac 139 bool GPRS::disconnect()
yihui 14:3c6454f033ac 140 {
Yihui Xiong 13:379ce1d51b88 141 puts("AT+CIPSHUT\r\n");
yihui 14:3c6454f033ac 142 connected = false;
yihui 14:3c6454f033ac 143 return true;
yihui 14:3c6454f033ac 144 }
yihui 14:3c6454f033ac 145
yihui 14:3c6454f033ac 146 bool GPRS::is_connected(int socket)
yihui 14:3c6454f033ac 147 {
yihui 14:3c6454f033ac 148 static uint32_t last = 0;
yihui 14:3c6454f033ac 149 if (((uint32_t)us_ticker_read() - last) > 60000000) {
yihui 14:3c6454f033ac 150 last = us_ticker_read();
yihui 14:3c6454f033ac 151
yihui 14:3c6454f033ac 152 flush();
yihui 14:3c6454f033ac 153 printf("AT+CIPSTATUS=%d\r\n", socket);
yihui 14:3c6454f033ac 154
yihui 14:3c6454f033ac 155 connected = false;
yihui 14:3c6454f033ac 156
yihui 14:3c6454f033ac 157 char response[80];
yihui 14:3c6454f033ac 158 readline(response, sizeof(response)); // echo, ignore
yihui 14:3c6454f033ac 159 if (readline(response, sizeof(response)) > 0) {
yihui 14:3c6454f033ac 160 if (strstr(response, "CONNECTED")) {
yihui 14:3c6454f033ac 161 connected = true;
yihui 14:3c6454f033ac 162 }
yihui 14:3c6454f033ac 163
yihui 14:3c6454f033ac 164 readline(response, sizeof(response)); // ok
yihui 14:3c6454f033ac 165 }
Yihui Xiong 13:379ce1d51b88 166 }
yihui 14:3c6454f033ac 167
yihui 14:3c6454f033ac 168 return connected;
yihui 14:3c6454f033ac 169 }
yihui 14:3c6454f033ac 170
yihui 14:3c6454f033ac 171 void GPRS::reset()
yihui 14:3c6454f033ac 172 {
yihui 14:3c6454f033ac 173
yihui 14:3c6454f033ac 174 }
yihui 14:3c6454f033ac 175
yihui 14:3c6454f033ac 176 bool GPRS::close(int socket)
yihui 14:3c6454f033ac 177 {
yihui 14:3c6454f033ac 178 if (socket < 0 || socket > (MAX_SOCK_NUM - 1)) {
yihui 14:3c6454f033ac 179 return false;
yihui 14:3c6454f033ac 180 }
yihui 14:3c6454f033ac 181
yihui 14:3c6454f033ac 182 printf("AT+CIPCLOSE=%d\r\n", socket);
yihui 14:3c6454f033ac 183 connected = false;
yihui 14:3c6454f033ac 184 return true;
Yihui Xiong 13:379ce1d51b88 185 }
Yihui Xiong 13:379ce1d51b88 186
Yihui Xiong 13:379ce1d51b88 187 int GPRS::sock_send(int socket, const char * data, int len)
Yihui Xiong 13:379ce1d51b88 188 {
Yihui Xiong 13:379ce1d51b88 189 if (socket < 0 || socket > MAX_SOCK_NUM-1 || len <= 0) {
Yihui Xiong 13:379ce1d51b88 190 return -1;
Yihui Xiong 13:379ce1d51b88 191 }
Yihui Xiong 13:379ce1d51b88 192
Yihui Xiong 13:379ce1d51b88 193 char response[64];
Yihui Xiong 13:379ce1d51b88 194
Yihui Xiong 13:379ce1d51b88 195 flush();
Yihui Xiong 13:379ce1d51b88 196 printf("AT+CIPSEND=%d,%d\r\n", socket, len);
Yihui Xiong 13:379ce1d51b88 197 readline(response, sizeof(response)); // echo, ignore
Yihui Xiong 13:379ce1d51b88 198 if (match("> ")) {
Yihui Xiong 13:379ce1d51b88 199 connected = false;
Yihui Xiong 13:379ce1d51b88 200 return -1;
Yihui Xiong 13:379ce1d51b88 201 }
Yihui Xiong 13:379ce1d51b88 202
Yihui Xiong 13:379ce1d51b88 203 write(data, len);
Yihui Xiong 13:379ce1d51b88 204
Yihui Xiong 13:379ce1d51b88 205 // read echo data
Yihui Xiong 13:379ce1d51b88 206 for (int i = 0; i < len; i++) {
Yihui Xiong 13:379ce1d51b88 207 while (!readable()) {
Yihui Xiong 13:379ce1d51b88 208 }
Yihui Xiong 13:379ce1d51b88 209 char ch = getc();
Yihui Xiong 13:379ce1d51b88 210 }
Yihui Xiong 13:379ce1d51b88 211
Yihui Xiong 13:379ce1d51b88 212 readline(response, sizeof(response));
Yihui Xiong 13:379ce1d51b88 213
Yihui Xiong 13:379ce1d51b88 214 // data received
Yihui Xiong 13:379ce1d51b88 215 int sock;
Yihui Xiong 13:379ce1d51b88 216 int bytes = 0;
Yihui Xiong 13:379ce1d51b88 217 if (sscanf(response, "+RECEIVE,%d,%d:", &sock, &bytes) == 2) {
Yihui Xiong 13:379ce1d51b88 218 while (bytes > 0) {
Yihui Xiong 13:379ce1d51b88 219 if (readable()) {
Yihui Xiong 13:379ce1d51b88 220 recv_buf[recv_bytes] = getc();
Yihui Xiong 13:379ce1d51b88 221 recv_bytes++;
Yihui Xiong 13:379ce1d51b88 222 bytes--;
Yihui Xiong 13:379ce1d51b88 223 }
Yihui Xiong 13:379ce1d51b88 224 }
Yihui Xiong 13:379ce1d51b88 225
Yihui Xiong 13:379ce1d51b88 226 readline(response, sizeof(response));
Yihui Xiong 13:379ce1d51b88 227 }
Yihui Xiong 13:379ce1d51b88 228
Yihui Xiong 13:379ce1d51b88 229 if (strstr(response, "SEND OK")) { // 0, SEND OK
Yihui Xiong 13:379ce1d51b88 230 return len;
Yihui Xiong 13:379ce1d51b88 231 }
Yihui Xiong 13:379ce1d51b88 232
Yihui Xiong 13:379ce1d51b88 233 if (strstr(response, "CLOSED")) {
Yihui Xiong 13:379ce1d51b88 234 connected = false;
Yihui Xiong 13:379ce1d51b88 235 }
Yihui Xiong 13:379ce1d51b88 236 return -1;
Yihui Xiong 13:379ce1d51b88 237 }
Yihui Xiong 13:379ce1d51b88 238
Yihui Xiong 13:379ce1d51b88 239 int GPRS::sock_recv(int socket, char* buf, int len)
Yihui Xiong 13:379ce1d51b88 240 {
Yihui Xiong 13:379ce1d51b88 241 if (recv_bytes > 0) {
Yihui Xiong 13:379ce1d51b88 242 if (len >= recv_bytes) {
Yihui Xiong 13:379ce1d51b88 243 len = recv_bytes;
Yihui Xiong 13:379ce1d51b88 244 memcpy(buf, recv_buf, recv_bytes);
Yihui Xiong 13:379ce1d51b88 245 recv_bytes = 0;
Yihui Xiong 13:379ce1d51b88 246 } else {
Yihui Xiong 13:379ce1d51b88 247 memcpy(buf, recv_buf, len);
Yihui Xiong 13:379ce1d51b88 248 recv_bytes -= len;
Yihui Xiong 13:379ce1d51b88 249 memcpy(recv_buf, recv_buf + len, recv_bytes);
Yihui Xiong 13:379ce1d51b88 250 }
Yihui Xiong 13:379ce1d51b88 251
Yihui Xiong 13:379ce1d51b88 252 return len;
Yihui Xiong 13:379ce1d51b88 253 }
Yihui Xiong 13:379ce1d51b88 254
Yihui Xiong 13:379ce1d51b88 255 char response[32];
Yihui Xiong 13:379ce1d51b88 256 if (readline(response, sizeof(response)) <= 0) {
Yihui Xiong 13:379ce1d51b88 257 return -1;
Yihui Xiong 13:379ce1d51b88 258 }
Yihui Xiong 13:379ce1d51b88 259
Yihui Xiong 13:379ce1d51b88 260 if (strstr(response, "CLOSED")) {
Yihui Xiong 13:379ce1d51b88 261 LOG("socket is closed, r(%s)\r\n", response);
Yihui Xiong 13:379ce1d51b88 262 connected = false;
Yihui Xiong 13:379ce1d51b88 263
Yihui Xiong 13:379ce1d51b88 264 return -1;
Yihui Xiong 13:379ce1d51b88 265 }
Yihui Xiong 13:379ce1d51b88 266
Yihui Xiong 13:379ce1d51b88 267 int sock;
Yihui Xiong 13:379ce1d51b88 268 int bytes = 0;
Yihui Xiong 13:379ce1d51b88 269 if (sscanf(response, "+RECEIVE,%d,%d:", &sock, &bytes) != 2) {
yihui 14:3c6454f033ac 270 LOG("unknow:%s\r\n", response);
Yihui Xiong 13:379ce1d51b88 271 return -1;
Yihui Xiong 13:379ce1d51b88 272 }
Yihui Xiong 13:379ce1d51b88 273
Yihui Xiong 13:379ce1d51b88 274 int bytes_read = 0;
Yihui Xiong 13:379ce1d51b88 275 while (bytes_read < bytes) {
Yihui Xiong 13:379ce1d51b88 276 if (readable()) {
Yihui Xiong 13:379ce1d51b88 277 buf[bytes_read] = getc();
Yihui Xiong 13:379ce1d51b88 278 bytes_read++;
Yihui Xiong 13:379ce1d51b88 279 }
Yihui Xiong 13:379ce1d51b88 280 }
Yihui Xiong 13:379ce1d51b88 281
Yihui Xiong 13:379ce1d51b88 282 return bytes;
Yihui Xiong 13:379ce1d51b88 283 }
Yihui Xiong 13:379ce1d51b88 284
Yihui Xiong 13:379ce1d51b88 285 int GPRS::new_socket()
Yihui Xiong 13:379ce1d51b88 286 {
Yihui Xiong 13:379ce1d51b88 287 socketID = 0; //we only support one socket.
Yihui Xiong 13:379ce1d51b88 288 return socketID;
yihui 14:3c6454f033ac 289 }