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 Xiong
Date:
Fri Apr 03 15:44:04 2015 +0800
Revision:
13:379ce1d51b88
Parent:
11:0184e407128e
Child:
14:3c6454f033ac
rework

Who changed what in which revision?

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